예제 #1
0
파일: DslBuilder.cs 프로젝트: Dervall/Snout
 public DslBuilder(XElement builderClassNode, XmlDocCommentReader commentReader, Type builderType)
 {
     input = builderClassNode.Value;
     syntaxStateClassname = builderClassNode.Attributes().Single(f => f.Name == "name").Value;
     outputNamespace = builderClassNode.Attributes().Single(f => f.Name == "namespace").Value;
     type = builderType;
     this.commentReader = commentReader;
 }
예제 #2
0
파일: DslParser.cs 프로젝트: Dervall/Snout
        public ILexer<int> CreateDslParserFromRegularExpression(string input, Type builderType, XmlDocCommentReader commentReader)
        {
            List<Identifier> identifiers = CreateIdentifiers(builderType, commentReader).ToList();
            IDictionary<string, char> usedIdentifiers = new Dictionary<string, char>();

            // We are going to create a lexer to read the input
            var inputLexer = LexerFactory<char>.Configure(configurator =>
            {
                Action<char> singleChar = c => configurator.Token(Regex.Escape(c.ToString()), f => c);
                char identifierChar = 'a';

                configurator.Token("[A-Za-z_][A-Za-z_0-9]+", f =>
                {
                    if (usedIdentifiers.ContainsKey(f))
                    {
                        return usedIdentifiers[f];
                    }

                    // Make sure the identifer exists
                    if (identifiers.SingleOrDefault(i => i.DslName == f) == null)
                    {
                        throw new Exception("No buildermethod called " + f + " was found in the class!");
                    }

                    if (identifierChar == 'Z' + 1)
                        identifierChar = 'a';
                    if (identifierChar > 'z')
                        throw new Exception("Snout cannot handle the amount of symbols you're using. Use less");

                    usedIdentifiers.Add(f, identifierChar);

                    return identifierChar++;
                }); // Identifiers

                singleChar('+');
                singleChar('*');
                singleChar('|');
                singleChar('?');
                singleChar('(');
                singleChar(')');

                configurator.Ignore("\\s+");
                configurator.Ignore(@"/\*([^*]+|\*[^/])*\*/");
            });

            inputLexer.SetSource(input);

            var dslRegEx = new StringBuilder();

            // Use the lexer to get a regular expression!
            for (var token = inputLexer.Next(); token.Item1 != -1; token = inputLexer.Next() )
            {
                dslRegEx.Append(token.Item2);
            }

            // Condense it into the Identifers dictionary
            Identifiers =
                identifiers.Where(f => usedIdentifiers.ContainsKey(f.DslName)).ToDictionary(
                    f => usedIdentifiers[f.DslName]);

            // Create another lexer, this one we will return
            return LexerFactory<int>.Configure(c => c.Token(dslRegEx.ToString(), f => 0));
        }
예제 #3
0
파일: DslParser.cs 프로젝트: Dervall/Snout
        private string GetDocumentation(MethodInfo method, XmlDocCommentReader commentReader)
        {
            var methodComments = commentReader.GetComments(method);

            // We are going to take the comments verbatim, but remove the <buildermethod/> tag
            var builderNode = methodComments.Descendants().Single(f => f.Name == "buildermethod");
            builderNode.Remove();
            return "///" + string.Join("\n///", methodComments.Nodes().SelectMany( n => n.ToString().Split('\n').Where(f => !string.IsNullOrWhiteSpace(f)).Select(f => f.TrimStart())));
        }
예제 #4
0
파일: DslParser.cs 프로젝트: Dervall/Snout
        private BuilderMethod GetBuilderMethod(MethodInfo methodInfo, XmlDocCommentReader commentReader)
        {
            var comments = commentReader.GetComments(methodInfo);

            if (comments != null)
            {
                // Look for a buildermethod subnode. If this is found create a BuilderMethod instance
                var builderMethodNode = comments.Descendants().SingleOrDefault(f => f.Name == "buildermethod");
                if (builderMethodNode != null)
                {
                    Func<string, string, string> attributeValueOrDefault = (attributeName, defaultValue) =>
                    {
                        var attribute = builderMethodNode.Attributes().SingleOrDefault(n => n.Name == attributeName);
                        return attribute == null ? defaultValue : attribute.Value;
                    };

                    string fluentName = attributeValueOrDefault("name", methodInfo.Name);
                    string dslName = attributeValueOrDefault("dslname", fluentName);
                    bool useProperty = Convert.ToBoolean(attributeValueOrDefault("useproperty", "true"));

                    return new BuilderMethod
                               {
                                   FluentName = fluentName,
                                   DslName = dslName,
                                   UseProperty = useProperty
                               };
                }
            }

            return null;
        }
예제 #5
0
파일: DslParser.cs 프로젝트: Dervall/Snout
        private IEnumerable<Identifier> CreateIdentifiers(Type builderType, XmlDocCommentReader commentReader)
        {
            foreach (var methodInfo in builderType.GetMethods())
            {
                // Read the xml documentation for this method. Look for the buildermethod tag
                // If this is found, we create a suitable terminal for this method
                var builderMethod = GetBuilderMethod(methodInfo, commentReader);
                if (builderMethod != null)
                {
                    var identifier = new Identifier {DslName = Regex.Escape(builderMethod.DslName)};
                    var method = new StringBuilder(builderMethod.FluentName);

                    // If there are generic type arguments to the builder method these will need to be transferred to the
                    // new interface method
                    var genericArguments = methodInfo.GetGenericArguments();
                    if (genericArguments.Any())
                    {
                        method.Append("<");
                        var dynamicAttribute = methodInfo.GetCustomAttributes(typeof(DynamicAttribute), true).OfType<DynamicAttribute>().FirstOrDefault();
                        IEnumerable<bool> transformFlags = dynamicAttribute == null ? null : dynamicAttribute.TransformFlags;
                        method.Append(string.Join(", ", genericArguments.Select(f =>
                        {
                            var ret = GetFullName(f, transformFlags);
                            if (transformFlags != null)
                                transformFlags = transformFlags.Skip(1);
                            return ret;
                        })));
                        method.Append(">");
                    }

                    Func<string, string> applyBracersIfNotEmpty = f => f.Length > 0 ? "<" + f + ">" : "";

                    // Append stuff to the debug name to make it call the builder method
                    // and to carry along the properties
                    var parameters = methodInfo.GetParameters();
                    var builderCall = string.Format("{0}{1}({2})",
                        methodInfo.Name,
                        applyBracersIfNotEmpty(string.Join(",", methodInfo.GetGenericArguments().Select(f => f.Name))),
                        string.Join(", ", parameters.Select(f => f.Name).ToArray()));
                    if (!parameters.Any() && !methodInfo.GetGenericArguments().Any() && builderMethod.UseProperty)
                    {
                        // No parameters and user wants this rendered as a property
                        method.Append(@"
            {{
            get
            {{
                builder." + builderCall + @";
                return new {0}{1}(builder);
            }}
            }}");
                    }
                    else
                    {
                        // There is supposed to be a method call
                        method.AppendFormat("({0})",
                            parameters.Any() ?
                            string.Join(", ", parameters.Select(f =>
                            {
                                var dynamicAttribute = f.GetCustomAttributes(typeof(DynamicAttribute), true).OfType<DynamicAttribute>().FirstOrDefault();

                                return string.Format("{0} {1}", GetFullName(f.ParameterType,
                                    dynamicAttribute != null ? dynamicAttribute.TransformFlags : null),
                                            f.Name);
                            }).ToArray<object>()) : "" );
                        method.Append(@"
            {{
            builder." + builderCall + @";
            return new {0}{1}(builder);
            }}");
                    }

                    identifier.MethodContents = method.ToString();
                    identifier.Documentation = GetDocumentation(methodInfo, commentReader);
                    yield return identifier;
                }
            }
        }
 /// <summary>
 /// Creates a new instances that reads comments from the specified XML Doc comments file.
 /// </summary>
 /// <param name="docCommentsFullPath">The full path of the XML Doc comments file.</param>
 public JoltCommentReader(string docCommentsFullPath)
 {
     if (docCommentsFullPath == null) throw new ArgumentNullException("docCommentsFullPath");
     _proxy = new XmlDocCommentReader(docCommentsFullPath);
 }
예제 #7
0
    /// <summary>
    /// Formats the text to be displayed in the tooltip using information from the object's member and from the XML documentation, if existing.
    /// </summary>
    /// <param name="scintilla"></param>
    /// <param name="member">Reflected member to display information from.</param>
    /// <param name="reader">Jolt's XmlDocCommentReader instance, to get and display comments from assembly-generated XML file.</param>
    /// <returns>The formatted text to display in the tooltip.</returns>
    /// <remarks></remarks>
    private static string FormatHelpTip(this ScintillaNET.Scintilla scintilla, MemberInfo member, Jolt.XmlDocCommentReader reader)
    {
        switch (member.MemberType)
        {
        case MemberTypes.Method:

            dynamic methods = Type.GetType(member.DeclaringType.FullName).GetMethods().Where(m => m.Name == member.Name).ToList();
            dynamic method  = methods[0];

            string summary           = "";
            string returntype        = "";
            string returndescription = "";
            string remarks           = "";

            Dictionary <string, string> argumentdescriptions = new Dictionary <string, string>();

            string txthelp = method.DeclaringType.Name + " method '" + member.Name + "'" + "\r\n";

            dynamic xmlhelp = reader.GetComments(method);

            if ((xmlhelp != null))
            {
                dynamic @params = xmlhelp.Elements("param").ToList;
                foreach (var p_loopVariable in @params)
                {
                    var p = p_loopVariable;
                    if (p.Value.ToString.Length > 70)
                    {
                        argumentdescriptions.Add(p.Attribute("name"), p.Value.ToString.Substring(0, 70).Trim("\n") + " [...]");
                    }
                    else
                    {
                        argumentdescriptions.Add(p.Attribute("name"), p.Value.ToString.Trim("\r\n"));
                    }
                }
                if (method.ReturnType.Name != "Void")
                {
                    dynamic rdesc = xmlhelp.Elements("returns").FirstOrDefault;
                    if ((rdesc != null))
                    {
                        returndescription = rdesc.Value;
                    }
                }
                dynamic redesc = xmlhelp.Elements("remarks").FirstOrDefault;
                if ((redesc != null))
                {
                    if (redesc.Value.Length > 1000)
                    {
                        remarks = redesc.Value.Substring(0, 1000) + " [...]";
                    }
                    else
                    {
                        remarks = redesc.Value;
                    }
                }
                redesc = xmlhelp.Elements("summary").FirstOrDefault;
                if ((redesc != null))
                {
                    summary  = redesc.Value;
                    txthelp += summary + "\r\n";
                }
            }

            if (method.GetParameters.Count > 0)
            {
                txthelp += "Parameters:" + "\r\n" + "\r\n";
                txthelp += "Type".PadRight(18) + "Name".PadRight(15) + "Description" + "\r\n";
                foreach (var par_loopVariable in method.GetParameters)
                {
                    var par = par_loopVariable;
                    if (argumentdescriptions.ContainsKey(par.Name))
                    {
                        txthelp += par.ParameterType.Name.PadRight(18) + par.Name.PadRight(15) + argumentdescriptions[par.Name] + "\r\n";
                    }
                    else
                    {
                        txthelp += par.ParameterType.Name.PadRight(18) + par.Name.PadRight(15) + "\r\n";
                    }
                }
                txthelp += "\r\n";
            }

            txthelp += "Return Type: " + method.ReturnType.ToString;
            if (!string.IsNullOrEmpty(returndescription))
            {
                txthelp += "\r\n" + "Return Parameter Description: " + returndescription;
            }
            if (!string.IsNullOrEmpty(remarks))
            {
                txthelp += "\r\n" + "\r\n" + "Remarks: " + remarks;
            }


            return(txthelp);

        case MemberTypes.Property:

            dynamic props = Type.GetType(member.DeclaringType.FullName).GetProperties().Where(p => p.Name == member.Name).ToList();
            dynamic prop  = props(0);

            summary = "";
            string proptype = "";

            txthelp  = prop.DeclaringType.Name + " property '" + prop.Name + "'" + "\r\n";
            txthelp += "Type: " + prop.PropertyType.ToString;

            xmlhelp = reader.GetComments(prop);

            if ((xmlhelp != null))
            {
                dynamic redesc = xmlhelp.Elements("summary").FirstOrDefault;
                if ((redesc != null))
                {
                    txthelp += "\r\n" + "Description: " + redesc.Value;
                }
            }


            return(txthelp);

        default:


            return("");
        }
    }
예제 #8
0
    /// <summary>
    /// Show a tooltip with information about the entered object method or property.
    /// </summary>
    /// <param name="scintilla"></param>
    /// <param name="reader">Jolt's XmlDocCommentReader instance, to get and display comments from assembly-generated XML file.</param>
    /// <remarks></remarks>
    public static void ShowToolTip(this ScintillaNET.Scintilla scintilla, Jolt.XmlDocCommentReader reader)
    {
        //parses the last keyword (object) (before the ".") and get suggestions for the autocomplete box from its properties and methods

        string [] splitters =
        {
            ".",
            "(",
            ")",
            " ",
            "\r",
            "\n",
            "\r\n"
        };

        dynamic text     = ScintillaExtender.getLastWord(scintilla).Split(splitters, StringSplitOptions.RemoveEmptyEntries);
        dynamic lastchar = Convert.ToChar(scintilla.GetCharAt(scintilla.CurrentPosition));

        string helptext = "";

        if (text.Length >= 2)
        {
            string lastkeyword = text[text.Length - 1];
            string lastobj     = text[text.Length - 2].Trim();
            //string obj = Convert.ToString(lastobj));
            switch (lastobj)
            {
            case "Browser":
                dynamic prop = typeof(TopDown_QA_FrameWork.Driver).GetMember(lastkeyword);
                if (prop.Length > 0)
                {
                    helptext = ScintillaExtender.FormatHelpTip(scintilla, prop[0], reader);
                }
                break;

            case "ims1":
            case "ims2":
            case "ims3":
            case "ims4":
            case "ims5":
            case "ims6":
            case "oms1":
            case "oms2":
            case "oms3":
            case "oms4":
            case "oms5":
            case "MaterialStream":
                prop = Type.GetType("DWSIM.DWSIM.SimulationObjects.Streams.MaterialStream").GetMember(lastkeyword);
                if (prop.Length > 0)
                {
                    helptext = ScintillaExtender.FormatHelpTip(scintilla, prop[0], reader);
                }
                break;

            case "ies1":
            case "oes1":
            case "EnergyStream":
                prop = Type.GetType("DWSIM.DWSIM.SimulationObjects.Streams.EnergyStream").GetMember(lastkeyword);
                if (prop.Length > 0)
                {
                    helptext = ScintillaExtender.FormatHelpTip(scintilla, prop[0], reader);
                }
                break;

            case "Flowsheet":
                prop = Type.GetType("DWSIM.FormFlowsheet").GetMember(lastkeyword);
                if (prop.Length > 0)
                {
                    helptext = ScintillaExtender.FormatHelpTip(scintilla, prop[0], reader);
                }
                break;

            case "Spreadsheet":
                prop = Type.GetType("DWSIM.SpreadsheetForm").GetMember(lastkeyword);
                if (prop.Length > 0)
                {
                    helptext = ScintillaExtender.FormatHelpTip(scintilla, prop[0], reader);
                }
                break;

            case "PropertyPackage":
                prop = Type.GetType("DWSIM.DWSIM.SimulationObjects.PropertyPackages.PropertyPackage").GetMember(lastkeyword);
                if (prop.Length > 0)
                {
                    helptext = ScintillaExtender.FormatHelpTip(scintilla, prop[0], reader);
                }
                break;

            case "UnitOp":
            case "Me":
                prop = Type.GetType("DWSIM.SimulationObjects_UnitOpBaseClass").GetMember(lastkeyword);
                if (prop.Length > 0)
                {
                    helptext = ScintillaExtender.FormatHelpTip(scintilla, prop(0), reader);
                }
                break;

            case "Solver":
                prop = Type.GetType("DWSIM.DWSIM.Flowsheet.FlowsheetSolver").GetMember(lastkeyword);
                if (prop.Length > 0)
                {
                    helptext = ScintillaExtender.FormatHelpTip(scintilla, prop(0), reader);
                }
                break;
            }

            //shows the tooltip

            if (!string.IsNullOrEmpty(helptext))
            {
                scintilla.CallTipShow(scintilla.CurrentPosition, helptext);
            }
            else
            {
                scintilla.CallTipCancel();
            }
        }
        else
        {
            //hides tooltip if visible

            scintilla.CallTipCancel();
        }
    }
예제 #9
0
파일: Program.cs 프로젝트: Dervall/Snout
        static void Main(string[] args)
        {
            string assemblyPath = null;
            string docPath = null;
            string outputPath = null;

            var optionSet = new OptionSet
            {
                { "a=|assembly=", "Path to assembly to use", f => assemblyPath = f },
                { "d=|doc=", "Path to documentation to use", f => docPath = f },
                { "o=|output=", "Output path", f => outputPath = f }
            };

            try
            {
                optionSet.Parse(args);
            }
            catch (OptionException)
            {
                Usage(optionSet);
                return;
            }

            if (assemblyPath == null)
            {
                Usage(optionSet);
                return;
            }

            assemblyPath = Path.GetFullPath(assemblyPath);

            if (docPath == null)
            {
                docPath = Path.Combine(Path.GetDirectoryName(assemblyPath),Path.GetFileNameWithoutExtension(assemblyPath) + ".xml");
            }

            if (outputPath == null)
            {
                outputPath = Directory.GetCurrentDirectory();
            }

            Console.WriteLine("Generating DSL from assembly {0}", assemblyPath);
            var targetAssembly = Assembly.LoadFile(assemblyPath);

            Console.WriteLine("Loading documentation from {0}", docPath);
            var commentReader = new XmlDocCommentReader(docPath);

            foreach (var type in targetAssembly.GetTypes())
            {
                var comments = commentReader.GetComments(type);
                if (comments != null)
                {
                    var builderClassNode = comments.Descendants().FirstOrDefault(f => f.Name == "builderclass");
                    if (builderClassNode != null)
                    {
                        var outputFile = string.Format("{0}.cs", builderClassNode.Attributes().Single(f => f.Name == "name").Value);

                        var dslBuilder = new DslBuilder(builderClassNode, commentReader, type);
                        string dslCode = dslBuilder.CreateDslCode();

                        using (var fileWriter = new StreamWriter(new FileStream(Path.Combine(outputPath, outputFile), FileMode.Create, FileAccess.Write)))
                        {
                            fileWriter.Write(dslCode);
                        }
                    }
                }
            }
        }