I have a situation where I need to create a class with a large string const. The code outside my control causes the generated CodeDom tree to be emitted to a C # source, and then later compiled as part of a larger assembly.
Unfortunately, I came across a situation where the length of this line exceeds 335440 characters in Win2K8 x64 (926240 in Win2K3 x86), the C # compiler comes out with a fatal error:
fatal error CS1647: expression is too long or too complicated to compile next to 'int'
MSDN says that CS1647 is "stack overflow in the compiler" (no pun intended!). Looking more closely, I determined that CodeDom “beautifully” wraps my const string with 80 characters. This forces the compiler to concatenate over 4,193 string fragments, which appear to be the depth of the C # compiler stack in x64 NetFx. CSC.exe must internally recursively evaluate this expression to "rehydrate" my single line.
My initial question is this: “ does anyone know about the work to change the way the code generator is generated? ” I cannot control the fact that the external system uses the C # source as an intermediate and I want this to be a constant ( rather than concatenating strings at runtime).
Alternatively, how can I formulate this expression in such a way that after a certain number of characters I can still create a constant, but it consists of several large pieces?
Full play here:
// this string breaks CSC: 335440 is Win2K8 x64 max, 926240 is Win2K3 x86 max string HugeString = new String('X', 926300); CodeDomProvider provider = CodeDomProvider.CreateProvider("C#"); CodeCompileUnit code = new CodeCompileUnit(); // namespace Foo {} CodeNamespace ns = new CodeNamespace("Foo"); code.Namespaces.Add(ns); // public class Bar {} CodeTypeDeclaration type = new CodeTypeDeclaration(); type.IsClass = true; type.Name = "Bar"; type.Attributes = MemberAttributes.Public; ns.Types.Add(type); // public const string HugeString = "XXXX..."; CodeMemberField field = new CodeMemberField(); field.Name = "HugeString"; field.Type = new CodeTypeReference(typeof(String)); field.Attributes = MemberAttributes.Public|MemberAttributes.Const; field.InitExpression = new CodePrimitiveExpression(HugeString); type.Members.Add(field); // generate class file using (TextWriter writer = File.CreateText("FooBar.cs")) { provider.GenerateCodeFromCompileUnit(code, writer, new CodeGeneratorOptions()); } // compile class file CompilerResults results = provider.CompileAssemblyFromFile(new CompilerParameters(), "FooBar.cs"); // output reults foreach (string msg in results.Output) { Console.WriteLine(msg); } // output errors foreach (CompilerError error in results.Errors) { Console.WriteLine(error); }
compiler-construction c # csc codedom
mckamey
source share