示例#1
0
        public static CodeCompileUnit Demo1()
        {
            // evaluates a simple expression
            var res = new CodeDomResolver();

            Console.WriteLine(res.Evaluate(SlangParser.ParseExpression("5*4-7")));

            // takes this file and get a codedom from it
            var ccu = SlangParser.ReadCompileUnitFrom("..\\..\\Demo1.cs");

            ccu.ReferencedAssemblies.Add("CodeDomGoKit.dll");
            ccu.ReferencedAssemblies.Add(typeof(CodeObject).Assembly.GetName().ToString());
            // now patch the parsed codedom so it's correct
            // NOTE: slang can't actually bind to this because it is a paramarray method
            // but we don't care here because it's not necessary. Slang only binds to what
            // it needs to and we never need the return type anyway (which is void)
            SlangPatcher.Patch(ccu);
            // now write it out in VB
            Console.WriteLine(CodeDomUtility.ToString(ccu, "vb"));
            // return the code we generated so we can use it for other demos
            // yay recycling
            Console.WriteLine("Press any key...");
            Console.ReadKey();
            Console.Clear();
            return(ccu);
        }
示例#2
0
        static void Demo4(CodeCompileUnit ccu)
        {
            // create one of these lil guys
            var res = new CodeDomResolver();

            // add our code to it
            res.CompileUnits.Add(ccu);
            // give it a chance to build its information over our code
            res.Refresh();
            CodeDomVisitor.Visit(ccu, (ctx) => {
                // for every expression...
                var expr = ctx.Target as CodeExpression;
                if (null != expr)
                {
                    // except method reference expressions...
                    var mri = expr as CodeMethodReferenceExpression;
                    if (null != mri)
                    {
                        return;
                    }
                    // get the expression type
                    var type = res.TryGetTypeOfExpression(expr);
                    // write it along with the expression itself
                    Console.WriteLine(
                        "Expression type {0}: {1} is {2}",
                        expr.GetType().Name,
                        CodeDomUtility.ToString(expr),
                        null != type?CodeDomUtility.ToString(type):"unresolvable");
                }
            });
            Console.WriteLine("Press any key...");
            Console.ReadKey();
            Console.Clear();
        }
示例#3
0
        internal CodeStatement GetCodeStatement(BaseTemplateCodeDomTreeGenerator generator, CodeExpression ctrlRefExpr)
        {
            CodeExpression expression2;

            if (this.UseSetAttribute)
            {
                CodeMethodInvokeExpression expression = new CodeMethodInvokeExpression(new CodeCastExpression(typeof(IAttributeAccessor), ctrlRefExpr), "SetAttribute", new CodeExpression[0]);
                expression.Parameters.Add(new CodePrimitiveExpression(base.Name));
                expression.Parameters.Add(new CodePrimitiveExpression(this.Value));
                return(new CodeExpressionStatement(expression));
            }
            CodeExpression right = null;

            if (base.PropertyInfo != null)
            {
                expression2 = CodeDomUtility.BuildPropertyReferenceExpression(ctrlRefExpr, base.Name);
            }
            else
            {
                expression2 = new CodeFieldReferenceExpression(ctrlRefExpr, base.Name);
            }
            if (base.Type == typeof(string))
            {
                right = generator.BuildStringPropertyExpression(this);
            }
            else
            {
                right = CodeDomUtility.GenerateExpressionForValue(base.PropertyInfo, this.Value, base.Type);
            }
            return(new CodeAssignStatement(expression2, right));
        }
示例#4
0
        static void Demo2()
        {
            var sw = new StringWriter();

            using (var sr = new StreamReader(@"..\..\Test.tt"))
                SlangPreprocessor.Preprocess(sr, sw);
            var ccu = SlangParser.ParseCompileUnit(sw.ToString());

            SlangPatcher.Patch(ccu);
            Console.WriteLine(CodeDomUtility.ToString(ccu));
            Console.WriteLine("Press any key...");
            Console.ReadKey();
            Console.Clear();
        }
示例#5
0
 static void _GenerateSymbolConstants(CodeTypeDeclaration target, IList <string> symbolTable)
 {
     // generate symbol constants
     for (int ic = symbolTable.Count, i = 0; i < ic; ++i)
     {
         var symbol = symbolTable[i];
         if (null != symbol)
         {
             var s = _MakeSafeName(symbol);
             s = _MakeUniqueMember(target, s);
             var constField = CodeDomUtility.Field(typeof(int), s, MemberAttributes.Const | MemberAttributes.Public, CodeDomUtility.Literal(i));
             target.Members.Add(constField);
         }
     }
 }
        static void _DumpMethod(object m)
        {
            // dump the method based on its type
            // can either be a MethodInfo or a
            // CodeMemberMethod
            var mi = m as MethodInfo;

            if (null != mi)
            {
                Console.WriteLine("{0}.{1}", mi.DeclaringType.Name, mi.Name);
                return;
            }
            var mm = m as CodeMemberMethod;

            Console.WriteLine(CodeDomUtility.ToString(mm));
        }
        static IList <CodeVariableDeclarationStatement> _TraceMember(CodeTypeMember m, CodeStatement t, out bool found)
        {
            var result = new List <CodeVariableDeclarationStatement>();
            var cmm    = m as CodeMemberMethod;

            if (null != cmm)
            {
                foreach (CodeStatement tt in cmm.Statements)
                {
                    Debug.WriteLine(CodeDomUtility.ToString(tt));
                    var r = _TraceStatement(tt, t, out found);
                    result.AddRange(r);
                    if (found)
                    {
                        return(result);
                    }
                }
                found = false;
                return(new CodeVariableDeclarationStatement[0]);
            }
            var cmp = m as CodeMemberProperty;

            if (null != cmp)
            {
                foreach (CodeStatement tt in cmp.GetStatements)
                {
                    var r = _TraceStatement(tt, t, out found);
                    result.AddRange(r);
                    if (found)
                    {
                        return(result);
                    }
                }
            }
            result.Clear();             // new scope
            foreach (CodeStatement tt in cmp.SetStatements)
            {
                var r = _TraceStatement(tt, t, out found);
                result.AddRange(r);
                if (found)
                {
                    return(result);
                }
            }
            found = false;
            return(new CodeVariableDeclarationStatement[0]);
        }
        // Build the statement that assigns this property
        internal CodeStatement GetCodeStatement(BaseTemplateCodeDomTreeGenerator generator,
                                                CodeExpression ctrlRefExpr)
        {
            // If we don't have a type, use IAttributeAccessor.SetAttribute
            if (UseSetAttribute)
            {
                // e.g. ((IAttributeAccessor)__ctrl).SetAttribute("{{_name}}", "{{_value}}");
                CodeMethodInvokeExpression methCallExpression = new CodeMethodInvokeExpression(
                    new CodeCastExpression(typeof(IAttributeAccessor), ctrlRefExpr),
                    "SetAttribute");

                methCallExpression.Parameters.Add(new CodePrimitiveExpression(Name));
                methCallExpression.Parameters.Add(new CodePrimitiveExpression(Value));
                return(new CodeExpressionStatement(methCallExpression));
            }

            CodeExpression leftExpr, rightExpr = null;

            if (PropertyInfo != null)
            {
                leftExpr = CodeDomUtility.BuildPropertyReferenceExpression(ctrlRefExpr, Name);
            }
            else
            {
                // In case of a field, there should only be one (unlike properties)
                Debug.Assert(Name.IndexOf('.') < 0, "_name.IndexOf('.') < 0");
                leftExpr = new CodeFieldReferenceExpression(ctrlRefExpr, Name);
            }

            if (Type == typeof(string))
            {
                rightExpr = generator.BuildStringPropertyExpression(this);
            }
            else
            {
                rightExpr = CodeDomUtility.GenerateExpressionForValue(PropertyInfo, Value, Type);
            }

            // Now that we have both side, add the assignment
            return(new CodeAssignStatement(leftExpr, rightExpr));
        }
示例#9
0
 static void Demo3(CodeCompileUnit ccu)
 {
     /// now let's take our code and modify it
     CodeDomVisitor.Visit(ccu, (ctx) => {
         // we're looking for a method invocation
         var mi = ctx.Target as CodeMethodInvokeExpression;
         if (null != mi)
         {
             // ... calling WriteLine
             if ("WriteLine" == mi.Method?.MethodName)
             {
                 // replace the passed in expression with "Hello world!"
                 mi.Parameters.Clear();
                 mi.Parameters.Add(new CodePrimitiveExpression("Hello world!"));
                 // done after the first WriteLine so we cancel
                 ctx.Cancel = true;
             }
         }
     });
     Console.WriteLine(CodeDomUtility.ToString(ccu));
     Console.WriteLine("Press any key...");
     Console.ReadKey();
     Console.Clear();
 }
示例#10
0
        static void Demo()
        {
            // note that in the real world cases, you'd need to use SlangPatcher.Patch()
            // on whole compile units to get proper codedom objects back. This method is
            // simply "close enough for government work" and may not work for languages
            // other than VB
            while (true)
            {
                Console.Write("Slang>");
                var s = Console.ReadLine();
                if (null != s)
                {
                    s = s.Trim();
                }
                if (string.IsNullOrEmpty(s))
                {
                    break;
                }
                var        isStatement = s.EndsWith(";") || s.EndsWith("}");
                CodeObject co          = null;
                try
                {
                    if (isStatement)
                    {
                        co = SlangParser.ParseStatement(s, true);
                    }
                    else
                    {
                        co = SlangParser.ParseExpression(s);
                    }
                }
                catch (SlangSyntaxException ex)
                {
                    Console.WriteLine("Error: " + ex.Message);
                }
                if (null != co)
                {
                    var ccu = _RootCode(co);
                    try
                    {
                        SlangPatcher.Patch(ccu);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Warning: Error resolving code - " + ex.Message);
                    }
                    var tc   = new CodeDomTypeConverter();
                    var item = (ccu.Namespaces[0].Types[0].Members[0] as CodeMemberMethod).Statements[0];

                    if (!isStatement)
                    {
                        co = item;
                        var es = item as CodeExpressionStatement;
                        if (null != es)
                        {
                            co = es.Expression;
                        }
                    }
                    else
                    {
                        co = item;
                    }

                    s = CodeDomUtility.ToString(co);
                    s = s.Trim();
                    Console.Write("C#: ");
                    Console.WriteLine(s);
                    s = CodeDomUtility.ToString(co, "vb");
                    s = s.Trim();
                    Console.Write("VB: ");
                    Console.WriteLine(s);

                    s = CodeDomUtility.ToString(CodeDomUtility.Literal(co, tc));
                    s = s.Trim();

                    Console.Write("CodeDom: ");
                    Console.WriteLine(s);
                    if (null != SlangPatcher.GetNextUnresolvedElement(ccu))
                    {
                        Console.WriteLine("Warning: Not all of the code could be resolved.");
                    }
                }
            }
        }
示例#11
0
        public static int Run(string[] args, TextReader stdin, TextWriter stdout, TextWriter stderr)
        {
            // our return code
            var result = 0;
            // app parameters
            string inputfile     = null;
            string outputfile    = null;
            string codeclass     = null;
            string codelanguage  = null;
            string codenamespace = null;
            string externaltoken = null;
            string nfagraph      = null;
            string dfagraph      = null;
            bool   ignorecase    = false;
            bool   noshared      = false;
            bool   ifstale       = false;
            // our working variables
            TextReader input  = null;
            TextWriter output = null;

            try
            {
                if (0 == args.Length)
                {
                    _PrintUsage(stderr);
                    result = -1;
                }
                else if (args[0].StartsWith("/"))
                {
                    throw new ArgumentException("Missing input file.");
                }
                else
                {
                    // process the command line args
                    inputfile = args[0];
                    for (var i = 1; i < args.Length; ++i)
                    {
                        switch (args[i].ToLowerInvariant())
                        {
                        case "/output":
                            if (args.Length - 1 == i)                                     // check if we're at the end
                            {
                                throw new ArgumentException(string.Format("The parameter \"{0}\" is missing an argument", args[i].Substring(1)));
                            }
                            ++i;                                     // advance
                            outputfile = args[i];
                            break;

                        case "/class":
                            if (args.Length - 1 == i)                                     // check if we're at the end
                            {
                                throw new ArgumentException(string.Format("The parameter \"{0}\" is missing an argument", args[i].Substring(1)));
                            }
                            ++i;                                     // advance
                            codeclass = args[i];
                            break;

                        case "/language":
                            if (args.Length - 1 == i)                                     // check if we're at the end
                            {
                                throw new ArgumentException(string.Format("The parameter \"{0}\" is missing an argument", args[i].Substring(1)));
                            }
                            ++i;                                     // advance
                            codelanguage = args[i];
                            break;

                        case "/namespace":
                            if (args.Length - 1 == i)                                     // check if we're at the end
                            {
                                throw new ArgumentException(string.Format("The parameter \"{0}\" is missing an argument", args[i].Substring(1)));
                            }
                            ++i;                                     // advance
                            codenamespace = args[i];
                            break;

                        case "/external":
                            if (args.Length - 1 == i)                                     // check if we're at the end
                            {
                                throw new ArgumentException(string.Format("The parameter \"{0}\" is missing an argument", args[i].Substring(1)));
                            }
                            ++i;                                     // advance
                            externaltoken = args[i];
                            break;

                        case "/nfagraph":
                            if (args.Length - 1 == i)                                     // check if we're at the end
                            {
                                throw new ArgumentException(string.Format("The parameter \"{0}\" is missing an argument", args[i].Substring(1)));
                            }
                            ++i;                                     // advance
                            nfagraph = args[i];
                            break;

                        case "/dfagraph":
                            if (args.Length - 1 == i)                                     // check if we're at the end
                            {
                                throw new ArgumentException(string.Format("The parameter \"{0}\" is missing an argument", args[i].Substring(1)));
                            }
                            ++i;                                     // advance
                            dfagraph = args[i];
                            break;

                        case "/ignorecase":
                            ignorecase = true;
                            break;

                        case "/noshared":
                            noshared = true;
                            break;

                        case "/ifstale":
                            ifstale = true;
                            break;


                        default:
                            throw new ArgumentException(string.Format("Unknown switch {0}", args[i]));
                        }
                    }
                    // now build it
                    if (string.IsNullOrEmpty(codeclass))
                    {
                        // default we want it to be named after the code file
                        // otherwise we'll use inputfile
                        if (null != outputfile)
                        {
                            codeclass = Path.GetFileNameWithoutExtension(outputfile);
                        }
                        else
                        {
                            codeclass = Path.GetFileNameWithoutExtension(inputfile);
                        }
                    }
                    if (string.IsNullOrEmpty(codelanguage))
                    {
                        if (!string.IsNullOrEmpty(outputfile))
                        {
                            codelanguage = Path.GetExtension(outputfile);
                            if (codelanguage.StartsWith("."))
                            {
                                codelanguage = codelanguage.Substring(1);
                            }
                        }
                        if (string.IsNullOrEmpty(codelanguage))
                        {
                            codelanguage = "cs";
                        }
                    }
                    var stale = true;
                    if (ifstale && null != outputfile)
                    {
                        stale = _IsStale(inputfile, outputfile);
                        if (!stale)
                        {
                            stale = _IsStale(CodeBase, outputfile);
                        }
                    }
                    if (!stale)
                    {
                        stderr.WriteLine("{0} skipped building {1} because it was not stale.", Name, outputfile);
                    }
                    else
                    {
                        if (null != outputfile)
                        {
                            stderr.Write("{0} is building file: {1}", Name, outputfile);
                        }
                        else
                        {
                            stderr.Write("{0} is building tokenizer.", Name);
                        }
                        input = new StreamReader(inputfile);
                        var    rules = new List <LexRule>();
                        string line;
                        while (null != (line = input.ReadLine()))
                        {
                            var lc = LexContext.Create(line);
                            lc.TrySkipCCommentsAndWhiteSpace();
                            if (-1 != lc.Current)
                            {
                                rules.Add(LexRule.Parse(lc));
                            }
                        }
                        input.Close();
                        input = null;
                        LexRule.FillRuleIds(rules);

                        var ccu = new CodeCompileUnit();
                        var cns = new CodeNamespace();
                        if (!string.IsNullOrEmpty(codenamespace))
                        {
                            cns.Name = codenamespace;
                        }
                        ccu.Namespaces.Add(cns);
                        var fa          = _BuildLexer(rules, ignorecase, inputfile);
                        var symbolTable = _BuildSymbolTable(rules);
                        var symids      = new int[symbolTable.Length];
                        for (var i = 0; i < symbolTable.Length; ++i)
                        {
                            symids[i] = i;
                        }
                        var blockEnds = _BuildBlockEnds(rules);
                        var nodeFlags = _BuildNodeFlags(rules);
                        if (null != nfagraph)
                        {
                            fa.RenderToFile(nfagraph);
                        }

                        fa = fa.ToDfa();
                        DfaEntry[] dfaTable = null;
                        dfaTable = _ToDfaStateTable(fa, symids);
                        if (!noshared)
                        {
                            if (string.IsNullOrEmpty(externaltoken))
                            {
                                // import our Export/Token.cs into the library
                                _ImportCompileUnit(Deslanged.Token, cns);
                            }

                            // import our Export/TableTokenizer.cs into the library
                            _ImportCompileUnit(Deslanged.TableTokenizer, cns);
                        }
                        if (!string.IsNullOrEmpty(externaltoken))
                        {
                            cns.Imports.Add(new CodeNamespaceImport(externaltoken));
                        }
                        var origName           = "Rolex.";
                        CodeTypeDeclaration td = null;
                        if (null == td)
                        {
                            td        = Deslanged.TableTokenizerTemplate.Namespaces[1].Types[0];
                            origName += td.Name;
                            td.Name   = codeclass;
                            CodeGenerator.GenerateSymbolConstants(td, symbolTable);
                        }
                        CodeDomVisitor.Visit(td, (ctx) =>
                        {
                            var tr = ctx.Target as CodeTypeReference;
                            if (null != tr)
                            {
                                if (0 == string.Compare(origName, tr.BaseType, StringComparison.InvariantCulture))
                                {
                                    tr.BaseType = codeclass;
                                }
                            }
                        });
                        CodeMemberField f = null;

                        f = CodeDomUtility.GetByName("DfaTable", td.Members) as CodeMemberField;
                        f.InitExpression = CodeGenerator.GenerateDfaTableInitializer(dfaTable);

                        f = CodeDomUtility.GetByName("NodeFlags", td.Members) as CodeMemberField;
                        f.InitExpression = CodeDomUtility.Literal(nodeFlags);
                        f = CodeDomUtility.GetByName("BlockEnds", td.Members) as CodeMemberField;
                        f.InitExpression = CodeDomUtility.Literal(blockEnds);

                        cns.Types.Add(td);

                        var hasColNS = false;
                        foreach (CodeNamespaceImport nsi in cns.Imports)
                        {
                            if (0 == string.Compare(nsi.Namespace, "System.Collections.Generic", StringComparison.InvariantCulture))
                            {
                                hasColNS = true;
                                break;
                            }
                        }
                        if (!hasColNS)
                        {
                            cns.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
                        }

                        stderr.WriteLine();
                        var prov = CodeDomProvider.CreateProvider(codelanguage);
                        var opts = new CodeGeneratorOptions();
                        opts.BlankLinesBetweenMembers = false;
                        opts.VerbatimOrder            = true;
                        if (null == outputfile)
                        {
                            output = stdout;
                        }
                        else
                        {
                            // open the file and truncate it if necessary
                            var stm = File.Open(outputfile, FileMode.Create);
                            stm.SetLength(0);
                            output = new StreamWriter(stm);
                        }
                        prov.GenerateCodeFromCompileUnit(ccu, output, opts);
                    }
                }
            }
            // we don't like to catch in debug mode
#if !DEBUG
            catch (Exception ex)
            {
                result = _ReportError(ex, stderr);
            }
#endif
            finally
            {
                // close the input file if necessary
                if (null != input)
                {
                    input.Close();
                }
                // close the output file if necessary
                if (null != outputfile && null != output)
                {
                    output.Close();
                }
            }
            return(result);
        }
        static void Demo6()
        {
            // load the xsd
            XmlSchema xsd = null;

            using (FileStream stream = new FileStream("..\\..\\Test.xsd", FileMode.Open, FileAccess.Read))
            {
                xsd = XmlSchema.Read(stream, null);
            }

            XmlSchemas xsds = new XmlSchemas();

            xsds.Add(xsd);
            xsds.Compile(null, true);
            XmlSchemaImporter xsdImporter = new XmlSchemaImporter(xsds);

            // create the codedom
            CodeNamespace   ns  = new CodeNamespace();
            CodeCompileUnit ccu = new CodeCompileUnit();

            ccu.ReferencedAssemblies.Add(typeof(XmlTypeAttribute).Assembly.GetName().ToString());
            ccu.Namespaces.Add(ns);
            XmlCodeExporter codeExporter = new XmlCodeExporter(ns, ccu);

            var maps = new List <XmlTypeMapping>();

            foreach (XmlSchemaType schemaType in xsd.SchemaTypes.Values)
            {
                maps.Add(xsdImporter.ImportSchemaType(schemaType.QualifiedName));
            }
            foreach (XmlSchemaElement schemaElement in xsd.Elements.Values)
            {
                maps.Add(xsdImporter.ImportTypeMapping(schemaElement.QualifiedName));
            }
            foreach (XmlTypeMapping map in maps)
            {
                codeExporter.ExportTypeMapping(map);
            }
            var typeMap = new Dictionary <string, CodeTypeDeclaration>(StringComparer.InvariantCulture);

            _FillTypeMap(ns, typeMap);
            foreach (var kvp in typeMap)
            {
                var td       = kvp.Value;
                var propElem = new HashSet <string>(StringComparer.InvariantCulture);
                var propAttr = new HashSet <string>(StringComparer.InvariantCulture);
                var fldMap   = new Dictionary <string, string>();
                _FillPropFldMaps(td, propElem, propAttr, fldMap);
                // fix up our xml type attribute
                foreach (CodeAttributeDeclaration d in td.CustomAttributes)
                {
                    if (0 == string.Compare(d.AttributeType.BaseType, "System.Xml.Serialization.XmlAttributeAttribute", StringComparison.InvariantCulture))
                    {
                        d.Arguments.Insert(0, new CodeAttributeArgument("TypeName", new CodePrimitiveExpression(td.Name)));
                        break;
                    }
                }
                // correct the type name
                td.Name = _ToNetCase(td.Name);
                CodeDomVisitor.Visit(td, (ctx) =>
                {
                    var fldRef = ctx.Target as CodeFieldReferenceExpression;
                    if (null != fldRef && fldMap.ContainsKey(fldRef.FieldName))
                    {
                        fldRef.FieldName = _ToPrivFldName(fldRef.FieldName);
                        return;
                    }
                    var fld = ctx.Target as CodeMemberField;
                    if (null != fld && fldMap.ContainsKey(fld.Name))
                    {
                        fld.Name = _ToPrivFldName(fld.Name);
                        var ctr  = fld.Type;
                        if (0 < ctr.ArrayRank)
                        {
                            ctr = ctr.ArrayElementType;
                        }
                        if (!CodeDomResolver.IsPrimitiveType(ctr))
                        {
                            ctr.BaseType = _ToNetCase(ctr.BaseType);
                        }
                    }
                    var prop = ctx.Target as CodeMemberProperty;
                    if (null != prop && (propElem.Contains(prop.Name) || propAttr.Contains(prop.Name)))
                    {
                        var n   = prop.Name;
                        var ctr = prop.Type;
                        if (0 < ctr.ArrayRank)
                        {
                            ctr = ctr.ArrayElementType;
                        }
                        if (!CodeDomResolver.IsPrimitiveType(ctr))
                        {
                            ctr.BaseType = _ToNetCase(ctr.BaseType);
                        }
                        prop.Name = _ToNetCase(n);
                        if (propElem.Contains(n))
                        {
                            foreach (CodeAttributeDeclaration a in prop.CustomAttributes)
                            {
                                if (0 == string.Compare("System.Xml.Serialization.XmlElementAttribute", a.AttributeType.BaseType, StringComparison.InvariantCulture))
                                {
                                    a.Arguments.Insert(0, new CodeAttributeArgument("ElementName", new CodePrimitiveExpression(n)));
                                    break;
                                }
                            }
                        }
                        else
                        {
                            foreach (CodeAttributeDeclaration a in prop.CustomAttributes)
                            {
                                if (0 == string.Compare("System.Xml.Serialization.XmlAttributeAttribute", a.AttributeType.BaseType, StringComparison.InvariantCulture))
                                {
                                    a.Arguments.Insert(0, new CodeAttributeArgument("AttributeName", new CodePrimitiveExpression(n)));
                                    break;
                                }
                            }
                        }
                    }
                });
            }

            // Check for invalid characters in identifiers
            CodeGenerator.ValidateIdentifiers(ns);

            // output the C# code
            Console.WriteLine(CodeDomUtility.ToString(ccu));
        }
示例#13
0
        static int Main(string[] args)
        {
            var result = 0;

            string     outputfile    = null;
            string     codeclass     = null;
            string     codenamespace = null;
            string     codelanguage  = null;
            string     t4language    = null;
            string     t4arguments   = null;
            bool       noserialize   = false;
            bool       ifstale       = false;
            bool       mutable       = false;
            TextReader input         = null;
            TextWriter output        = null;

            try
            {
                var asms   = new List <string>(args.Length);
                var inputs = new List <string>(args.Length);
                if (0 == args.Length)
                {
                    _PrintUsage();
                    result = -1;
                }
                else if (args[0].StartsWith("/"))
                {
                    throw new ArgumentException("Missing input file.");
                }
                else
                {
                    int start = 0;

                    // process the command line args
                    for (start = 0; start < args.Length; ++start)
                    {
                        var a = args[start];
                        if (a.StartsWith("/"))
                        {
                            break;
                        }
                        inputs.Add(a);
                    }
                    for (var i = start; i < args.Length; ++i)
                    {
                        switch (args[i])
                        {
                        case "/output":
                            if (args.Length - 1 == i)                                     // check if we're at the end
                            {
                                throw new ArgumentException(string.Format("The parameter \"{0}\" is missing an argument", args[i].Substring(1)));
                            }
                            ++i;                                     // advance
                            outputfile = args[i];
                            break;

                        case "/language":
                            if (args.Length - 1 == i)                                     // check if we're at the end
                            {
                                throw new ArgumentException(string.Format("The parameter \"{0}\" is missing an argument", args[i].Substring(1)));
                            }
                            ++i;                                     // advance
                            codelanguage = args[i];
                            break;

                        case "/t4language":
                            if (args.Length - 1 == i)                                     // check if we're at the end
                            {
                                throw new ArgumentException(string.Format("The parameter \"{0}\" is missing an argument", args[i].Substring(1)));
                            }
                            ++i;                                     // advance
                            t4language = args[i];
                            break;

                        case "/t4args":
                            if (args.Length - 1 == i)                                     // check if we're at the end
                            {
                                throw new ArgumentException(string.Format("The parameter \"{0}\" is missing an argument", args[i].Substring(1)));
                            }
                            ++i;                                     // advance
                            t4arguments = args[i];
                            break;

                        case "/class":
                            if (args.Length - 1 == i)                                     // check if we're at the end
                            {
                                throw new ArgumentException(string.Format("The parameter \"{0}\" is missing an argument", args[i].Substring(1)));
                            }
                            ++i;                                     // advance
                            codeclass = args[i];
                            break;

                        case "/namespace":
                            if (args.Length - 1 == i)                                     // check if we're at the end
                            {
                                throw new ArgumentException(string.Format("The parameter \"{0}\" is missing an argument", args[i].Substring(1)));
                            }
                            ++i;                                     // advance
                            codenamespace = args[i];
                            break;

                        case "/asms":
                            if (args.Length - 1 == i)                                     // check to see if we're at the end
                            {
                                throw new ArgumentException(string.Format("The parameter \"{0}\" is missing an argument", args[i].Substring(1)));
                            }
                            ++i;
                            while (i < args.Length && !args[i].StartsWith("/"))
                            {
                                asms.Add(args[i]);
                                ++i;
                            }
                            if (0 == asms.Count)
                            {
                                throw new ArgumentException(string.Format("The parameter \"{0}\" is missing an argument", args[i - 1].Substring(1)));
                            }
                            break;

                        case "/ifstale":
                            ifstale = true;
                            break;

                        case "/mutable":
                            mutable = true;
                            break;

                        case "/noserialize":
                            noserialize = true;
                            break;

                        default:
                            throw new ArgumentException(string.Format("Unknown switch {0}", args[i]));
                        }
                    }

                    // now build it.
                    if (string.IsNullOrEmpty(t4language))
                    {
                        t4language = "cs";
                    }
                    if (string.IsNullOrEmpty(codelanguage))
                    {
                        if (!string.IsNullOrEmpty(outputfile))
                        {
                            codelanguage = Path.GetExtension(outputfile);
                            if (codelanguage.StartsWith("."))
                            {
                                codelanguage = codelanguage.Substring(1);
                            }
                        }
                        if (string.IsNullOrEmpty(codelanguage))
                        {
                            codelanguage = "cs";
                        }
                    }
                    var stale = true;
                    if (ifstale && null != outputfile)
                    {
                        stale = false;
                        foreach (var f in inputs)
                        {
                            if (_IsStale(f, outputfile) || _IsStale(_CodeBase, outputfile))
                            {
                                stale = true;
                                break;
                            }
                        }
                    }
                    if (!stale)
                    {
                        Console.Error.WriteLine("{0} skipped cook of {1} because it was not stale.", _Name, outputfile);
                    }
                    else
                    {
                        // main build code here
                        if (null != outputfile)
                        {
                            Console.Error.Write("{0} is cooking {1}.", _Name, outputfile);
                        }
                        else
                        {
                            Console.Error.Write("{0} is cooking deslanged code.", _Name);
                        }

                        #region Load Builder
                        CodeCompileUnit builderCcu = null;
                        using (var stm = typeof(Program).Assembly.GetManifestResourceStream("Deslang.Shared.CodeDomBuilder.cs"))
                        {
                            builderCcu = SlangParser.ReadCompileUnitFrom(stm);
                        }
                        builderCcu.ReferencedAssemblies.Add(typeof(CodeObject).Assembly.GetName().ToString());
                        SlangPatcher.Patch(builderCcu);
                        #endregion

                        var donor = builderCcu.Namespaces[1].Types[0];

                        Console.Error.WriteLine();
                        var sb    = new StringBuilder();
                        var sw    = new StringWriter(sb);
                        var ccus  = new CodeCompileUnit[inputs.Count];
                        var targs = new Dictionary <string, object>();
                        if (null != t4arguments)
                        {
                            var ta = t4arguments.Split('&');
                            for (var i = 0; i < ta.Length; i++)
                            {
                                var    tap = ta[i].Split('=');
                                var    n   = tap[0];
                                object o   = null;
                                if (1 < tap.Length)
                                {
                                    o = Uri.UnescapeDataString(tap[1]);
                                }
                                targs[n] = o;
                            }
                        }
                        for (var i = 0; i < ccus.Length; i++)
                        {
                            var f = inputs[i];
                            sb.Clear();
                            input = new StreamReader(f);

                            SlangPreprocessor.Preprocess(input, sw, targs, t4language);

                            input.Close();
                            input = null;
                            var ccu = SlangParser.ParseCompileUnit(sw.ToString());
                            if (0 == i)
                            {
                                ccu.ReferencedAssemblies.AddRange(asms.ToArray());
                                ccu.ReferencedAssemblies.Add(typeof(CodeObject).Assembly.GetName().ToString());
                            }
                            ccus[i] = ccu;
                        }
                        // now our unpatched input is in ccus
                        SlangPatcher.Patch(ccus);
                        var  co = SlangPatcher.GetNextUnresolvedElement(ccus);
                        int  l = 0, c = 0;
                        long p = 0L;

                        if (null != co)
                        {
                            Console.Error.Write("Warning - input was not entirely resolved. Output may not be valid. Next unresolved element is: " + CodeDomUtility.ToString(co));
                            var o = co.UserData["slang:line"];
                            if (o is int)
                            {
                                l = (int)o;
                            }
                            o = co.UserData["slang:column"];
                            if (o is int)
                            {
                                c = (int)o;
                            }
                            o = co.UserData["slang:position"];
                            if (o is long)
                            {
                                p = (long)o;
                            }
                        }
                        if (l + c + p > 0)
                        {
                            Console.Error.WriteLine(" at line {0}, column {1}, position {2}", l, c, p);
                        }
                        else
                        {
                            Console.Error.WriteLine();
                        }
                        var ns       = new CodeNamespace();
                        var ccuFinal = new CodeCompileUnit();
                        ccuFinal.Namespaces.Add(ns);
                        if (!noserialize)
                        {
                            // now they're patched. Let's serialize.
                            // create our namespace and compileunit.

                            if (string.IsNullOrEmpty(codeclass))
                            {
                                codeclass = "Deslanged";
                            }
                            var cls = new CodeTypeDeclaration(codeclass);
                            cls.IsClass        = true;
                            cls.IsPartial      = true;
                            cls.TypeAttributes = TypeAttributes.NotPublic;
                            for (var i = 0; i < ccus.Length; i++)
                            {
                                var ccuInit = C.Literal(ccus[i], new CodeDomTypeConverter());
                                V.Visit(ccuInit, (ctx) =>
                                {
                                    var tr = ctx.Target as CodeTypeReference;
                                    if (null != tr)
                                    {
                                        if (tr.BaseType.StartsWith("System.CodeDom."))
                                        {
                                            tr.BaseType = tr.BaseType.Substring(15);
                                        }
                                        else if (tr.BaseType.StartsWith("System.Reflection."))
                                        {
                                            tr.BaseType = tr.BaseType.Substring(18);
                                        }
                                    }
                                    // look for our uses of codedombuilder
                                    var mi = ctx.Target as CodeMethodInvokeExpression;
                                    if (null != mi)
                                    {
                                        var tref = mi.Method.TargetObject as CodeTypeReferenceExpression;
                                        if (null != tref)
                                        {
                                            if (0 == string.Compare("CD.CodeDomBuilder", tref.Type.BaseType, StringComparison.InvariantCulture))
                                            {
                                                mi.Method.TargetObject = C.TypeRef(codeclass);
                                                // find the method in our donor type;
                                                var m = C.GetByName(mi.Method.MethodName, donor.Members);
                                                if (null != m)                                                 // if it hasn't already been moved
                                                {
                                                    // move it
                                                    m.Name       = "_" + m.Name;
                                                    m.Attributes = (m.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Private;
                                                    donor.Members.Remove(m);
                                                    cls.Members.Add(m);
                                                }
                                                mi.Method.MethodName = "_" + mi.Method.MethodName;
                                            }
                                        }
                                    }
                                });
                                var name = Path.GetFileNameWithoutExtension(inputs[i]);
                                if (mutable)
                                {
                                    var fld = C.Field(typeof(CodeCompileUnit), name, MemberAttributes.Public | MemberAttributes.Static, ccuInit);
                                    cls.Members.Add(fld);
                                }
                                else
                                {
                                    var prop = C.Property(typeof(CodeCompileUnit), name, MemberAttributes.Public | MemberAttributes.Static);
                                    prop.GetStatements.Add(C.Return(ccuInit));
                                    cls.Members.Add(prop);
                                }
                            }
                            if (!string.IsNullOrEmpty(codenamespace))
                            {
                                ns.Name = codenamespace;
                            }
                            ns.Types.Add(cls);
                            ns.Imports.Add(new CodeNamespaceImport("System.CodeDom"));
                            ns.Imports.Add(new CodeNamespaceImport("System.Reflection"));
                        }
                        else
                        {
                            foreach (var ccu in ccus)
                            {
                                foreach (CodeDirective dir in ccu.StartDirectives)
                                {
                                    ccuFinal.StartDirectives.Add(dir);
                                }
                                foreach (CodeDirective dir in ccu.EndDirectives)
                                {
                                    ccuFinal.EndDirectives.Add(dir);
                                }
                                foreach (CodeAttributeDeclaration attr in ccu.AssemblyCustomAttributes)
                                {
                                    ccuFinal.AssemblyCustomAttributes.Add(attr);
                                }
                                foreach (CodeNamespace cns in ccu.Namespaces)
                                {
                                    var ccns = CodeDomUtility.GetByName(cns.Name, ccuFinal.Namespaces);
                                    if (null == ccns)
                                    {
                                        ccns      = new CodeNamespace();
                                        ccns.Name = cns.Name;
                                        ccuFinal.Namespaces.Add(ccns);
                                    }
                                    foreach (CodeNamespaceImport nsi in cns.Imports)
                                    {
                                        var found = false;
                                        foreach (CodeNamespaceImport nnsi in ccns.Imports)
                                        {
                                            if (nnsi.Namespace.Equals(nsi.Namespace, StringComparison.Ordinal))
                                            {
                                                found = true;
                                                break;
                                            }
                                        }
                                        if (!found)
                                        {
                                            ccns.Imports.Add(nsi);
                                        }
                                    }
                                    foreach (CodeCommentStatement ccs in cns.Comments)
                                    {
                                        ccns.Comments.Add(ccs);
                                    }
                                    foreach (CodeTypeDeclaration td in cns.Types)
                                    {
                                        ccns.Types.Add(td);
                                    }
                                }
                            }
                        }
                        // we're ready with ccuFinal
                        var prov = CodeDomProvider.CreateProvider(codelanguage);
                        var opts = new CodeGeneratorOptions();
                        opts.BlankLinesBetweenMembers = false;
                        opts.VerbatimOrder            = true;
                        if (null == outputfile)
                        {
                            output = Console.Out;
                        }
                        else
                        {
                            // open the file and truncate it if necessary
                            var stm = File.Open(outputfile, FileMode.Create);
                            stm.SetLength(0);
                            output = new StreamWriter(stm);
                        }
                        prov.GenerateCodeFromCompileUnit(ccuFinal, output, opts);
                    }
                }
            }
#if !DEBUG
            catch (Exception ex)
            {
                result = _ReportError(ex);
            }
#endif
            finally
            {
                if (null != input)
                {
                    input.Close();
                    input = null;
                }
                if (null != outputfile && null != output)
                {
                    output.Close();
                    output = null;
                }
            }
            return(result);
        }