/// <summary> /// Gets the contract source file, if one does not exist it will create the partial class file. /// </summary> /// <param name="source">The visual studio source file to search.</param> /// <param name="sourceClass">The target class that contains the contract.</param> /// <returns>The target source code or null if it could not be created.</returns> public static async Task <CsSource> GetContractSourceFileAsync(VsCSharpSource source, CsClass sourceClass) { if (source == null) { return(null); } if (sourceClass == null) { return(null); } var contractFile = GetContractFilePath(sourceClass); CsSource result = null; if (contractFile.hasFile) { result = await source.GetCsSourceDocumentFromParent(contractFile.filePath); } else { var manager = source.SourceCode.LoadNamespaceManager(sourceClass.Namespace); var partialClassSource = CSharpSourceGenerationCommon.GeneratePartialClass(sourceClass, manager); if (string.IsNullOrEmpty(partialClassSource)) { throw new CodeFactoryException($"Could not generated partial class definition for class {sourceClass.Name}"); } result = await source.AddCSharpCodeFileToParentAsync(partialClassSource, Path.GetFileName(contractFile.filePath)); } return(result); }
private async Task <CsSource> AddMethodMember(CsClass targetClass, CsMethod member, bool logging, bool cdf, bool cdfAspNet, string targetFilePath, NamespaceManager manager) { CsSource result = null; string sourceCode = null; if (cdfAspNet) { if (WebApiSupport.IsControllerAction(member)) { sourceCode = CSharpSourceGenerationCommonDeliveryFramework.GenerateControllerActionMethodSourceCode(member, manager, true, true, CsSecurity.Public, logging, "_logger"); } else { sourceCode = CSharpSourceGenerationCommonDeliveryFramework.GenerateStandardMethodSourceCode(member, manager, true, true, CsSecurity.Public, logging, "_logger"); } } else { if (cdf) { sourceCode = CSharpSourceGenerationCommonDeliveryFramework.GenerateStandardMethodSourceCode(member, manager, true, true, CsSecurity.Public, logging, "_logger"); } else { if (logging) { sourceCode = CSharpSourceGenerationNetCommon.GenerateStandardMethodSourceCode(member, manager, true, true, CsSecurity.Public, true, "_logger"); } else { sourceCode = CSharpSourceGenerationCommon.GenerateStandardMethodSourceCode(member, manager, true, true); } } } if (string.IsNullOrEmpty(sourceCode)) { throw new CodeFactoryException("Was not able to generate the source code for the member method."); } result = await targetClass.AddToEndAsync(targetFilePath, CsSourceFormatter.IndentCodeBlock(2, sourceCode)); if (result == null) { throw new CodeFactoryException("Could not load the source code after adding the member."); } return(result); }
private async Task <CsSource> AddProperty(CsClass targetClass, CsProperty member, string targetFilePath, NamespaceManager manager) { CsSource result = null; string sourceCode = CSharpSourceGenerationCommon.GenerateStandardPropertySourceCode(member, manager); if (string.IsNullOrEmpty(sourceCode)) { throw new CodeFactoryException("Was not able to generate the source code for the member property."); } result = await targetClass.AddToEndAsync(targetFilePath, CsSourceFormatter.IndentCodeBlock(2, sourceCode)); if (result == null) { throw new CodeFactoryException("Could not load the source code after adding the member."); } return(result); }
private async Task <CsSource> UpdateSubscriptionAsync(CsField subscriptionField, CsClass sourceClass, VsCSharpSource source) { SourceFormatter formatter = new SourceFormatter(); string injectSourceCode = null; var contract = subscriptionField.DataType.GetInterfaceModel(); if (contract == null) { return(null); } CsSource sourceCode = source.SourceCode; try { CsClass currentClass = sourceClass; var events = contract.Events; var subscribePath = ContractHelper.GetSubscribeFilePath(currentClass); if (!subscribePath.hasFile) { var manager = sourceCode.LoadNamespaceManager(sourceClass.Namespace); var parent = await source.GetParentAsync(); if (parent == null) { throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription"); } VsDocument generatedDocument = null; string partialClassSource = CSharpSourceGenerationCommon.GeneratePartialClass(currentClass, manager); if (parent.ModelType == VisualStudioModelType.ProjectFolder) { var parentFolder = parent as VsProjectFolder; if (parentFolder == null) { throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription"); } generatedDocument = await parentFolder.AddDocumentAsync(Path.GetFileName(subscribePath.filePath), partialClassSource); } else { var parentProject = parent as VsProject; if (parentProject == null) { throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription"); } generatedDocument = await parentProject.AddDocumentAsync(subscribePath.filePath, partialClassSource); } sourceCode = await generatedDocument.GetCSharpSourceModelAsync(); sourceCode = await sourceCode.AddMissingNamespaces(contract.Events, currentClass.Namespace); currentClass = sourceCode.GetModel(currentClass.LookupPath) as CsClass; if (currentClass == null) { throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription"); } } else { var parent = await source.GetParentAsync(); VsCSharpSource sourceDocument = null; if (parent.ModelType == VisualStudioModelType.ProjectFolder) { var parentFolder = parent as VsProjectFolder; if (parentFolder == null) { throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription"); } var children = await parentFolder.GetChildrenAsync(false, true); sourceDocument = children.Where(c => c.ModelType == VisualStudioModelType.CSharpSource) .Cast <VsCSharpSource>() .FirstOrDefault(s => s.SourceCode.SourceDocument == subscribePath.filePath); } else { var parentProject = parent as VsProject; if (parentProject == null) { throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription"); } var children = await parentProject.GetChildrenAsync(false, true); sourceDocument = children.Where(c => c.ModelType == VisualStudioModelType.CSharpSource) .Cast <VsCSharpSource>() .FirstOrDefault(s => s.SourceCode.SourceDocument == subscribePath.filePath);; } if (sourceDocument == null) { throw new CodeFactoryException("Could load the contract document."); } sourceCode = sourceDocument.SourceCode; sourceCode = await sourceCode.AddMissingNamespaces(contract.Events, currentClass.Namespace); currentClass = sourceCode.GetModel(currentClass.LookupPath) as CsClass; if (currentClass == null) { throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription"); } } var namespaceManager = sourceCode.LoadNamespaceManager(currentClass.Namespace); foreach (var contractEvent in contract.Events) { var eventHandlerName = CSharpSourceGenerationWPF.GenerateContractEventHandlerMethodName(subscriptionField, contractEvent); if (eventHandlerName == null) { throw new CodeFactoryException($"Could not create the source code for a contract event handler."); } if (currentClass.Methods.Any(m => m.Name == eventHandlerName)) { continue; } var eventHandlerSource = CSharpSourceGenerationWPF.GenerateContractEventHandlerMethod(subscriptionField, contractEvent, namespaceManager); if (eventHandlerSource == null) { throw new CodeFactoryException($"Could not create the source code for the event handler {eventHandlerName}"); } sourceCode = await currentClass.AddToEndAsync(subscribePath.filePath, InjectSourceCodeAtLevel(2, eventHandlerSource)); currentClass = sourceCode.GetModel(currentClass.LookupPath) as CsClass; if (currentClass == null) { throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription"); } } var subscriptionName = CSharpSourceGenerationWPF.GenerateContractSubscriptionMethodName(subscriptionField); var subscriptionMethod = currentClass.Methods.FirstOrDefault(m => m.Name == subscriptionName); if (subscriptionMethod != null) { sourceCode = await subscriptionMethod.DeleteAsync(); currentClass = sourceCode.GetModel(currentClass.LookupPath) as CsClass; if (currentClass == null) { throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription"); } } var subscriptionSource = CSharpSourceGenerationWPF.GenerateContractSubscriptionMethod(subscriptionField, contract); if (subscriptionSource == null) { throw new CodeFactoryException("Cannot generate the subscription contract source code."); } sourceCode = await currentClass.AddToEndAsync(subscribePath.filePath, InjectSourceCodeAtLevel(2, subscriptionSource)); currentClass = sourceCode.GetModel(currentClass.LookupPath) as CsClass; if (currentClass == null) { throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription"); } var releaseName = CSharpSourceGenerationWPF.GenerateContractReleaseMethodName(subscriptionField); var releaseMethod = currentClass.Methods.FirstOrDefault(m => m.Name == releaseName); if (releaseMethod != null) { sourceCode = await releaseMethod.DeleteAsync(); currentClass = sourceCode.GetModel(currentClass.LookupPath) as CsClass; if (currentClass == null) { throw new CodeFactoryException("Cannot access the parent of the source code document, cannot update subscription"); } } var releaseSource = CSharpSourceGenerationWPF.GenerateContractReleaseMethod(subscriptionField, contract); if (releaseSource == null) { throw new CodeFactoryException("Cannot generate the release contract source code."); } sourceCode = await currentClass.AddToEndAsync(subscribePath.filePath, InjectSourceCodeAtLevel(2, releaseSource)); } catch (CodeFactoryException) { throw; } catch (Exception unhandledException) { throw new CodeFactoryException("The following unhandledException occured", unhandledException); } return(sourceCode); }
private async Task <CsSource> AddEvent(CsClass targetClass, CsEvent member, bool isContractMember, string targetFilePath, NamespaceManager manager) { CsSource result = null; CsClass currentClass = targetClass; string eventSourceCode = null; string eventFieldName = null; if (isContractMember) { string fieldPrefix = "_"; string fieldSuffix = "Handler"; eventFieldName = $"{fieldPrefix}{member.Name.ConvertToCamelCase()}{fieldSuffix}"; if (!currentClass.Fields.Any(f => f.Name == eventFieldName)) { string fieldSource = $"private {member.EventType.CSharpFormatTypeName(manager)} {eventFieldName};"; result = await currentClass.AddToBeginningAsync(targetFilePath, CsSourceFormatter.IndentCodeBlock(2, fieldSource)); currentClass = result.GetModel(currentClass.LookupPath) as CsClass; if (currentClass == null) { throw new CodeFactoryException("Could not load class data cannot update members."); } } eventSourceCode = CSharpSourceGenerationCommon.GenerateAddRemoveEvent(member, manager, CsSecurity.Public, fieldPrefix, fieldSuffix); } else { eventSourceCode = CSharpSourceGenerationCommon.GenerateStandardEventSourceCode(member, manager); } if (string.IsNullOrEmpty(eventSourceCode)) { throw new CodeFactoryException("Could not generate the event source code."); } result = await currentClass.AddToEndAsync(targetFilePath, CsSourceFormatter.IndentCodeBlock(2, eventSourceCode)); currentClass = result.GetModel(currentClass.LookupPath) as CsClass; if (currentClass == null) { throw new CodeFactoryException("Could not load class data cannot update members."); } string raiseEventSourceCode = null; if (isContractMember) { if (string.IsNullOrEmpty(eventFieldName)) { throw new CodeFactoryException("Event field name was not provided cannot create event handler"); } raiseEventSourceCode = CSharpSourceGenerationCommon.GenerateStandardRaiseEventMethod(member, manager, member.Name, CsSecurity.Protected, eventFieldName); } else { raiseEventSourceCode = CSharpSourceGenerationCommon.GenerateStandardRaiseEventMethod(member, manager, member.Name, CsSecurity.Protected); } result = await currentClass.AddToEndAsync(targetFilePath, CsSourceFormatter.IndentCodeBlock(2, raiseEventSourceCode)); return(result); }