public void TestCode() { var codeFile = new CodeDocument {TabCharacter = " "}; codeFile.Namespace("Test") .Class("public", "TestClass", "") ._() ._("private string _value;") ._() .Function("public", "TestClass", "string value") ._("_value = value;") .End() ._() .Function("public void ", "TestMethod", "") ._("_value = 5;") .End() ._() ._() .Interface("public", "TestInterface", "") ._("void TestMethod();") .End() .End() .End(); Debug.WriteLine(codeFile.ToString()); Assert.IsTrue(true); }
public void TestStateCodeGeneration() { ICodeBlock codeBlock = new CodeDocument(0); mButtonInButtonList.CurrentState = "InvalidState"; StateCodeGenerator.WriteSetStateOnNamedObject(mButtonInButtonList, codeBlock); string result = codeBlock.ToString(); if (result.Contains(mButtonInButtonList.CurrentState)) { throw new Exception("Code generation for NamedObjects is generating state setting code when states don't really exist"); } // Make sure generation doesn't mess up on a entity with a "" base (instead of null) StateCodeGenerator scg = new StateCodeGenerator(); EntitySave entitySave = new EntitySave(); entitySave.States.Add(new StateSave()); entitySave.BaseEntity = ""; scg.GenerateFields(codeBlock, entitySave); }
internal static void GenerateUsings(StringBuilder stringBuilder, IElement saveObject) { if (stringBuilder.Contains("// Generated Usings")) { ICodeBlock usings = new CodeDocument(); UsingsCodeGenerator.GenerateUsingStatements(usings, saveObject); int startOfUsingSection = GetIndexAfter("// Generated Usings", stringBuilder); stringBuilder.Insert(startOfUsingSection, usings.ToString()); } }
public static void GenerateCode(IElement element) { if (element == null) { throw new ArgumentNullException("element"); } string template; if (element is ScreenSave) { template = mScreenTemplateGeneratedCode; } else { template = mEntityTemplateGeneratedCode; } // Since anything can modify an enumeration value we want to make sure that // it's proper before generating code for it: // If enumeration values don't work property let's just print some output and carry on try { element.FixEnumerationValues(); } catch (Exception e) { PluginManager.ReceiveError("Error fixing enumerations for " + element + ": " + e.ToString()); } // Do this before doing anything else since // these reusable entire file RFS's are used // in other code. RefreshReusableEntireFileRfses(element); EventCodeGenerator.GenerateEventGeneratedFile(element); if (element.Events.Count != 0) { var sharedCodeFullFileName = EventResponseSave.GetSharedCodeFullFileName(element, FileManager.GetDirectory(ProjectManager.GlueProjectFileName)); EventCodeGenerator.CreateEmptyCodeIfNecessary(element, sharedCodeFullFileName, false); } EventCodeGenerator.AddStubsForCustomEvents(element); CreateGeneratedFileIfNecessary(element); StringBuilder stringBuilder = new StringBuilder(template); foreach (PluginManager pluginManager in PluginManager.GetInstances()) { CodeGeneratorPluginMethods.CallCodeGenerationStart(pluginManager, element); } if (ContentLoadWriter.SuppressGlobalContentDictionaryRefresh == false) { ReferencedFileSaveCodeGenerator.RefreshGlobalContentDictionary(); } if (ReferencedFileSaveCodeGenerator.GlobalContentFilesDictionary == null) { throw new Exception("Global content files dictionary should not be null"); } string objectName = FileManager.RemovePath(element.Name); string projectNamespace = ProjectManager.ProjectNamespace; if (element is EntitySave) { string directory = FileManager.MakeRelative(FileManager.GetDirectory(element.Name)); if (directory.ToLower() != "Entities/".ToLower()) { string relativeDirectory = FileManager.MakeRelative(directory); relativeDirectory = relativeDirectory.Substring(0, relativeDirectory.Length - 1); relativeDirectory = relativeDirectory.Replace('/', '.'); projectNamespace += "." + relativeDirectory; } } else if (element is ScreenSave) { projectNamespace += ".Screens"; } string contentManagerName = element.UseGlobalContent ? "\"Global\"" : null; ScreenSave asScreenSave = element as ScreenSave; if (asScreenSave != null && !string.IsNullOrEmpty(asScreenSave.ContentManagerMethod)) { contentManagerName = asScreenSave.ContentManagerMethod; } var whatToInheritFrom = GetInheritance(element); CodeWriter.SetClassNameAndNamespace( projectNamespace, objectName, stringBuilder, !string.IsNullOrEmpty(contentManagerName), contentManagerName, whatToInheritFrom ); #region Make Activity, Initialize, PostInitalize, and Destroy "override" if necessary if ( element.InheritsFromElement()) { if (stringBuilder.Contains("virtual void Initialize")) { stringBuilder.Replace("virtual void Initialize", "override void Initialize"); } if (stringBuilder.Contains("virtual void Activity")) { stringBuilder.Replace("virtual void Activity", "override void Activity"); } if (stringBuilder.Contains("virtual void Destroy")) { stringBuilder.Replace("virtual void Destroy", "override void Destroy"); } } #endregion try { CodeWriter.GenerateUsings(stringBuilder, element); } catch (Exception e) { string stackTrace = e.StackTrace; throw new Exception("Error trying to generate using statements for " + element + "\n\n" + stackTrace, e); } #region Generate Fields ICodeBlock fieldsSection = CodeWriter.GenerateFields(element); int startOfFieldsSection = CodeWriter.GetIndexAfter("// Generated Fields", stringBuilder); stringBuilder.Insert(startOfFieldsSection, fieldsSection.ToString()); #endregion #region Generate Initialize ICodeBlock initializeSection = CodeWriter.GenerateInitialize(element); int startOfInitializeSection = CodeWriter.GetIndexAfter("// Generated Initialize", stringBuilder); stringBuilder.Insert(startOfInitializeSection, initializeSection.ToString()); #endregion #region Generate AddToManagers int startOfAddToManagers = CodeWriter.GetIndexAfter("// Generated AddToManagers", stringBuilder); ICodeBlock addToManagersSection = CodeWriter.GenerateAddToManagers(element); stringBuilder.Insert(startOfAddToManagers, addToManagersSection.ToString()); #endregion #region GenerateActivity ICodeBlock activityBlock = new CodeDocument(3); ICodeBlock currentBlock = activityBlock; currentBlock = CodeWriter.GenerateActivity(currentBlock, element); currentBlock = CodeWriter.GenerateAfterActivity(currentBlock, element); int startOfActivity = CodeWriter.GetIndexAfter("// Generated Activity", stringBuilder); stringBuilder.Insert(startOfActivity, activityBlock.ToString()); #endregion #region Generate Destroy ICodeBlock destroySection = CodeWriter.GenerateDestroy(element); int startOfDestroySection = CodeWriter.GetIndexAfter("// Generated Destroy", stringBuilder); stringBuilder.Insert(startOfDestroySection, destroySection.ToString()); #endregion #region Generate Methods ICodeBlock methodsSection = new CodeDocument(2); CodeWriter.GenerateMethods(methodsSection, element); int startOfMethodsSection = CodeWriter.GetIndexAfter("// Generated Methods", stringBuilder); stringBuilder.Insert(startOfMethodsSection, methodsSection.ToString()); #endregion #region Extra Classes CodeBlockBase codeBlock = new CodeBlockBase(null); foreach (var codeGenerator in CodeGenerators) { codeGenerator.GenerateAdditionalClasses(codeBlock, element); } string extraClasses = codeBlock.ToString(); if (!string.IsNullOrEmpty(extraClasses)) { const string extraClassesComment = "// Extra classes"; int indexToReplace = stringBuilder.LastIndexOf(extraClassesComment); stringBuilder.Remove(indexToReplace, extraClassesComment.Length); stringBuilder.Insert(indexToReplace, extraClasses); } #endregion string generatedCodeFileName = element.Name + ".Generated.cs"; CodeWriter.SaveFileContents(stringBuilder.ToString(), FileManager.RelativeDirectory + generatedCodeFileName, true); #region Extra stuff if it's a ScreenSave if (element is ScreenSave) { bool inherits = !string.IsNullOrEmpty(element.BaseElement) && element.BaseElement != "<NONE>"; if (inherits) { #region Set the inheritance to the proper class string fileContents; string nameWithoutPath = FileManager.RemovePath(element.Name); fileContents = FileManager.FromFileText(FileManager.RelativeDirectory + element.Name + ".Generated.cs"); #endregion #region Replace the ContentManagerName contentManagerName = (element as ScreenSave).ContentManagerForCodeGeneration; if (fileContents.Contains("base(" + contentManagerName + ")")) { // use the lower-case contentManagerName since that's the argument that's given to // the base class' constructor. fileContents = fileContents.Replace("base(" + contentManagerName + ")", "base()"); } #endregion EliminateCall("\tInitialize();", ref fileContents); EliminateCall(" Initialize();", ref fileContents); CodeWriter.SaveFileContents(fileContents, FileManager.RelativeDirectory + element.Name + ".Generated.cs", true); } } #endregion #region Extra stuff if it's an EntitySave if (element is EntitySave) { EntitySave entitySave = element as EntitySave; string fileContents = stringBuilder.ToString(); string fileName = FileManager.RelativeDirectory + element.Name + ".Generated.cs"; bool shouldSave = false; #region Ok, the code is generated, but we may still need to give it a base class bool inherits; EntitySave rootEntitySave; List<string> inheritanceList = InheritanceCodeWriter.Self.GetInheritanceList(element, entitySave, out inherits, out rootEntitySave); InheritanceCodeWriter.Self.RemoveCallsForInheritance(entitySave, inherits, rootEntitySave, ref fileContents, ref shouldSave); #endregion #region If this thing is created by other entities, then we should make it IPoolable if (entitySave.CreatedByOtherEntities) { FactoryCodeGenerator.UpdateFactoryClass(entitySave); } #endregion #region If this uses global content, then make it use global content regardless of what is passed in if (entitySave.UseGlobalContent) { fileContents = fileContents.Replace("ContentManagerName = contentManagerName;", "ContentManagerName = FlatRedBall.FlatRedBallServices.GlobalContentManager;"); shouldSave = true; } #endregion #region If a change was made to the fileContents, let's save it if (shouldSave) { bool tryAgain = true; CodeWriter.SaveFileContents(fileContents, fileName, tryAgain); } #endregion } #endregion }
private static string GetBehaviorContents(string behaviorName) { ICodeBlock codeBlock = new CodeDocument(); string fileName = BehaviorFolder + behaviorName + ".cs"; if (File.Exists(fileName)) { string behaviorContents = FileManager.FromFileText(fileName ); codeBlock.Line(behaviorContents); } else { codeBlock.Line("// There is an invalid behavior reference to behavior " + behaviorName); } return codeBlock.ToString(); }
public void CodeGenerationStart(IElement element) { var stateChainCollection = GlueCommands.TreeNodeCommands.GetProperty<StateChainCollection>(element, PropertyName); if(stateChainCollection == null) return; var elementNameWithoutPath = FileManager.RemovePath(element.Name); var document = new CodeDocument(); ICodeBlock codeBlock = document; if (stateChainCollection.StateChains.Count <= 0) { return; } codeBlock = codeBlock .Line("using FlatRedBall.Instructions;") .Namespace(GlueCommands.GenerateCodeCommands.GetNamespaceForElement(element)) .Class("public partial ", element.ClassName, ""); //Create Enum codeBlock = codeBlock .Enum("public", "StateChains") .Line("None = 0,"); for (int i = 0; i < stateChainCollection.StateChains.Count; i++) { if (i == stateChainCollection.StateChains.Count - 1) codeBlock.Line(stateChainCollection.StateChains[i].Name); else codeBlock.Line(stateChainCollection.StateChains[i].Name + ","); } codeBlock = codeBlock.End(); //Private members codeBlock ._() .Line("private StateChains _currentStateChain = StateChains.None;") .Line("private int _index;") .Line("private Instruction _instruction;") ._(); //CurrentStateChain Property codeBlock = codeBlock .Property("public StateChains", "CurrentStateChain") .Get() .Line("return _currentStateChain;") .End() .Set() .Line("StopStateChain();") ._() .Line("_currentStateChain = value;") .Line("_index = 0;") ._() .Switch("_currentStateChain"); foreach (var stateChain in stateChainCollection.StateChains) { codeBlock .Case("StateChains." + stateChain.Name) .Line("StartNextState" + stateChain.Name + "();"); } codeBlock = codeBlock .End() .End() .End(); codeBlock._(); //ManageStateChains codeBlock = codeBlock .Function("public void", "ManageStateChains", "") .If("CurrentStateChain == StateChains.None") .Line("return;") .End() ._() .Switch("CurrentStateChain"); foreach (var stateChain in stateChainCollection.StateChains) { var index = 0; codeBlock = codeBlock .Case("StateChains." + stateChain.Name); foreach (var stateChainState in stateChain.StateChainStates.Where(stateChainState => !string.IsNullOrEmpty(stateChainState.State))) { if (index == 0) { codeBlock .If("_index == 0 && CurrentState == VariableState." + stateChainState.State) .Line("_index++;") .Line("StartNextState" + stateChain.Name + "();"); } else { codeBlock .ElseIf("_index == " + index + " && CurrentState == VariableState." + stateChainState.State) .Line("_index++;") .Line("StartNextState" + stateChain.Name + "();"); } index++; } codeBlock = codeBlock .End(); } codeBlock = codeBlock .End() .End(); codeBlock._(); //StopStateChain codeBlock = codeBlock .Function("public void", "StopStateChain", "") .If("CurrentStateChain == StateChains.None") .Line("return;") .End() ._() .Switch("CurrentStateChain"); foreach (var stateChain in stateChainCollection.StateChains) { var index = 0; codeBlock = codeBlock .Case("StateChains." + stateChain.Name); foreach (var stateChainState in stateChain.StateChainStates) { if (index == 0) { codeBlock .If("_index == 0") .Line("Instructions.Remove(_instruction);") .Line("StopStateInterpolation(VariableState." + stateChainState.State + ");") .End(); }else { codeBlock .ElseIf("_index == " + index) .Line("Instructions.Remove(_instruction);") .Line("StopStateInterpolation(VariableState." + stateChainState.State + ");") .End(); } index++; } codeBlock = codeBlock .End(); } codeBlock = codeBlock .End() .Line("_instruction = null;") .End(); codeBlock._(); //StartNextState***** foreach (var stateChain in stateChainCollection.StateChains) { codeBlock = codeBlock .Function("private void", "StartNextState" + stateChain.Name, "") .If("_index < 0") .Line("_index = 0;") .End() ._() .If("_index >= " + stateChain.StateChainStates.Count) .Line("_index = 0;") .End() ._() .Switch("_index"); var index = 0; foreach (var stateChainState in stateChain.StateChainStates) { codeBlock .Case(index.ToString()) .Line("_instruction = InterpolateToState(VariableState." + stateChainState.State + ", " + stateChainState.Time / 1000 + ");"); index++; } codeBlock = codeBlock .End() .End() ._(); } GlueCommands.ProjectCommands.CreateAndAddPartialFile(element, "StateChains", document.ToString()); }
public static void CreateEmptyCodeIfNecessary(IElement currentElement, string fullFileName, bool forceRegenerateContents) { bool doesFileExist = File.Exists(fullFileName); if (!doesFileExist) { PluginManager.ReceiveOutput("Forcing a regneration of " + fullFileName + " because Glue can't find it anywhere."); // There is no shared code file for this event, so we need to make one ProjectManager.CodeProjectHelper.CreateAndAddPartialCodeFile(fullFileName, true); } if (!doesFileExist || forceRegenerateContents) { string namespaceString = GlueCommands.Self.GenerateCodeCommands.GetNamespaceForElement(currentElement); ICodeBlock templateCodeBlock = new CodeDocument(); EventCodeGenerator.AddUsingStatementsToBlock(templateCodeBlock); ICodeBlock namespaceCB = templateCodeBlock.Namespace(namespaceString); ICodeBlock classCB = namespaceCB.Class("public partial", currentElement.ClassName, null); classCB ._() .End() .End(); string templateToSave = templateCodeBlock.ToString(); FlatRedBall.Glue.IO.FileWatchManager.IgnoreNextChangeOnFile(fullFileName); FileManager.SaveText(templateToSave, fullFileName); } // Add if it isn't part of the project const bool saveFile = false; // don't save it - we just want to make sure it's part of the project ProjectManager.CodeProjectHelper.CreateAndAddPartialCodeFile(fullFileName, saveFile); }
/// <summary> /// Injects the insideOfMethod into an event for the argument /// </summary> /// <param name="currentElement">The IElement containing the EventResponseSave.</param> /// <param name="eventResponseSave">The EventResponseSave which should have its contents set or replaced.</param> /// <param name="insideOfMethod">The inside of the methods to assign.</param> /// <returns>The full file name which contains the method contents.</returns> public static string InjectTextForEventAndSaveCustomFile(IElement currentElement, EventResponseSave eventResponseSave, string insideOfMethod) { // In case the user passes null we don't want to have null reference exceptions: if (insideOfMethod == null) { insideOfMethod = ""; } ParsedMethod parsedMethod = eventResponseSave.GetParsedMethodFromAssociatedFile(); string fullFileName = eventResponseSave.GetSharedCodeFullFileName(); bool forceRegenerate = false; string fileContents = null; if (File.Exists(fullFileName)) { fileContents = FileManager.FromFileText(fullFileName); forceRegenerate = fileContents.Contains("public partial class") == false && fileContents.Contains("{") == false; if (forceRegenerate) { GlueGui.ShowMessageBox("Forcing a regneration of " + fullFileName + " because it appears to be empty."); } } CreateEmptyCodeIfNecessary(currentElement, fullFileName, forceRegenerate); fileContents = FileManager.FromFileText(fullFileName); int indexToAddAt = 0; if (parsedMethod != null) { int startIndex; int endIndex; GetStartAndEndIndexForMethod(parsedMethod, fileContents, out startIndex, out endIndex); // We want to include the \r\n at the end, so add 2 endIndex += 2; string whatToRemove = fileContents.Substring(startIndex, endIndex - startIndex); fileContents = fileContents.Replace(whatToRemove, null); indexToAddAt = startIndex; // remove the method to re-add it } else { indexToAddAt = EventManager.GetLastLocationInClass(fileContents, startOfLine:true); } ICodeBlock codeBlock = new CodeDocument(2); codeBlock.TabCharacter = " "; insideOfMethod = "" + insideOfMethod.Replace("\r\n", "\r\n "); codeBlock = EventCodeGenerator.FillWithCustomEventCode(codeBlock, eventResponseSave, insideOfMethod, currentElement); string methodContents = codeBlock.ToString(); fileContents = fileContents.Insert(indexToAddAt, codeBlock.ToString()); eventResponseSave.Contents = null; try { FlatRedBall.Glue.IO.FileWatchManager.IgnoreNextChangeOnFile(fullFileName); FileManager.SaveText(fileContents, fullFileName); } catch (Exception e) { PluginManager.ReceiveError("Could not save file to " + fullFileName); } return fullFileName; }