private static async Task GenerateVisitorInterface() { string baseDirectory = Path.GetFullPath( Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), @"..\..\..\..")); ProjectWithCodeAnalysis project = await ProjectWithCodeAnalysis.OpenAsync( Path.Combine(baseDirectory, @"CSharpDom.CodeAnalysis\CSharpDom.CodeAnalysis.csproj")); LoadedProjectWithCodeAnalysis loadedProject = await project.LoadAsync(); Interface visitorInterface = new Interface("ICodeAnalysisVisitor"); IEnumerable <string> classNames = from @class in loadedProject.AllClasses let baseClassName = @class.BaseClass?.Name where baseClassName != null && baseClassName.StartsWith("Editable") && !baseClassName.Contains("Expression") && !baseClassName.Contains("Statement") let className = @class.Name orderby className select className; foreach (string className in classNames) { string parameterName = Regex.Replace(className, "WithCodeAnalysis$", ""); parameterName = parameterName.Substring(0, 1).ToLower() + parameterName.Substring(1); InterfaceMethod method = new InterfaceMethod($"Visit{className}") { ReturnType = new TypeReference(typeof(void)), Parameters = new Collection <MethodParameter>() { new MethodParameter(parameterName, new TypeReference(className)) } }; visitorInterface.Body.Methods.Add(method); } Console.WriteLine(visitorInterface.ToString()); }
private static async Task GenerateEditableWrappers() { string baseDirectory = Path.GetFullPath( Path.Combine(Path.GetDirectoryName(typeof(Program).Assembly.Location), @"..\..\..\..")); ProjectWithCodeAnalysis project = await ProjectWithCodeAnalysis.OpenAsync( Path.Combine(baseDirectory, @"CSharpDom\CSharpDom.csproj")); project.Lock(); foreach (DocumentWithCodeAnalysis document in project.Documents.OrderBy(document => document.FullFilePath)) { document.IsLocked = true; string filePath = document.FullFilePath; if (!filePath.Contains(@"CSharpDom\BaseClasses\Wrappers")) { continue; } string newDirectory = Path.GetDirectoryName(filePath) .Replace(@"CSharpDom\BaseClasses\Wrappers", @"CSharpDom\BaseClasses\Editable\Wrappers"); string destinationPath = Path.Combine(newDirectory, GetNewName(Path.GetFileName(filePath))); if (File.Exists(destinationPath)) { continue; } LoadedDocumentWithCodeAnalysis loadedDocument = await document.LoadAsync(); NamespaceWithCodeAnalysis @namespace = loadedDocument.Namespaces.First(); Console.WriteLine($"Writing: {Path.GetFileName(destinationPath)}"); string namespaceName = @namespace.Name; using (CodeAnalysisSettings.AllowEdits(loadedDocument)) { foreach (UsingDirectiveWithCodeAnalysis directive in loadedDocument.UsingDirectives) { directive.Name = directive.Name.Replace("CSharpDom.Common", "CSharpDom.Common.Editable"); } loadedDocument.UsingDirectives.Add(new UsingDirectiveWithCodeAnalysis("CSharpDom.Common")); loadedDocument.UsingDirectives = loadedDocument.UsingDirectives .OrderBy(directive => directive.Name) .ToArray(); @namespace.Name = "CSharpDom.BaseClasses.Editable.Wrappers"; SealedClassWithCodeAnalysis @class = @namespace.Classes.SealedClasses.First(); @class.Name = "Editable" + @class.Name; @class.BaseClass.Name = Regex.Replace(@class.BaseClass.Name, "^Abstract", "Editable"); ITypeReferenceWithCodeAnalysis interfaceReference = @class.ImplementedInterfaces.First().GenericParameters[0]; interfaceReference.Name = Regex.Replace(interfaceReference.Name, "^I", "IEditable"); foreach (GenericParameterDeclarationWithCodeAnalysis genericParameter in @class.GenericParameters) { InterfaceReferenceWithCodeAnalysis constraint = genericParameter.InterfaceConstraints.First(); constraint.Name = Regex.Replace(constraint.Name, "^I", "IEditable"); } ITypeReferenceWithCodeAnalysis constructorParameterType = @class.Constructors.First().Parameters[0].ParameterType; constructorParameterType.Name = Regex.Replace(constructorParameterType.Name, "^I", "IEditable"); foreach (SealedClassAutoPropertyWithCodeAnalysis property in @class.Properties.AutoProperties) { if (property.Name == "WrappedObject") { //CodeAnalysisLogger.StartLoggingDebugMessages(); property.PropertyType.Name = Regex.Replace(property.PropertyType.Name, "^I", "IEditable"); //string[] logMessages = CodeAnalysisLogger.GetDebugLogMessages(); //CodeAnalysisLogger.StopLoggingDebugMessages(); break; } } foreach (SealedClassPropertyWithCodeAnalysis property in @class.Properties) { string propertyName = property.Name; if (propertyName == "WrappedObject") { continue; } string propertyTypeName = property.PropertyType.Name; if (propertyTypeName.Contains("ReadOnly")) { property.PropertyType.Name = propertyTypeName.Replace("ReadOnly", string.Empty); } IExpressionWithCodeAnalysis expression = ExpressionFactory.Binary( ExpressionFactory.Member(ExpressionFactory.Identifier("WrappedObject"), propertyName), BinaryOperatorExpressionType.Assign, ExpressionFactory.Identifier("value")); property.SetAccessor = new ClassAccessorWithCodeAnalysis( AccessorType.Set, new MethodBodyWithCodeAnalysis(StatementFactory.Expression(expression))); } Directory.CreateDirectory(Path.GetDirectoryName(destinationPath)); const int maximumLineLength = 120; string sourceCode = loadedDocument.ToSourceCode( new IndentBaseTypeListIfTooLongRule(maximumLineLength), new IndentGenericParamterDefinitionsIfTooLongRule(maximumLineLength), new IndentMethodParametersIfTooLongRule(maximumLineLength)); File.WriteAllText(destinationPath, sourceCode); } } }