Пример #1
0
        /// <summary>
        /// Fill the function variables with names.
        /// </summary>
        private void FillVariableNames()
        {
            List <Symbol> variablesToFill = fn.Variables;

            for (int i = 0; i < variablesToFill.Count; i++)
            {
                Symbol sym = (Symbol)variablesToFill[i];
                sym.m_values = null;
                sym.m_value  = 0;
                object sometypeofobject = Apsim.Get(Object as Model, sym.m_name.Trim());
                if (sometypeofobject == null)
                {
                    throw new Exception("Cannot find variable: " + sym.m_name + " while evaluating expression: " + expression);
                }
                if (sometypeofobject is double)
                {
                    sym.m_value = (double)sometypeofobject;
                }
                else if (sometypeofobject is int)
                {
                    sym.m_value = Convert.ToDouble(sometypeofobject, System.Globalization.CultureInfo.InvariantCulture);
                }
                else if (sometypeofobject is double[])
                {
                    sym.m_values = (double[])sometypeofobject;
                }
                else if (sometypeofobject is double[][])
                {
                    double[][]    allvalues           = sometypeofobject as double[][];
                    List <double> singleArrayOfValues = new List <double>();
                    foreach (double[] dimension in allvalues)
                    {
                        foreach (double value in dimension)
                        {
                            singleArrayOfValues.Add(value);
                        }
                    }
                    sym.m_values = (double[])singleArrayOfValues.ToArray();
                }
                variablesToFill[i] = sym;
            }
            fn.Variables = variablesToFill;
        }
Пример #2
0
        /// <summary>Documents the specified model.</summary>
        /// <param name="modelNameToDocument">The model name to document.</param>
        /// <param name="tags">The auto doc tags.</param>
        /// <param name="headingLevel">The starting heading level.</param>
        public void DocumentModel(string modelNameToDocument, List <AutoDocumentation.ITag> tags, int headingLevel)
        {
            Simulation simulation = Apsim.Find(this, typeof(Simulation)) as Simulation;

            if (simulation != null)
            {
                // Find the model of the right name.
                IModel modelToDocument = Apsim.Find(simulation, modelNameToDocument);

                // Get the path of the model (relative to parentSimulation) to document so that
                // when replacements happen below we will point to the replacement model not the
                // one passed into this method.
                string pathOfSimulation      = Apsim.FullPath(simulation) + ".";
                string pathOfModelToDocument = Apsim.FullPath(modelToDocument).Replace(pathOfSimulation, "");

                // Clone the simulation
                Simulation clonedSimulation = Apsim.Clone(simulation) as Simulation;

                // Make any substitutions.
                MakeSubstitutions(new Simulation[] { clonedSimulation });

                // Now use the path to get the model we want to document.
                modelToDocument = Apsim.Get(clonedSimulation, pathOfModelToDocument) as IModel;

                // resolve all links in cloned simulation.
                Apsim.ResolveLinks(clonedSimulation);
                foreach (Model child in Apsim.ChildrenRecursively(clonedSimulation))
                {
                    Apsim.ResolveLinks(child);
                }

                // Document the model.
                modelToDocument.Document(tags, headingLevel, 0);

                // Unresolve links.
                Apsim.UnresolveLinks(clonedSimulation);
                foreach (Model child in Apsim.ChildrenRecursively(clonedSimulation))
                {
                    Apsim.UnresolveLinks(child);
                }
            }
        }
Пример #3
0
        /// <summary>Documents the specified model.</summary>
        /// <param name="modelNameToDocument">The model name to document.</param>
        /// <param name="tags">The auto doc tags.</param>
        /// <param name="headingLevel">The starting heading level.</param>
        public void DocumentModel(string modelNameToDocument, List <AutoDocumentation.ITag> tags, int headingLevel)
        {
            Simulation simulation = Apsim.Find(this, typeof(Simulation)) as Simulation;

            if (simulation != null)
            {
                // Find the model of the right name.
                IModel modelToDocument = Apsim.Find(simulation, modelNameToDocument);

                // If not found then find a model of the specified type.
                if (modelToDocument == null)
                {
                    modelToDocument = Apsim.Get(simulation, "[" + modelNameToDocument + "]") as IModel;
                }

                // If the simulation has the same name as the model we want to document, dig a bit deeper
                if (modelToDocument == simulation)
                {
                    modelToDocument = Apsim.ChildrenRecursivelyVisible(simulation).FirstOrDefault(m => m.Name.Equals(modelNameToDocument, StringComparison.OrdinalIgnoreCase));
                }

                // If still not found throw an error.
                if (modelToDocument != null)
                {
                    // Get the path of the model (relative to parentSimulation) to document so that
                    // when replacements happen below we will point to the replacement model not the
                    // one passed into this method.
                    string pathOfSimulation      = Apsim.FullPath(simulation) + ".";
                    string pathOfModelToDocument = Apsim.FullPath(modelToDocument).Replace(pathOfSimulation, "");

                    // Clone the simulation
                    Simulation clonedSimulation = Apsim.Clone(simulation) as Simulation;

                    // Make any substitutions.
                    MakeSubstitutions(clonedSimulation);

                    // Now use the path to get the model we want to document.
                    modelToDocument = Apsim.Get(clonedSimulation, pathOfModelToDocument) as IModel;

                    if (modelToDocument == null)
                    {
                        throw new Exception("Cannot find model to document: " + modelNameToDocument);
                    }

                    // resolve all links in cloned simulation.
                    Links.Resolve(clonedSimulation);

                    modelToDocument.IncludeInDocumentation = true;
                    foreach (IModel child in Apsim.ChildrenRecursively(modelToDocument))
                    {
                        child.IncludeInDocumentation = true;
                    }

                    // Document the model.
                    AutoDocumentation.DocumentModel(modelToDocument, tags, headingLevel, 0, documentAllChildren: true);

                    // Unresolve links.
                    Links.Unresolve(clonedSimulation);
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Parse a string into documentation tags
        /// </summary>
        /// <param name="stringToParse">The string to parse</param>
        /// <param name="model">The associated model where the string came from</param>
        /// <param name="tags">The list of tags to add to</param>
        /// <param name="headingLevel">The current heading level</param>
        /// <param name="indent">The current indent level</param>
        /// <param name="documentAllChildren">Ensure all children are documented?</param>
        public static void ParseTextForTags(string stringToParse, IModel model, List <ITag> tags, int headingLevel, int indent, bool documentAllChildren)
        {
            List <IModel> childrenDocumented   = new List <Core.IModel>();
            int           numSpacesStartOfLine = -1;
            string        paragraphSoFar       = string.Empty;

            if (stringToParse.StartsWith("\r\n"))
            {
                stringToParse = stringToParse.Remove(0, 2);
            }
            StringReader reader             = new StringReader(stringToParse);
            string       line               = reader.ReadLine();
            int          targetHeadingLevel = headingLevel;

            while (line != null)
            {
                line = line.Trim();

                // Adjust heading levels.
                if (line.StartsWith("#"))
                {
                    int currentHeadingLevel = line.Count(c => c == '#');
                    targetHeadingLevel = headingLevel + currentHeadingLevel - 1; // assumes models start numbering headings at 1 '#' character
                    string hashString = new string('#', targetHeadingLevel);
                    line = hashString + line.Replace("#", "") + hashString;
                }

                if (line != string.Empty)
                {
                    {
                        if (numSpacesStartOfLine == -1)
                        {
                            int preLineLength = line.Length;
                            line = line.TrimStart();
                            numSpacesStartOfLine = preLineLength - line.Length - 1;
                        }
                        else
                        {
                            line = line.Remove(0, numSpacesStartOfLine);
                        }
                    }
                }

                // Remove expression macros and replace with values.
                line = RemoveMacros(model, line);

                string heading;
                int    thisHeadingLevel;
                if (GetHeadingFromLine(line, out heading, out thisHeadingLevel))
                {
                    StoreParagraphSoFarIntoTags(tags, indent, ref paragraphSoFar);
                    tags.Add(new Heading(heading, thisHeadingLevel));
                }
                else if (line.StartsWith("[Document "))
                {
                    StoreParagraphSoFarIntoTags(tags, indent, ref paragraphSoFar);

                    // Find child
                    string childName = line.Replace("[Document ", "").Replace("]", "");
                    IModel child     = Apsim.Get(model, childName) as IModel;
                    if (child == null)
                    {
                        paragraphSoFar += "<b>Unknown child name: " + childName + " </b>\r\n";
                    }
                    else
                    {
                        DocumentModel(child, tags, targetHeadingLevel + 1, indent);
                        childrenDocumented.Add(child);
                    }
                }
                else if (line.StartsWith("[DocumentType "))
                {
                    StoreParagraphSoFarIntoTags(tags, indent, ref paragraphSoFar);

                    // Find children
                    string childTypeName = line.Replace("[DocumentType ", "").Replace("]", "");
                    Type   childType     = ReflectionUtilities.GetTypeFromUnqualifiedName(childTypeName);
                    foreach (IModel child in Apsim.Children(model, childType))
                    {
                        DocumentModel(child, tags, targetHeadingLevel + 1, indent);
                        childrenDocumented.Add(child);
                    }
                }
                else if (line == "[DocumentView]")
                {
                    tags.Add(new ModelView(model));
                }
                else
                {
                    paragraphSoFar += " " + line + "\r\n";
                }

                line = reader.ReadLine();
            }

            StoreParagraphSoFarIntoTags(tags, indent, ref paragraphSoFar);

            if (documentAllChildren)
            {
                // write children.
                foreach (IModel child in Apsim.Children(model, typeof(IModel)))
                {
                    if (!childrenDocumented.Contains(child))
                    {
                        DocumentModel(child, tags, headingLevel + 1, indent, documentAllChildren);
                    }
                }
            }
        }
Пример #5
0
        /// <summary>Writes the description of a class to the tags.</summary>
        /// <param name="model">The model to get documentation for.</param>
        /// <param name="tags">The tags to add to.</param>
        /// <param name="headingLevel">The heading level to use.</param>
        /// <param name="indent">The indentation level.</param>
        /// <param name="documentAllChildren">Document all children?</param>
        /// <param name="withHeading">Put a heading in for this model?</param>
        public static void DocumentModel(IModel model, List <ITag> tags, int headingLevel, int indent, bool documentAllChildren = false, bool withHeading = false)
        {
            if (doc == null)
            {
                string fileName = Path.ChangeExtension(Assembly.GetExecutingAssembly().Location, ".xml");
                doc = new XmlDocument();
                doc.Load(fileName);
            }

            if (withHeading)
            {
                tags.Add(new AutoDocumentation.Heading(model.Name, headingLevel));
            }

            List <IModel> childrenDocumented = new List <Core.IModel>();

            string  nameToFindInSummary = "members/T:" + model.GetType().FullName.Replace("+", ".") + "/summary";
            XmlNode summaryNode         = XmlUtilities.Find(doc.DocumentElement, nameToFindInSummary);

            if (summaryNode != null)
            {
                int    numSpacesStartOfLine = -1;
                string paragraphSoFar       = string.Empty;
                string st = summaryNode.InnerXml;
                if (st.StartsWith("\r\n"))
                {
                    st = st.Remove(0, 2);
                }
                StringReader reader             = new StringReader(st);
                string       line               = reader.ReadLine();
                int          targetHeadingLevel = headingLevel;
                while (line != null)
                {
                    line = line.Trim();

                    // Adjust heading levels.
                    if (line.StartsWith("#"))
                    {
                        int currentHeadingLevel = line.Count(c => c == '#') / 2;
                        targetHeadingLevel = headingLevel + currentHeadingLevel - 1;
                        string hashString = new string('#', targetHeadingLevel);
                        line = hashString + line.Replace("#", "") + hashString;
                    }

                    if (line != string.Empty)
                    {
                        {
                            if (numSpacesStartOfLine == -1)
                            {
                                int preLineLength = line.Length;
                                line = line.TrimStart();
                                numSpacesStartOfLine = preLineLength - line.Length - 1;
                            }
                            else
                            {
                                line = line.Remove(0, numSpacesStartOfLine);
                            }
                        }
                    }
                    string heading;
                    int    thisHeadingLevel;
                    if (GetHeadingFromLine(line, out heading, out thisHeadingLevel))
                    {
                        StoreParagraphSoFarIntoTags(tags, indent, ref paragraphSoFar);
                        tags.Add(new Heading(heading, thisHeadingLevel));
                    }
                    else if (line.StartsWith("[Document "))
                    {
                        StoreParagraphSoFarIntoTags(tags, indent, ref paragraphSoFar);

                        // Find child
                        string childName = line.Replace("[Document ", "").Replace("]", "");
                        IModel child     = Apsim.Get(model, childName) as IModel;
                        if (child == null)
                        {
                            paragraphSoFar += "<b>Unknown child name: " + childName + " </b>\r\n";
                        }
                        else
                        {
                            child.Document(tags, targetHeadingLevel + 1, indent);
                            childrenDocumented.Add(child);
                        }
                    }
                    else
                    {
                        paragraphSoFar += " " + line + "\r\n";
                    }

                    line = reader.ReadLine();
                }

                StoreParagraphSoFarIntoTags(tags, indent, ref paragraphSoFar);
            }

            if (documentAllChildren)
            {
                // write children.
                foreach (IModel child in Apsim.Children(model, typeof(IModel)))
                {
                    if (!childrenDocumented.Contains(child))
                    {
                        child.Document(tags, headingLevel + 1, indent);
                    }
                }
            }
        }
Пример #6
0
        /// <summary>
        /// Internal [link] resolution algorithm.
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="allModels">A collection of all model wrappers</param>
        private void ResolveInternal(object obj, List <ModelWrapper> allModels)
        {
            // Go looking for [Link]s
            foreach (IVariable field in GetAllDeclarations(GetModel(obj),
                                                           GetModel(obj).GetType(),
                                                           BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Public,
                                                           allLinks: true))
            {
                LinkAttribute link = field.GetAttribute(typeof(LinkAttribute)) as LinkAttribute;

                if (link != null)
                {
                    // Get the field type or the array element if it is an array field.
                    Type fieldType = field.DataType;
                    if (fieldType.IsArray)
                    {
                        fieldType = fieldType.GetElementType();
                    }
                    else if (field.DataType.Name.StartsWith("List") && field.DataType.GenericTypeArguments.Length == 1)
                    {
                        fieldType = field.DataType.GenericTypeArguments[0];
                    }

                    // Try and get a match from our services first.
                    List <object> matches;
                    matches = services.FindAll(s => fieldType.IsAssignableFrom(s.GetType()));

                    // If no match on services then try other options.
                    if (matches.Count == 0 && obj is IModel)
                    {
                        Simulation parentSimulation = Apsim.Parent(obj as IModel, typeof(Simulation)) as Simulation;
                        if (fieldType.IsAssignableFrom(typeof(ILocator)) && parentSimulation != null)
                        {
                            matches.Add(new Locator(obj as IModel));
                        }
                        else if (fieldType.IsAssignableFrom(typeof(IEvent)) && parentSimulation != null)
                        {
                            matches.Add(new Events(obj as IModel));
                        }
                    }

                    // If no match on services then try other options.
                    if (matches.Count == 0)
                    {
                        // Get a list of models that could possibly match.
                        if (link is ParentLinkAttribute)
                        {
                            matches = new List <object>();
                            matches.Add(GetParent(obj, fieldType));
                        }
                        else if (link is LinkByPathAttribute)
                        {
                            object match = Apsim.Get(obj as IModel, (link as LinkByPathAttribute).Path);
                            if (match != null)
                            {
                                matches.Add(match);
                            }
                        }
                        else if (link.IsScoped(field))
                        {
                            matches = GetModelsInScope(obj, allModels);
                        }
                        else
                        {
                            matches = GetChildren(obj);
                        }
                    }

                    // Filter possible matches to those of the correct type.
                    matches.RemoveAll(match => !fieldType.IsAssignableFrom(GetModel(match).GetType()));

                    // If we should use name to match then filter matches to those with a matching name.
                    if (link.UseNameToMatch(field))
                    {
                        matches.RemoveAll(match => !StringUtilities.StringsAreEqual(GetName(match), field.Name));
                    }

                    if (field.DataType.IsArray)
                    {
                        Array array = Array.CreateInstance(fieldType, matches.Count);
                        for (int i = 0; i < matches.Count; i++)
                        {
                            array.SetValue(GetModel(matches[i]), i);
                        }
                        field.Value = array;
                    }
                    else if (field.DataType.Name.StartsWith("List") && field.DataType.GenericTypeArguments.Length == 1)
                    {
                        var   listType            = typeof(List <>);
                        var   constructedListType = listType.MakeGenericType(fieldType);
                        IList array = Activator.CreateInstance(constructedListType) as IList;
                        for (int i = 0; i < matches.Count; i++)
                        {
                            array.Add(GetModel(matches[i]));
                        }
                        field.Value = array;
                    }
                    else if (matches.Count == 0)
                    {
                        if (!link.IsOptional)
                        {
                            throw new Exception("Cannot find a match for link " + field.Name + " in model " + GetFullName(obj));
                        }
                    }
                    else if (matches.Count >= 2 && !link.IsScoped(field))
                    {
                        throw new Exception(string.Format(": Found {0} matches for link {1} in model {2} !", matches.Count, field.Name, GetFullName(obj)));
                    }
                    else
                    {
                        field.Value = GetModel(matches[0]);
                    }
                }
            }
        }
Пример #7
0
 /// <summary>
 /// Internal [link] resolution algorithm.
 /// </summary>
 /// <param name="obj"></param>
 private void ResolveInternal(object obj)
 {
     foreach (IVariable field in GetAllDeclarations(GetModel(obj),
                                                    GetModel(obj).GetType(),
                                                    BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Public,
                                                    allLinks: true))
     {
         LinkAttribute link = field.GetAttribute(typeof(LinkAttribute)) as LinkAttribute;
         if (link != null)
         {
             Type fieldType = field.DataType;
             if (fieldType.IsArray)
             {
                 fieldType = fieldType.GetElementType();
             }
             else if (field.DataType.Name.StartsWith("List") && field.DataType.GenericTypeArguments.Length == 1)
             {
                 fieldType = field.DataType.GenericTypeArguments[0];
             }
             List <object> matches;
             matches = services.FindAll(s => fieldType.IsAssignableFrom(s.GetType()));
             if (matches.Count == 0 && obj is IModel)
             {
                 Simulation parentSimulation = Apsim.Parent(obj as IModel, typeof(Simulation)) as Simulation;
                 if (fieldType.IsAssignableFrom(typeof(ILocator)) && parentSimulation != null)
                 {
                     matches.Add(new Locator(obj as IModel));
                 }
                 else if (fieldType.IsAssignableFrom(typeof(IEvent)) && parentSimulation != null)
                 {
                     matches.Add(new Events(obj as IModel));
                 }
             }
             if (matches.Count == 0)
             {
                 if (link is ParentLinkAttribute)
                 {
                     matches = new List <object>();
                     matches.Add(GetParent(obj, fieldType));
                 }
                 else if (link is LinkByPathAttribute)
                 {
                     object match = Apsim.Get(obj as IModel, (link as LinkByPathAttribute).Path);
                     if (match != null)
                     {
                         matches.Add(match);
                     }
                 }
                 else if (link.IsScoped(field))
                 {
                     matches = Apsim.FindAll(obj as IModel).Cast <object>().ToList();
                 }
                 else
                 {
                     matches = GetChildren(obj);
                 }
             }
             matches.RemoveAll(match => !fieldType.IsAssignableFrom(GetModel(match).GetType()));
             if (link.UseNameToMatch(field))
             {
                 matches.RemoveAll(match => !StringUtilities.StringsAreEqual(GetName(match), field.Name));
             }
             if (field.DataType.IsArray)
             {
                 Array array = Array.CreateInstance(fieldType, matches.Count);
                 for (int i = 0; i < matches.Count; i++)
                 {
                     array.SetValue(GetModel(matches[i]), i);
                 }
                 field.Value = array;
             }
             else if (field.DataType.Name.StartsWith("List") && field.DataType.GenericTypeArguments.Length == 1)
             {
                 var   listType            = typeof(List <>);
                 var   constructedListType = listType.MakeGenericType(fieldType);
                 IList array = Activator.CreateInstance(constructedListType) as IList;
                 for (int i = 0; i < matches.Count; i++)
                 {
                     array.Add(GetModel(matches[i]));
                 }
                 field.Value = array;
             }
             else if (matches.Count == 0)
             {
                 if (!link.IsOptional)
                 {
                     throw new Exception("Cannot find a match for link " + field.Name + " in model " + GetFullName(obj));
                 }
             }
             else if (matches.Count >= 2 && !link.IsScoped(field))
             {
                 throw new Exception(string.Format(": Found {0} matches for link {1} in model {2} !", matches.Count, field.Name, GetFullName(obj)));
             }
             else
             {
                 field.Value = GetModel(matches[0]);
             }
         }
     }
 }