public void TestConstCStyleArray() { // Simple set of types for an index array var vArray = new ItemCStyleArray("int[]", new ItemSimpleType("arr", "int")); vArray.Add(0, "10", true); var vIndex = new ItemSimpleType("n", "int"); ROOTClassShell mainClass = new ROOTClassShell("TestSimpleRename") { }; mainClass.Add(vIndex); mainClass.Add(vArray); var ntup = new NtupleTreeInfo() { Classes = new ROOTClassShell[] { mainClass }, ClassImplimintationFiles = new string[0] }; var userinfo = new TTreeUserInfo() { Groups = new ArrayGroup[] { new ArrayGroup() { Name = "ungrouped", Variables = new VariableInfo[] { new VariableInfo() { NETName = "n", TTreeName = "n" }, new VariableInfo() { NETName = "arr", TTreeName = "arr" } } } } }; var cg = new ClassGenerator(); var outputFile = new FileInfo("TestConstCStyleArray.cs"); cg.GenerateClasss(ntup, outputFile, "junk", new Dictionary <string, TTreeUserInfo>() { { "TestSimpleRename", userinfo } }); CopyToOutput(outputFile); /// Look through this to see if we can make sure there are no renames! Assert.IsTrue(FindInFile(outputFile, "int[] arr"), "Array Decl missing"); Assert.IsTrue(FindInFile(outputFile, "int n"), "Index decl missing"); Assert.IsTrue(FindInFile(outputFile, "[ArraySizeIndex(\"10\", IsConstantExpression = true, Index = 0)]"), "Missing array size index attribute"); }
public void TestNonIntIndex() { /// Create simple user info - but don't do anything with it! ItemSimpleType simpleIndex = new ItemSimpleType("index", "float[]"); ItemSimpleType simpleVal = new ItemSimpleType("var1", "float[]"); ROOTClassShell mainClass = new ROOTClassShell("TestNonIntIndex") { }; mainClass.Add(simpleIndex); mainClass.Add(simpleVal); var ntup = new NtupleTreeInfo() { Classes = new ROOTClassShell[] { mainClass }, ClassImplimintationFiles = new string[0] }; var userinfo = new TTreeUserInfo() { Groups = new ArrayGroup[] { new ArrayGroup() { Name = "jets", Variables = new VariableInfo[] { new VariableInfo() { NETName = "index", TTreeName = "index", IndexToGroup = "muons" } } }, new ArrayGroup() { Name = "muons", Variables = new VariableInfo[] { new VariableInfo() { NETName = "var1", TTreeName = "var1" } } } } }; var cg = new ClassGenerator(); var outputFile = new FileInfo("TestNonIntIndex.cs"); cg.GenerateClasss(ntup, outputFile, "junk", new Dictionary <string, TTreeUserInfo>() { { "TestNonIntIndex", userinfo } }); }
public void GroupWithArrayLengthSpecification() { ItemSimpleType simple1 = new ItemSimpleType("avar", "int[]"); ItemSimpleType simple2 = new ItemSimpleType("bvar", "int[]"); ROOTClassShell mainClass = new ROOTClassShell("GroupWithArrayLengthSpecification") { }; mainClass.Add(simple1); mainClass.Add(simple2); var ntup = new NtupleTreeInfo() { Classes = new ROOTClassShell[] { mainClass }, ClassImplimintationFiles = new string[0] }; var userinfo = new TTreeUserInfo() { Groups = new ArrayGroup[] { new ArrayGroup() { Name = "jets", NETNameOfVariableToUseAsArrayLength = "b", Variables = new VariableInfo[] { new VariableInfo() { NETName = "a", TTreeName = "avar" }, new VariableInfo() { NETName = "b", TTreeName = "bvar" }, } } } }; var cg = new ClassGenerator(); var outputFile = new FileInfo("GroupWithArrayLengthSpecification.cs"); cg.GenerateClasss(ntup, outputFile, "junk", new Dictionary <string, TTreeUserInfo>() { { "GroupWithArrayLengthSpecification", userinfo } }); DumpOutputFile(outputFile); /// Look through this to see if we can make sure there are no renames! Assert.IsTrue(FindInFile(outputFile, "UseAsArrayLength"), "Missing the UseAsArrayLength attribute!!"); }
public void TestCStyleArrayBadIndexName() { // Simple set of types for an index array var vArray = new ItemCStyleArray("int[]", new ItemSimpleType("arr", "int")); vArray.Add(0, "i", false); var vIndex = new ItemSimpleType("n", "int"); ROOTClassShell mainClass = new ROOTClassShell("TestSimpleRename") { }; mainClass.Add(vIndex); mainClass.Add(vArray); var ntup = new NtupleTreeInfo() { Classes = new ROOTClassShell[] { mainClass }, ClassImplimintationFiles = new string[0] }; var userinfo = new TTreeUserInfo() { Groups = new ArrayGroup[] { new ArrayGroup() { Name = "ungrouped", Variables = new VariableInfo[] { new VariableInfo() { NETName = "n", TTreeName = "n" }, new VariableInfo() { NETName = "arr", TTreeName = "arr" } } } } }; var cg = new ClassGenerator(); var outputFile = new FileInfo("TestCStyleArray.cs"); cg.GenerateClasss(ntup, outputFile, "junk", new Dictionary <string, TTreeUserInfo>() { { "TestSimpleRename", userinfo } }); }
public void TestSimpleGroupWithCustomClassName() { /// Create simple user info - but don't do anything with it! ItemSimpleType simple = new ItemSimpleType("var1", "int[]"); ROOTClassShell mainClass = new ROOTClassShell("TestSimpleGroupAndRename") { }; mainClass.Add(simple); var ntup = new NtupleTreeInfo() { Classes = new ROOTClassShell[] { mainClass }, ClassImplimintationFiles = new string[0] }; var userinfo = new TTreeUserInfo() { Groups = new ArrayGroup[] { new ArrayGroup() { Name = "jets", ClassName = "Jet", Variables = new VariableInfo[] { new VariableInfo() { NETName = "myvar", TTreeName = "var1" } } } } }; var cg = new ClassGenerator(); var outputFile = new FileInfo("TestSimpleGroupAndRename.cs"); cg.GenerateClasss(ntup, outputFile, "junk", new Dictionary <string, TTreeUserInfo>() { { "TestSimpleGroupAndRename", userinfo } }); DumpOutputFile(outputFile); /// Look through this to see if we can make sure there are no renames! Assert.IsTrue(FindInFile(outputFile, "RenameVariable(\"var1\")"), "Rename missing!"); Assert.IsTrue(FindInFile(outputFile, "TTreeVariableGrouping"), "Missing TTreeVariableGrouping"); Assert.IsTrue(FindInFile(outputFile, "jets"), "missing a reference to jets"); Assert.IsTrue(FindInFile(outputFile, "int myvar"), "myvar missing"); Assert.IsTrue(FindInFile(outputFile, "int[] var1"), "val1 missing"); Assert.IsFalse(FindInFile(outputFile, "ungrouped"), "group found"); Assert.IsFalse(FindInFile(outputFile, "TestSimpleGroupAndRenamejets"), "Found the non-class name default class name"); Assert.IsTrue(FindInFile(outputFile, "Jet"), "Did not find the Jet custom class name"); }
/// <summary> /// Fill in some defaults for later user! /// </summary> /// <param name="classSpec"></param> /// <param name="userInfo"></param> /// <returns></returns> private IDictionary <string, TTreeUserInfo> FillInDefaults(NtupleTreeInfo classSpec, IDictionary <string, TTreeUserInfo> userInfo) { if (userInfo == null) { return(null); } Dictionary <string, TTreeUserInfo> result = new Dictionary <string, TTreeUserInfo>(); foreach (var c in classSpec.Classes) { if (userInfo.ContainsKey(c.Name)) { result[c.Name] = FillInDefaults(c, userInfo[c.Name]); } } return(result); }
public void TestDuplicateClassNames() { var vIndex = new ItemSimpleType("n", "int"); ROOTClassShell mainClass = new ROOTClassShell("TestSimpleRename") { }; mainClass.Add(vIndex); ROOTClassShell mainClass1 = new ROOTClassShell("TestSimpleRename") { }; mainClass1.Add(vIndex); var ntup = new NtupleTreeInfo() { Classes = new ROOTClassShell[] { mainClass, mainClass1 }, ClassImplimintationFiles = new string[0] }; var userinfo = new TTreeUserInfo() { Groups = new ArrayGroup[] { new ArrayGroup() { Name = "ungrouped", Variables = new VariableInfo[] { new VariableInfo() { NETName = "n", TTreeName = "n" }, } } } }; var cg = new ClassGenerator(); var outputFile = new FileInfo("TestDuplicateClassNames.cs"); cg.GenerateClasss(ntup, outputFile, "junk", new Dictionary <string, TTreeUserInfo>() { { "TestDuplicateClassNames", userinfo } }); }
public void TestColonsInVarName() { ItemSimpleType simple = new ItemSimpleType("dude::fork", "int[]"); ROOTClassShell mainClass = new ROOTClassShell("TestSimpleGroupAndRename") { }; mainClass.Add(simple); var ntup = new NtupleTreeInfo() { Classes = new ROOTClassShell[] { mainClass }, ClassImplimintationFiles = new string[0] }; var userinfo = new TTreeUserInfo() { Groups = new ArrayGroup[] { new ArrayGroup() { Name = "jets", Variables = new VariableInfo[] { new VariableInfo() { NETName = "dude::fork", TTreeName = "dude::fork" } } } } }; var cg = new ClassGenerator(); var outputFile = new FileInfo("TestSimpleGroupAndRename.cs"); cg.GenerateClasss(ntup, outputFile, "junk", new Dictionary <string, TTreeUserInfo>() { { "TestSimpleGroupAndRename", userinfo } }); DumpOutputFile(outputFile); /// Look through this to see if we can make sure there are no renames! Assert.IsFalse(FindInFile(outputFile, "dude::fork"), "Saw the double colon!!"); Assert.IsTrue(FindInFile(outputFile, "dude__fork"), "Missing the variable!!"); }
public void TestNoGroups() { /// Create simple user info - but don't do anything with it! ItemSimpleType simple = new ItemSimpleType("var1", "int[]"); Assert.IsFalse(simple.NotAPointer, "not a pointer"); ROOTClassShell mainClass = new ROOTClassShell("TestSimpleRename") { }; mainClass.Add(simple); var ntup = new NtupleTreeInfo() { Classes = new ROOTClassShell[] { mainClass }, ClassImplimintationFiles = new string[0] }; var userinfo = new TTreeUserInfo() { Groups = new ArrayGroup[] { new ArrayGroup() { Name = "ungrouped", Variables = new VariableInfo[] { new VariableInfo() { NETName = "var1", TTreeName = "var1" } } } } }; var cg = new ClassGenerator(); var outputFile = new FileInfo("TestNoGroups.cs"); cg.GenerateClasss(ntup, outputFile, "junk", new Dictionary <string, TTreeUserInfo>() { { "TestSimpleRename", userinfo } }); /// Look through this to see if we can make sure there are no renames! Assert.IsFalse(FindInFile(outputFile, "RenameVariable"), "We saw a rename!"); Assert.IsFalse(FindInFile(outputFile, "ungrouped"), "group found"); }
public void TestCharactersInClassName() { ItemSimpleType simple = new ItemSimpleType("fork", "int"); ROOTClassShell mainClass = new ROOTClassShell("##Shapes") { }; mainClass.Add(simple); var ntup = new NtupleTreeInfo() { Classes = new ROOTClassShell[] { mainClass }, ClassImplimintationFiles = new string[0] }; var userinfo = new TTreeUserInfo() { Groups = new ArrayGroup[] { new ArrayGroup() { Name = "jets", Variables = new VariableInfo[] { new VariableInfo() { NETName = "fork", TTreeName = "fork" } } } } }; var cg = new ClassGenerator(); var outputFile = new FileInfo("TestCharactersInClassName.cs"); cg.GenerateClasss(ntup, outputFile, "junk", new Dictionary <string, TTreeUserInfo>() { { "TestSimpleGroupAndRename", userinfo } }); DumpOutputFile(outputFile); Assert.AreEqual(3, CountInFile(outputFile, "##Shapes"), "Missing reference ot the shapes object"); }
/// <summary> /// Command line interface to parse all the TTree's in a /// TFile and make the XML file that specifies their layout /// for later object generation. /// </summary> /// <param name="args"></param> static void Main(string[] args) { /// /// Parse the inputs /// List <FileInfo> rootFiles = new List <FileInfo>(); List <FileInfo> libraries = new List <FileInfo>(); string specialFile = ""; FileInfo outputFile = null; DirectoryInfo outputDir = null; bool doExistanceCheck = true; foreach (var arg in args) { if (arg == "-o") { specialFile = "o"; doExistanceCheck = false; continue; } if (arg == "-d") { specialFile = "outD"; doExistanceCheck = false; continue; } if (specialFile == "outD") { DirectoryInfo inf = new DirectoryInfo(arg); if (!inf.Exists) { inf.Create(); } outputDir = inf; specialFile = ""; continue; } FileInfo f = new FileInfo(arg); if (doExistanceCheck && !f.Exists) { SimpleLogging.Log("Could not file file {0}", f.FullName); return; } doExistanceCheck = true; if (specialFile.Length > 0) { if (specialFile == "o") { outputFile = f; } specialFile = ""; } else if (f.Extension == ".root" || f.Name.Contains(".root.")) { rootFiles.Add(f); } else { libraries.Add(f); } } if (rootFiles.Count == 0) { SimpleLogging.Log("no input root files to scan!"); return; } // Output directory for all our files is where the root file is located if we don't have anything better! if (outputDir == null) { outputDir = rootFiles[0].Directory; } if (outputFile == null) { outputFile = new FileInfo(string.Format("{0}\\{1}", outputDir.FullName, Path.ChangeExtension(rootFiles[0].Name, "ntupom"))); } /// /// Make sure to write everything to a log file for the next step! /// using (var logFile = File.CreateText(Path.ChangeExtension(outputFile.FullName, ".log"))) { SimpleLogging.AddStream(logFile); /// /// Next, load up all the libraries /// var gSystem = ROOTNET.NTSystem.gSystem; foreach (var lib in libraries) { gSystem.Load(lib.FullName); } /// /// Next, we need to find all the classes that are in those libraries, /// and then figure out where the location of the classes is. /// var loadedNames = (from s in libraries select Path.GetFileNameWithoutExtension(s.Name)).ToArray(); var usedClasses = from cls in ROOTNET.NTROOT.gROOT.ListOfClasses.Cast <ROOTNET.Interface.NTClass>() let shared = cls.SharedLibs where shared != null let name = Path.GetFileNameWithoutExtension(shared.Split().First()) where loadedNames.Contains(name) select cls; var sourcefiles = from cls in usedClasses select cls.GetImplFileName(); /// /// And now process the root files! /// var converter = new TTreeParser.ParseTFile { ProxyGenerationLocation = outputDir }; var rootClassList = from f in rootFiles from c in converter.ParseFile(f) select c; var allClasses = rootClassList.ToArray(); if (allClasses.Length == 0) { SimpleLogging.Log("No classes were found in the input files!"); return; } /// /// Write out the output xml file now /// NtupleTreeInfo results = new NtupleTreeInfo() { Classes = allClasses, ClassImplimintationFiles = sourcefiles.ToArray() }; XmlSerializer xmlout = new XmlSerializer(typeof(NtupleTreeInfo)); using (var output = outputFile.CreateText()) { xmlout.Serialize(output, results); } } }
/// <summary> /// After reading in, it is nice to fill in some defaults if the user didn't first. That makes it a lot easier to /// write code for the output of this - so it isn't filled with lots of special cases. /// </summary> /// <param name="classSpec"></param> private void FillInDefaults(NtupleTreeInfo classSpec) { }
/// <summary> /// Generate the classes given the input classes /// </summary> /// <param name="classSpec"></param> /// <param name="outputCSFile"></param> /// <param name="namespaceName"></param> public void GenerateClasss(NtupleTreeInfo classSpec, FileInfo outputCSFile, string namespaceName, IDictionary <string, TTreeUserInfo> userInfo = null) { /// /// Parameter checks /// if (outputCSFile == null) { throw new ArgumentNullException("outputCSFile"); } if (string.IsNullOrWhiteSpace(namespaceName)) { throw new ArgumentNullException("namespaceName"); } bool isbad = namespaceName.Any(c => !char.IsLetterOrDigit(c)); if (isbad || !char.IsLetter(namespaceName[0])) { throw new ArgumentException("Namespace is not a legal C++ name"); } if (classSpec == null) { throw new ArgumentNullException("classSpec"); } if (classSpec.Classes == null) { throw new ArgumentNullException("classSpec.Classes"); } var classByName = (from c in classSpec.Classes group c by c.Name into g where g.Count() > 1 select g.Key).ToArray(); if (classByName.Length > 0) { var msg = new StringBuilder(); msg.AppendFormat("The following classes have the same name:"); foreach (var cname in classByName) { msg.AppendFormat(" {0}", cname); } throw new InvalidDataException(msg.ToString()); } foreach (var c in classSpec.ClassImplimintationFiles) { if (c == null) { throw new ArgumentNullException("Class support files can't be null"); } if (!File.Exists(c)) { throw new ArgumentException("Can't fine class support file '" + c + "'."); } } // // Fill in some defaults // userInfo = FillInDefaults(classSpec, userInfo); // // Do some quick checks for consistency // foreach (var cls in classSpec.Classes) { // Check that the index variable for all c-style arrays is "good". var CStyleArrays = from item in cls.Items where item is ItemCStyleArray let cSpec = item as ItemCStyleArray from cindex in cSpec.Indicies where !cindex.indexConst && cindex.indexBoundName != "implied" select cindex.indexBoundName; var IndexTypes = (from indexer in CStyleArrays let match = (from item in cls.Items where item.Name == indexer select item).FirstOrDefault() select Tuple.Create(indexer, match)).ToArray(); var missingIndexTypes = (from indexer in IndexTypes where indexer.Item2 == null select indexer).ToArray(); if (missingIndexTypes.Length > 0) { var msg = new StringBuilder(); msg.Append("C Style arrays used index variables that I can't find in the class: "); foreach (var vname in missingIndexTypes) { msg.Append(vname + " "); } throw new InvalidOperationException(msg.ToString()); } var nonIntIndexTypes = (from index in IndexTypes where index.Item2.ItemType != "int" select index).ToArray(); if (nonIntIndexTypes.Length > 0) { var msg = new StringBuilder(); msg.Append("C Style arrays used index variables that are not integers: "); foreach (var vname in nonIntIndexTypes) { msg.AppendFormat("{0}({1}) ", vname.Item2.Name, vname.Item2.ItemType); } throw new InvalidOperationException(msg.ToString()); } } // // Now, start generating the output classes! // using (var output = outputCSFile.CreateText()) { /// /// Write out the header and using clauses /// output.WriteLine("//"); output.WriteLine("// Automatically Generated File - do not modify!"); output.WriteLine("// Generated on {0} by TTreeClassGenerator::ClassGenerator", DateTime.Now); output.WriteLine("// Translated ntuple classes"); foreach (var cls in classSpec.Classes) { output.WriteLine("// - ntuple {0}", cls.Name.FixupClassName()); } output.WriteLine("//"); output.WriteLine(); output.WriteLine("using System.IO;"); output.WriteLine("using LINQToTTreeLib;"); output.WriteLine("using LinqToTTreeInterfacesLib;"); output.WriteLine("using LINQToTTreeLib.CodeAttributes;"); output.WriteLine("using System.Linq.Expressions;"); output.WriteLine(); output.WriteLine("namespace {0} {{", namespaceName); /// /// Now, write something out for each class /// foreach (var cls in classSpec.Classes) { try { /// /// Write out the info class that contains everything needed to process this. /// We could use attribute programming here, but that takes more code at the other /// end, so until there is a real reason, we'll do it this way. /// /// This is a kludge until we do more work to fix things with attributes, etc. /// void writeOutExtra() { if (cls.IsTopLevelClass) { output.WriteLine(" public static string[] _gObjectFiles= {"); foreach (var item in classSpec.ClassImplimintationFiles) { output.WriteLine(" @\"" + item + "\","); } output.WriteLine(" };"); output.WriteLine(" public static string[] _gCINTLines= {"); if (cls.CINTExtraInfo != null) { foreach (var item in cls.CINTExtraInfo) { output.WriteLine(" @\"" + item + "\","); } } output.WriteLine(" };"); output.WriteLine(" public static string[] _gClassesToDeclare= {"); if (cls.ClassesToGenerate != null) { foreach (var item in cls.ClassesToGenerate) { output.WriteLine(" @\"" + item.classSpec + "\","); } } output.WriteLine(" };"); output.WriteLine(" public static string[] _gClassesToDeclareIncludes = {"); if (cls.ClassesToGenerate != null) { foreach (var item in cls.ClassesToGenerate) { output.WriteLine(" @\"" + item.includeFiles + "\","); } } output.WriteLine(" };"); } } /// /// First, if there is a translated object model, write it out. /// var rawClassName = cls.Name.FixupClassName(); if (userInfo != null) { if (userInfo.ContainsKey(cls.Name)) { if (RequiresTranslation(userInfo[cls.Name])) { rawClassName = rawClassName + "TranslatedTo"; var varTypes = FindVariableTypes(cls.Items); WriteTranslatedObjectStructure(output, userInfo[cls.Name], cls.Name, rawClassName, varTypes, writeOutExtra); output.WriteLine(); output.WriteLine(); } } } // // Write out the class header. // If this is a generated class, then we need an attribute to mark it. // if (cls.IsTClonesArrayClass) { output.WriteLine(" [TClonesArrayImpliedClass]"); } if (!cls.IsTopLevelClass) { output.WriteLine(" public partial class {0}", rawClassName); output.WriteLine(" {"); } else { output.WriteLine(" public partial class {0} : IExpressionHolder", rawClassName); output.WriteLine(" {"); output.WriteLine(" public Expression HeldExpression {get; private set;}"); output.WriteLine(" public {0} (Expression expr) {{ HeldExpression = expr; }}", rawClassName); } output.WriteLine(); /// /// These fields will never be set or accessed - so we turn off some warnings the compiler will generate. /// They are dummies so that intellisense works and we can do the translation properly. /// output.WriteLine("#pragma warning disable 0649"); foreach (var item in cls.Items) { WriteItem(item, output); } output.WriteLine("#pragma warning restore 0649"); writeOutExtra(); output.WriteLine(" }"); // End of the class output.WriteLine(); output.WriteLine(); /// /// Next, write out the queriable classes so we can actually do the queries /// against the trees! /// if (cls.IsTopLevelClass) { output.WriteLine(" /// Helper classes"); output.WriteLine(" public static class Queryable{0}", cls.Name.FixupClassName()); output.WriteLine(" {"); output.WriteLine(" /// Create a LINQ to TTree interface for a file and optional tree name"); output.WriteLine(" public static QueriableTTree<{0}> CreateQueriable (this FileInfo rootFile, string treeName = \"{1}\")", cls.Name.FixupClassName(), cls.Name); output.WriteLine(" {"); output.WriteLine(" return new QueriableTTree<{0}>(rootFile, treeName);", cls.Name.FixupClassName()); output.WriteLine(" }"); output.WriteLine(" /// Create a LINQ to TTree interface for a list of files and optional tree name"); output.WriteLine(" public static QueriableTTree<{0}> CreateQueriable (this FileInfo[] rootFiles, string treeName = \"{1}\")", cls.Name.FixupClassName(), cls.Name); output.WriteLine(" {"); output.WriteLine(" return new QueriableTTree<{0}>(rootFiles, treeName);", cls.Name.FixupClassName()); output.WriteLine(" }"); output.WriteLine(" /// Create a LINQ to TTree interface for a list of URLs and optional tree name"); output.WriteLine(" public static QueriableTTree<{0}> CreateQueriable (this System.Uri[] rootURLs, string treeName = \"{1}\")", cls.Name.FixupClassName(), cls.Name); output.WriteLine(" {"); output.WriteLine(" return new QueriableTTree<{0}>(rootURLs, treeName);", cls.Name.FixupClassName()); output.WriteLine(" }"); output.WriteLine(" }"); } } catch (Exception e) { var errorMessage = new StringBuilder(); errorMessage.AppendFormat("Error while processing class '{0}", cls.Name); var ex = e; while (ex != null) { errorMessage.AppendFormat(": {0}", e.Message); ex = e.InnerException; } // Kill off the output file! output.Close(); outputCSFile.Delete(); // Propagate the error upwards. throw new Exception(errorMessage.ToString(), e); } } /// /// Done! /// output.WriteLine("}"); // For the namespace output.Close(); } }
public void TestRenamedIndex() { /// Create simple user info - but don't do anything with it! ItemSimpleType simpleIndex = new ItemSimpleType("index", "int[]"); ItemSimpleType simpleVal = new ItemSimpleType("var1", "float[]"); ROOTClassShell mainClass = new ROOTClassShell("TestRenamedIndex") { }; mainClass.Add(simpleIndex); mainClass.Add(simpleVal); var ntup = new NtupleTreeInfo() { Classes = new ROOTClassShell[] { mainClass }, ClassImplimintationFiles = new string[0] }; var userinfo = new TTreeUserInfo() { Groups = new ArrayGroup[] { new ArrayGroup() { Name = "jets", Variables = new VariableInfo[] { new VariableInfo() { NETName = "muons", TTreeName = "index", IndexToGroup = "muons" } } }, new ArrayGroup() { Name = "muons", Variables = new VariableInfo[] { new VariableInfo() { NETName = "var1", TTreeName = "var1" } } } } }; var cg = new ClassGenerator(); var outputFile = new FileInfo("TestRenamedIndex.cs"); cg.GenerateClasss(ntup, outputFile, "junk", new Dictionary <string, TTreeUserInfo>() { { "TestRenamedIndex", userinfo } }); DumpOutputFile(outputFile); /// Look through this to see if we can make sure there are no renames! Assert.IsTrue(FindInFile(outputFile, "TTreeVariableGrouping"), "Missing TTreeVariableGrouping"); Assert.IsTrue(FindInFile(outputFile, "jets"), "missing a reference to jets"); Assert.IsTrue(FindInFile(outputFile, "muons"), "missing a reference to jets"); Assert.IsTrue(FindInFile(outputFile, "IndexToOtherObjectArray(typeof("), "Missing IndexToOtherObject"); Assert.IsTrue(FindInFile(outputFile, "TestRenamedIndexmuons muons"), "Muon reference is imporper"); Assert.IsTrue(FindInFile(outputFile, "float var1"), "var1 missing"); Assert.IsFalse(FindInFile(outputFile, "ungrouped"), "group found"); }
public void GenerateClassFromClasses( ClassGenerator target, int outputChoice, int numExtraFiles, int numExtraFilesToCreate, int extraFileIndexNull, string nameSName, int NumObjectCollection) { if (numExtraFiles < 0 || numExtraFilesToCreate < 0 || extraFileIndexNull < 0 || outputChoice < 0 || NumObjectCollection < 0) { return; } /// /// Kill off the directory we might have left behind from a previous run, and create a new one. /// DirectoryInfo testDir = new DirectoryInfo(".\\GenerateClassFromClasses"); if (testDir.Exists) { testDir.Delete(true); } testDir.Create(); /// /// Setup the input stuff so Pex can play /// FileInfo outputCSFile; if (outputChoice == 1) { outputCSFile = new FileInfo(testDir.FullName + "\\output.cs"); } else { outputCSFile = null; } ROOTClassShell[] objCollect = null; if (NumObjectCollection > 0) { List <ROOTClassShell> objs = new List <ROOTClassShell>(); for (int i = 0; i < NumObjectCollection; i++) { ROOTClassShell rcs = new ROOTClassShell(); rcs.Name = "dude_" + i.ToString(); for (int j = 0; j < i; j++) { IClassItem item = null; switch (NumObjectCollection % 4) { case 0: item = null; break; case 1: var itm = new ItemSimpleType() { ItemType = "int" }; item = itm; break; case 2: var itmv = new ItemVector() { ItemType = "int[]" }; item = itmv; break; case 3: var itmr = new ItemROOTClass() { ItemType = "TLorentzVector" }; item = itmr; break; } if (item != null) { item.Name = "item_" + j.ToString(); } rcs.Items.Add(item); } objs.Add(rcs); } objCollect = objs.ToArray(); } /// /// Create the final object, and any extra files needed! /// NtupleTreeInfo info = new NtupleTreeInfo() { Classes = objCollect }; info.ClassImplimintationFiles = (from c in Enumerable.Range(0, numExtraFiles) let f = new FileInfo(testDir.FullName + "\\GenerateClassFromClasses_extra_" + c.ToString() + ".cpp") select f.FullName ).ToArray(); int maxFilesToCreate = numExtraFilesToCreate > numExtraFiles ? numExtraFiles : numExtraFilesToCreate; for (int i = 0; i < maxFilesToCreate; i++) { using (var w = File.CreateText(info.ClassImplimintationFiles[i])) { w.WriteLine(); w.Close(); } } if (extraFileIndexNull < numExtraFiles) { info.ClassImplimintationFiles[extraFileIndexNull] = null; } /// /// Ok, do the investigation /// target.GenerateClasss(info, outputCSFile, nameSName); Assert.IsFalse(info.ClassImplimintationFiles.Any(c => c == null), "no null implementation files allowed"); Assert.IsFalse(info.ClassImplimintationFiles.Any(c => !File.Exists(c)), "all implimntation files must exist"); /// Check that all the ntuple proxy guys and the temp file guys appear in the file foreach (var item in info.ClassImplimintationFiles) { Assert.IsTrue(FindInFile(outputCSFile, item), "coul dnot find impl file '" + item + "'"); } }