/// <summary> /// Builds the new and the existing classes' ClassCodeElements, evaluates all changes and returns a list of them. /// </summary> /// <param name="go">Go.</param> public List <ClassMemberCompareElement> Compare(GameObject go) { CodeGeneratorResult result = BuildClasses(); if (result.Success) { if (!existingClass.IsEmpty()) { List <ClassMemberCompareElement> comparisonResult = CodeElementUtils.CompareClasses(existingClass, newClass, config.IgnoreExistingCode, config.KeepObsoleteMembers); // only Get, Set and Is methods of the existing class are analysed by reflection so remove all // other methods that are provided by default comparisonResult.RemoveAll((element) => element.Member == "Awake" || element.Member == "InitialiseEventManager"); if (builder.allTransitionsHash != existingAllTransitionsHash) { comparisonResult.Add(new ClassMemberCompareElement(ClassMemberCompareElement.Result.New, "", "Transition definition changes", "", "Transition changes", "")); } string message = ""; comparisonResult.ForEach((s) => message += s + "\n"); Logger.Debug("Comparison between new and existing class reveals " + comparisonResult.Count + " changes: " + message); return(comparisonResult); } } return(new List <ClassMemberCompareElement> ()); }
/// <summary> /// Initialises templateEngine and builds newClass and existingClass. /// </summary> /// <returns>The classes.</returns> CodeGeneratorResult BuildClasses() { TemplateLookup templateLookup = new TemplateLookup(config); CodeGeneratorResult result = templateLookup.GetPathToTemplate(className); if (result.Success) { result = templateEngine.Prepare(templateLookup.TemplateConfig); if (result.NoSuccess) { return(result); } newClass = builder.Build(); if (newClass.IsEmpty()) { return(result.SetError("No Input", "The input seems to be invalid. Check that there are any states or parameter to process.")); } Logger.Debug("New: " + newClass); if (!existingClassBuilder.HasType()) { Logger.Info("Generating source for " + className + " the very first time"); } try { existingClassBuilder.MethodBinding = BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.NonPublic; existingClassBuilder.MethodInfoFilter = (MethodInfo mi) => mi.Name.StartsWith("Is") || mi.Name.StartsWith("Set") || mi.Name.StartsWith("Get") || mi.Name == "IdToName" || mi.Name == "Update" || mi.Name == "FixedUpdate"; existingClass = existingClassBuilder.Build(); // little bit dirty hack: we don't want special methods like Update to participate in the regular // workflow i.e. mark as obsolete to be regenerated once with code throwing NotImplementedException. // So if settings have changed, mark them as obsolete to force their removal List <GenericMethodCodeElement> updateMethods = existingClass.Methods.FindAll( (GenericMethodCodeElement m) => m.Name == "Update" || m.Name == "FixedUpdate"); updateMethods.ForEach((GenericMethodCodeElement m) => m.Obsolete = true); } catch (System.Exception ex) { Logger.Warning(ex.Message + "\n" + ex.StackTrace); result.SetError("Error", "Oops. An unexpected error occurred. Details" + ex.Message + "\n" + ex.StackTrace); } } return(result); }