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); }
static void _Test(string file) { Console.WriteLine("Parsing file: " + file); // don't read directly from the file for perf testing. StreamReader sr = null; string text = null; try { sr = new StreamReader(file); text = sr.ReadToEnd(); } finally { if (null != sr) { sr.Close(); } } var sw = new Stopwatch(); sw.Start(); for (var i = 0; i < 100; ++i) { CodeObject co = SlangParser.ParseCompileUnit(text); } sw.Stop(); Console.WriteLine("Parsed " + Path.GetFileName(file) + " in " + (sw.ElapsedMilliseconds / 100d) + " msec"); //Console.WriteLine(CodeDomUtility.ToString(co).TrimEnd()); }
static void RunResolver() { byte[] data; using (var stream = File.OpenRead(@"myfile.bin")) { data = new byte[(int)stream.Length]; stream.Read(data, 0, data.Length); } // create a resolver var res = new CodeDomResolver(); // read the resolver sample into the compile unit CodeCompileUnit ccu; using (var stm = File.OpenRead(@"..\..\Resolver.cs")) ccu = SlangParser.ReadCompileUnitFrom(stm); // remember to patch it! SlangPatcher.Patch(ccu); Console.Error.WriteLine(CU.ToString(ccu)); // add the compile unit to the resolver res.CompileUnits.Add(ccu); // prepare the resolver // any time you add compile units you'll need // to call Refresh() res.Refresh(); // go through all expressions in the // graph and try to get their type CodeDomVisitor.Visit(ccu, (ctx) => { var expr = ctx.Target as CodeExpression; if (null != expr) { // we want everything except CodeTypeReferenceExpression var ctre = expr as CodeTypeReferenceExpression; if (null == ctre) { // get the scope of the expression var scope = res.GetScope(expr); CodeTypeReference ctr = res.TryGetTypeOfExpression(expr, scope); if (null != ctr) { Console.WriteLine(CU.ToString(expr) + " is type: " + CU.ToString(ctr)); Console.WriteLine("Scope Dump:"); Console.WriteLine(scope.ToString()); } } } }); }
static void RunTemplate() { // compute the primes. algorithm borrowed // from SLax at https://stackoverflow.com/questions/1510124/program-to-find-prime-numbers var primesMax = 100; var primesArr = Enumerable.Range(0, (int)Math.Floor(2.52 * Math.Sqrt(primesMax) / Math.Log(primesMax))).Aggregate( Enumerable.Range(2, primesMax - 1).ToList(), (result, index) => { var bp = result[index]; var sqr = bp * bp; result.RemoveAll(i => i >= sqr && i % bp == 0); return(result); } ).ToArray(); // read the template into the compile unit CodeCompileUnit ccu; using (var stm = File.OpenRead(@"..\..\Template.cs")) ccu = SlangParser.ReadCompileUnitFrom(stm); // patch it either before or after modifying it SlangPatcher.Patch(ccu); // find the target namespace and change it var ns = ccu.TryGetNamespace("T_NAMESPACE"); ns.Name = "TestNS"; // find the target class var type = ns.TryGetType("T_TYPE"); // change the name type.Name = "TestPrimes"; // get the Primes field: var primes = type.TryGetMember("Primes") as CodeMemberField; // change the init expression to the primes array primes.InitExpression = CU.Literal(primesArr); // fixup any references to T_NAMESPACE or T_TYPE CodeDomVisitor.Visit(ccu, (ctx) => { var ctr = ctx.Target as CodeTypeReference; if (null != ctr) { ctr.BaseType = ctr.BaseType.Replace("T_NAMESPACE", ns.Name).Replace("T_TYPE", type.Name); } }); // already patched prior // SlangPatcher.Patch(ccu); // now write the result out Console.WriteLine(CU.ToString(ccu)); }
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(); }
static void RunBinding() { // we'll need the resolver in a bit var res = new CodeDomResolver(); // read the binding sample into the compile unit CodeCompileUnit ccu; using (var stm = File.OpenRead(@"..\..\Binding.cs")) ccu = SlangParser.ReadCompileUnitFrom(stm); // add the compile unit to the resolver res.CompileUnits.Add(ccu); // prepare the resolver res.Refresh(); // get the first class available var tdecl = ccu.Namespaces[1].Types[0]; // capture the scope at the typedecl level var scope = res.GetScope(tdecl); // create a new binder with that scope var binder = new CodeDomBinder(scope); // get the method group for Test(...) var methodGroup = binder.GetMethodGroup(tdecl, "Test", BindingFlags.Public | BindingFlags.Instance); // select the method that can take a string value var m = binder.SelectMethod(BindingFlags.Public, methodGroup, new CodeTypeReference[] { new CodeTypeReference(typeof(string)) }, null); Console.WriteLine(CU.ToString((CodeMemberMethod)m)); // select the method that can take a short value // (closest match accepts int) m = binder.SelectMethod(BindingFlags.Public, methodGroup, new CodeTypeReference[] { new CodeTypeReference(typeof(short)) }, null); Console.WriteLine(CU.ToString((CodeMemberMethod)m)); }
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."); } } } }
public static CodeCompileUnit GenerateCompileUnit(XbnfGenerationInfo genInfo, string codeclass, string codenamespace, bool fast) { var result = new CodeCompileUnit(); var ns = new CodeNamespace(); if (!string.IsNullOrEmpty(codenamespace)) { ns.Name = codenamespace; } result.Namespaces.Add(ns); ns.Imports.Add(new CodeNamespaceImport("System.Collections.Generic")); var td = C.Class(codeclass, false); td.CustomAttributes.Add(GeneratedCodeAttribute); td.BaseTypes.Add(C.Type("GlrTableParser")); // GlrTableParser(int[][][][] parseTable,string[] symbolTable, ParseAttribute[][] attributes,int[] errorSentinels, IEnumerable<Token> tokenizer,int maxErrorCount) td.Members.Add(C.Field(C.Type(typeof(int[][][][])), "ParseTable", MemberAttributes.FamilyAndAssembly | MemberAttributes.Static)); td.Members.Add(C.Field(C.Type(typeof(string[])), "SymbolTable", MemberAttributes.FamilyAndAssembly | MemberAttributes.Static)); td.Members.Add(C.Field(C.Type(C.Type("ParseAttribute", 1), 1), "ParseAttributes", MemberAttributes.FamilyAndAssembly | MemberAttributes.Static)); td.Members.Add(C.Field(C.Type(typeof(int[])), "ErrorSentinels", MemberAttributes.FamilyAndAssembly | MemberAttributes.Static)); //td.Members.Add(C.Field(C.Type(typeof(int[])), "NodeFlags", MemberAttributes.FamilyAndAssembly | MemberAttributes.Static)); var et = C.Type("IEnumerable"); et.TypeArguments.Add(C.Type("Token")); var ctor = C.Ctor(MemberAttributes.Public, C.Param(et, "tokenizer")); ctor.BaseConstructorArgs.AddRange(new CodeExpression[] { C.FieldRef(C.TypeRef(codeclass), "ParseTable"), C.FieldRef(C.TypeRef(codeclass), "SymbolTable"), C.FieldRef(C.TypeRef(codeclass), "ParseAttributes"), C.FieldRef(C.TypeRef(codeclass), "ErrorSentinels"), //C.FieldRef(C.TypeRef(codeclass), "NodeFlags"), C.ArgRef("tokenizer"), C.FieldRef(C.TypeRef(typeof(int)), "MaxValue") }); td.Members.Add(ctor); ctor = C.Ctor(MemberAttributes.Public, C.Param(et, "tokenizer"), C.Param(typeof(int), "maxErrorCount")); ctor.BaseConstructorArgs.AddRange(new CodeExpression[] { C.FieldRef(C.TypeRef(codeclass), "ParseTable"), C.FieldRef(C.TypeRef(codeclass), "SymbolTable"), C.FieldRef(C.TypeRef(codeclass), "ParseAttributes"), C.FieldRef(C.TypeRef(codeclass), "ErrorSentinels"), //C.FieldRef(C.TypeRef(codeclass), "NodeFlags"), C.ArgRef("tokenizer"), C.ArgRef("maxErrorCount") }); td.Members.Add(ctor); ns.Types.Add(td); CfgGlrParseTable pt; genInfo.Cfg.TryToGlrParseTable(out pt); int ts; var syms = XbnfConvert.GetSymbolTable(genInfo, out ts); (C.GetByName("ParseTable", td.Members) as CodeMemberField).InitExpression = C.Literal(pt.ToArray(syms)); (C.GetByName("SymbolTable", td.Members) as CodeMemberField).InitExpression = C.Literal(syms.ToArray()); (C.GetByName("ParseAttributes", td.Members) as CodeMemberField).InitExpression = _SerializeParseAttributes(genInfo, syms); (C.GetByName("ErrorSentinels", td.Members) as CodeMemberField).InitExpression = _SerializeErrorSentinels(genInfo, syms); //(C.GetByName("NodeFlags", td.Members) as CodeMemberField).InitExpression = _SerializeNodeFlags(genInfo,syms); foreach (var code in genInfo.Xbnf.Code) { td.Members.AddRange(SlangParser.ParseMembers(code.Value, code.Line, code.Column, code.Position)); } var hasChangeType = false; var hasEvalAny = false; foreach (var prod in genInfo.Xbnf.Productions) { if (null != prod.Action) { var hasEA = false; var hasCT = false; _GenerateAction(genInfo, syms, td, prod, fast, out hasCT, out hasEA); if (hasCT) { hasChangeType = true; } if (hasEA) { hasEvalAny = true; } } } var consts = new string[syms.Count]; for (int ic = syms.Count, i = 0; i < ic; ++i) { var s = syms[i]; if ("#ERROR" == s) { s = "ErrorSymbol"; } else if ("#EOS" == s) { s = "EosSymbol"; } s = _MakeSafeName(s); s = _MakeUniqueMember(td, s); consts[i] = s; td.Members.Add(C.Field(typeof(int), s, MemberAttributes.Const | MemberAttributes.Public, C.Literal(i))); } if (hasChangeType) { var m = C.Method(C.Type(typeof(object)), "_ChangeType", MemberAttributes.Static | MemberAttributes.Private, C.Param(typeof(object), "obj"), C.Param(typeof(Type), "type")); m.Statements.Add(C.Var(typeof(TypeConverter), "typeConverter", C.Invoke(C.TypeRef(typeof(TypeDescriptor)), "GetConverter", C.ArgRef("obj")))); // if(null!=typeConverter || !typeConverter.CanConvertTo(type)) m.Statements.Add(C.If(C.Or(C.IdentEq(C.Null, C.VarRef("typeConverter")), C.Not(C.Invoke(C.VarRef("typeConverter"), "CanConvertTo", C.ArgRef("type")))), C.Return(C.Invoke(C.TypeRef(typeof(Convert)), "ChangeType", C.ArgRef("obj"), C.ArgRef("type"))) )); m.Statements.Add(C.Return(C.Invoke(C.VarRef("typeConverter"), "ConvertTo", C.ArgRef("obj"), C.ArgRef("type")))); td.Members.Add(m); } if (hasEvalAny) { var sid = C.PropRef(C.ArgRef("node"), "SymbolId"); var m = C.Method(typeof(object), "_EvaluateAny", MemberAttributes.Private | MemberAttributes.Static, C.Param(C.Type("ParseNode"), "node"), C.Param(typeof(object), "state")); for (int ic = genInfo.Xbnf.Productions.Count, i = 0; i < ic; ++i) { var p = genInfo.Xbnf.Productions[i]; if (!p.IsCollapsed && !p.IsHidden) { var sidcmp = syms.IndexOf(p.Name); var sidcf = C.FieldRef(C.TypeRef(td.Name), consts[sidcmp]); var cnd = C.If(C.Eq(sid, sidcf)); if (!p.IsTerminal) { cnd.TrueStatements.Add(C.Return(C.Invoke(C.TypeRef(td.Name), string.Concat("Evaluate", p.Name), C.ArgRef("node"), C.ArgRef("state")))); } else { cnd.TrueStatements.Add(C.Return(C.PropRef(C.ArgRef("node"), "Value"))); } m.Statements.Add(cnd); } } m.Statements.Add(C.Return(C.Null)); td.Members.Add(m); } return(result); }
static void _GenerateAction(XbnfGenerationInfo info, IList <string> syms, CodeTypeDeclaration parser, XbnfProduction prod, bool fast, out bool hasChangeType, out bool hasEvalAny) { var isStart = ReferenceEquals(prod, info.Xbnf.StartProduction); var isShared = false; hasChangeType = false; hasEvalAny = false; var hasReturn = false; var ai = prod.Attributes.IndexOf("shared"); if (-1 < ai) { var o = prod.Attributes[ai].Value; if (o is bool && (bool)o) { isShared = true; } } var type = new CodeTypeReference(typeof(object)); ai = prod.Attributes.IndexOf("type"); if (-1 < ai) { var s = prod.Attributes[ai].Value as string; if (!string.IsNullOrEmpty(s)) { //type = new CodeTypeReference(CodeDomResolver.TranslateIntrinsicType(s)); type = SlangParser.ParseType(s); } } MemberAttributes pattrs = MemberAttributes.Public | MemberAttributes.Static; MemberAttributes attrs = MemberAttributes.FamilyAndAssembly | MemberAttributes.Static; var rs = new StringBuilder(); foreach (var r in info.Cfg.FillNonTerminalRules(prod.Name)) { rs.AppendLine(r.ToString()); } if (isStart) { var ms = C.Method(type, "Evaluate", pattrs, C.Param(C.Type("ParseNode"), "node")); ms.Comments.AddRange(C.ToComments(string.Format("<summary>\r\nEvaluates a derivation of the form:\r\n{0}\r\n</summary>\r\n<remarks>\r\nThe production rules are:\r\n{1}\r\n</remarks>\r\n<param name=\"node\">The <see cref=\"ParseNode\"/> to evaluate</param>\r\n<returns>The result of the evaluation</returns>", prod.ToString("p").TrimEnd(), rs.ToString().TrimEnd()), true)); ms.Statements.Add(C.Return(C.Invoke(C.TypeRef(parser.Name), string.Concat("Evaluate", prod.Name), C.ArgRef("node"), C.Null))); parser.Members.Add(ms); ms = C.Method(type, "Evaluate", pattrs, C.Param(C.Type("ParseNode"), "node"), C.Param(C.Type(typeof(object)), "state")); ms.Comments.AddRange(C.ToComments(string.Format("<summary>\r\nEvaluates a derivation of the form:\r\n{0}\r\n</summary>\r\n<remarks>\r\nThe production rules are:\r\n{1}\r\n</remarks>\r\n<param name=\"node\">The <see cref=\"ParseNode\"/> to evaluate</param>\r\n<param name=\"state\">A user supplied state object. What it should be depends on the production's associated code block</param>\r\n<returns>The result of the evaluation</returns>", prod.ToString("p").TrimEnd(), rs.ToString().TrimEnd()), true)); ms.Statements.Add(C.Return(C.Invoke(C.TypeRef(parser.Name), string.Concat("Evaluate", prod.Name), C.ArgRef("node"), C.ArgRef("state")))); parser.Members.Add(ms); } var m = C.Method(type, string.Concat("Evaluate", prod.Name), (!isStart && isShared)?pattrs:attrs, C.Param("ParseNode", "node"), C.Param(typeof(object), "state")); m.Comments.AddRange(C.ToComments(string.Format("<summary>\r\nEvaluates a derivation of the form:\r\n{0}\r\n</summary>\r\n<remarks>\r\nThe production rules are:\r\n{1}\r\n</remarks>\r\n<param name=\"node\">The <see cref=\"ParseNode\"/> to evaluate</param>\r\n<param name=\"state\">A user supplied state object. What it should be depends on the production's associated code block</param>\r\n<returns>The result of the evaluation</returns>", prod.ToString("p").TrimEnd(), rs.ToString().TrimEnd()), true)); var stmts = SlangParser.ParseStatements(prod.Action.Value, prod.Action.Line, prod.Action.Column, prod.Action.Position); bool hasCT, hasE, hasR; _TranslateMacros(info, parser, stmts, type, out hasCT, out hasE, out hasR); if (hasCT) { hasChangeType = true; } if (hasE) { hasEvalAny = true; } if (hasR) { hasReturn = true; } if (!hasReturn) { if (!CD.CodeDomResolver.IsNullOrVoidType(type)) { stmts.Add(C.Return(C.Default(type))); } else { stmts.Add(C.Return(C.Null)); } } m.Statements.AddRange(stmts); parser.Members.Add(m); }
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); }