public virtual void SetRoot(OutputModelObject root) { this.root = root; }
private Template Walk(OutputModelObject outputModel, bool header) { AbstractTarget target = GetTarget(); if (target == null) { throw new NotSupportedException("Cannot generate code without a target."); } OutputModelWalker walker = new OutputModelWalker(tool, target.GetTemplates()); return walker.Walk(outputModel, header); }
public virtual Template Walk(OutputModelObject omo, bool header) { // CREATE TEMPLATE FOR THIS OUTPUT OBJECT Type cl = omo.GetType(); string templateName = cl.Name; if (templateName == null) { tool.errMgr.ToolError(ErrorType.NO_MODEL_TO_TEMPLATE_MAPPING, cl.Name); return new Template("[" + templateName + " invalid]"); } if (header) templateName += "Header"; Template st = templates.GetInstanceOf(templateName); if (st == null) { tool.errMgr.ToolError(ErrorType.CODE_GEN_TEMPLATES_INCOMPLETE, templateName); return new Template("[" + templateName + " invalid]"); } if (st.impl.FormalArguments == null) { tool.errMgr.ToolError(ErrorType.CODE_TEMPLATE_ARG_ISSUE, templateName, "<none>"); return st; } IDictionary<string, FormalArgument> formalArgs = new LinkedHashMap<string, FormalArgument>(); foreach (var argument in st.impl.FormalArguments) formalArgs[argument.Name] = argument; // PASS IN OUTPUT MODEL OBJECT TO TEMPLATE AS FIRST ARG string modelArgName = st.impl.FormalArguments[0].Name; st.Add(modelArgName, omo); // COMPUTE STs FOR EACH NESTED MODEL OBJECT MARKED WITH @ModelElement AND MAKE ST ATTRIBUTE ISet<string> usedFieldNames = new HashSet<string>(); IEnumerable<FieldInfo> fields = GetFields(cl); foreach (FieldInfo fi in fields) { ModelElementAttribute annotation = fi.GetCustomAttribute<ModelElementAttribute>(); if (annotation == null) { continue; } string fieldName = fi.Name; if (!usedFieldNames.Add(fieldName)) { tool.errMgr.ToolError(ErrorType.INTERNAL_ERROR, "Model object " + omo.GetType().Name + " has multiple fields named '" + fieldName + "'"); continue; } // Just don't set [ModelElement] fields w/o formal argument in target ST if (!formalArgs.ContainsKey(fieldName)) continue; try { object o = fi.GetValue(omo); if (o is OutputModelObject) { // SINGLE MODEL OBJECT? OutputModelObject nestedOmo = (OutputModelObject)o; Template nestedST = Walk(nestedOmo, header); //System.Console.WriteLine("set ModelElement " + fieldName + "=" + nestedST + " in " + templateName); st.Add(fieldName, nestedST); } else if (o is IDictionary) { IDictionary nestedOmoMap = (IDictionary)o; IDictionary<object, Template> m = new LinkedHashMap<object, Template>(); for (IDictionaryEnumerator enumerator = nestedOmoMap.GetEnumerator(); enumerator.MoveNext(); ) { DictionaryEntry entry = enumerator.Entry; Template nestedST = Walk((OutputModelObject)entry.Value, header); //System.Console.WriteLine("set ModelElement " + fieldName + "=" + nestedST + " in " + templateName); m[entry.Key] = nestedST; } st.Add(fieldName, m); } else if (o is IEnumerable && !(o is string)) { // LIST OF MODEL OBJECTS? IEnumerable nestedOmos = (IEnumerable)o; foreach (object nestedOmo in nestedOmos) { if (nestedOmo == null) continue; Template nestedST = Walk((OutputModelObject)nestedOmo, header); //System.Console.WriteLine("set ModelElement " + fieldName + "=" + nestedST + " in " + templateName); st.Add(fieldName, nestedST); } } else if (o != null) { tool.errMgr.ToolError(ErrorType.INTERNAL_ERROR, "not recognized nested model element: " + fieldName); } } catch (FieldAccessException) { tool.errMgr.ToolError(ErrorType.CODE_TEMPLATE_ARG_ISSUE, templateName, fieldName); } } //st.impl.Dump(); return st; }