private static void EditInterfaceBaseInterfaces( InterfaceWithCodeAnalysis @interface, string oldInterfaceName, List <ITypeReferenceWithCodeAnalysis> genericParameters) { foreach (InterfaceReferenceWithCodeAnalysis reference in @interface.Interfaces.ToArray()) { string referenceName = reference.Name; if (referenceName == "IVisitable") { UnspecifiedTypeReferenceWithCodeAnalysis genericParameterType = reference.GenericParameters[0] as UnspecifiedTypeReferenceWithCodeAnalysis; genericParameterType.Name = genericParameterType.Name.Replace("Generic", "Editable"); } else { reference.Name = GetNewName(referenceName); } } InterfaceReferenceWithCodeAnalysis interfaceReference = new InterfaceReferenceWithCodeAnalysis( oldInterfaceName, genericParameters.ToArray()); @interface.Interfaces.Add(interfaceReference); }
public static async Task GenerateEditableInterface(DocumentWithCodeAnalysis document) { string filePath = document.FullFilePath; string destinationPath = Path.Combine( Path.GetDirectoryName(filePath).Replace(@"CSharpDom\Common", @"CSharpDom\Common\Editable"), GetNewName(Path.GetFileName(filePath))); if (File.Exists(destinationPath)) { return; } LoadedDocumentWithCodeAnalysis loadedDocument = await document.LoadAsync(); NamespaceWithCodeAnalysis @namespace = loadedDocument.Namespaces.First(); if (@namespace.Interfaces.Count == 0) { return; } Console.WriteLine($"Writing: {Path.GetFileName(destinationPath)}"); string namespaceName = @namespace.Name; using (CodeAnalysisSettings.AllowEdits(loadedDocument)) { EditUsingDirectives(loadedDocument, namespaceName); @namespace.Name = Regex.Replace(namespaceName, "^CSharpDom.Common", "CSharpDom.Common.Editable"); InterfaceWithCodeAnalysis @interface = @namespace.Interfaces.First(); string interfaceName = @interface.Name; @interface.Name = GetNewName(interfaceName); List <ITypeReferenceWithCodeAnalysis> genericParameters = EditInterfaceGenericParameters(@interface); EditInterfaceBaseInterfaces(@interface, interfaceName, genericParameters); EditInterfaceProperties(@interface); } 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); }
private static void EditInterfaceProperties(InterfaceWithCodeAnalysis @interface) { foreach (InterfacePropertyWithCodeAnalysis property in @interface.Properties.ToArray()) { PropertyDeclarationSyntax syntax = property.Syntax; property.Syntax = syntax.WithAccessorList( syntax.AccessorList.AddAccessors(SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration))); property.InheritanceModifier = InterfaceMemberInheritanceModifier.New; if (property.PropertyType is UnspecifiedTypeReferenceWithCodeAnalysis propertyType) { string propertyTypeName = propertyType.Name; if (propertyTypeName.StartsWith("IReadOnly")) { propertyType.Name = propertyTypeName.Replace("ReadOnly", string.Empty); } } } }
private static List <ITypeReferenceWithCodeAnalysis> EditInterfaceGenericParameters( InterfaceWithCodeAnalysis @interface) { List <ITypeReferenceWithCodeAnalysis> genericParameters = new List <ITypeReferenceWithCodeAnalysis>(); foreach (GenericParameterDeclarationWithCodeAnalysis parameter in @interface.GenericParameters) { genericParameters.Add(new GenericParameterReferenceWithCodeAnalysis(parameter.Name)); if (parameter.InterfaceConstraints.Count == 0) { continue; } InterfaceReferenceWithCodeAnalysis constraint = parameter.InterfaceConstraints.First(); constraint.Name = GetNewName(constraint.Name); } return(genericParameters); }
public static async Task GenerateBaseClass(DocumentWithCodeAnalysis document) { string filePath = document.FullFilePath; string destinationPath = Path.Combine( Path.GetDirectoryName(filePath).Replace(@"CSharpDom\Common", @"CSharpDom\BaseClasses"), GetNewName(Path.GetFileName(filePath))); if (File.Exists(destinationPath)) { return; } LoadedDocumentWithCodeAnalysis loadedDocument = await document.LoadAsync(); NamespaceWithCodeAnalysis @namespace = loadedDocument.Namespaces.First(); if (@namespace.Interfaces.Count == 0) { return; } InterfaceWithCodeAnalysis @interface = @namespace.Interfaces.First(); if (@interface.GenericParameters.Count == 0) { return; } Console.WriteLine($"Writing: {Path.GetFileName(destinationPath)}"); string namespaceName = @namespace.Name; using (CodeAnalysisSettings.AllowEdits(loadedDocument)) { LoadedDocumentWithCodeAnalysis newDocument = new LoadedDocumentWithCodeAnalysis(); newDocument.UsingDirectives.Add(new UsingDirectiveWithCodeAnalysis(namespaceName)); DocumentWithCodeAnalysis baseClassDocument = document.Project.AddDocument( destinationPath, newDocument); NamespaceWithCodeAnalysis newNamespace = new NamespaceWithCodeAnalysis( baseClassDocument, namespaceName.Replace("Common", "BaseClasses")); AbstractClassWithCodeAnalysis baseClass = new AbstractClassWithCodeAnalysis( baseClassDocument, TypeVisibilityModifier.Public, GetNewName(@interface.Name)) { GenericParameters = @interface.GenericParameters, BaseClass = new ClassReferenceWithCodeAnalysis("AbstractExpression") }; ITypeReferenceWithCodeAnalysis[] implementedInterfaceGenericParameters = @interface.GenericParameters .Select(parameter => new GenericParameterReferenceWithCodeAnalysis(parameter.Name)) .ToArray(); baseClass.ImplementedInterfaces.Add( new InterfaceReferenceWithCodeAnalysis(@interface.Name, implementedInterfaceGenericParameters)); newNamespace.Classes.AbstractClasses.Add(baseClass); newDocument.Namespaces.Add(newNamespace); await baseClass.ImplementInterfaceAsync(@class => @class.ImplementedInterfaces.First(), baseClassDocument); foreach (AbstractClassPropertyWithCodeAnalysis property in baseClass.Properties) { } } 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); }