Exemplo n.º 1
0
        private static async Task EditGenericVisitor()
        {
            string baseDirectory = Path.GetFullPath(
                Path.Combine(Path.GetDirectoryName(typeof(Program).Assembly.Location), @"..\..\..\.."));
            LoadedDocumentWithCodeAnalysis document = await LoadedDocumentWithCodeAnalysis.LoadFromFileAsync(
                Path.Combine(baseDirectory, @"CSharpDom\Common\Expressions\GenericExpressionVisitor.cs"));

            foreach (StaticClassMethodWithCodeAnalysis method in
                     document.Namespaces.First().Classes.StaticClasses.First().Methods)
            {
                IList <IStatementWithCodeAnalysis> statements = method.Body.Statements;
                if (statements.Count == 1 &&
                    statements[0] is ExpressionStatementWithCodeAnalysis expressionStatement &&
                    expressionStatement.Expression is MethodCallExpressionWithCodeAnalysis methodCall &&
                    methodCall.Expression is MemberExpressionWithCodeAnalysis member &&
                    member.ObjectExpression is IdentifierExpressionWithCodeAnalysis identifier &&
                    identifier.Name == "GenericExpressionChildVisitor")
                {
                    continue;
                }

                //statements.Clear();
                IExpressionWithCodeAnalysis expression = ExpressionFactory.MethodCall(
                    ExpressionFactory.Member(ExpressionFactory.Identifier("GenericChildVisitor"), method.Name));
                statements.Add(StatementFactory.Expression(expression));
            }
        }
Exemplo n.º 2
0
        private static void EditUsingDirectives(
            LoadedDocumentWithCodeAnalysis loadedDocument,
            string namespaceName)
        {
            List <UsingDirectiveWithCodeAnalysis> usingDirectives = loadedDocument.UsingDirectives.ToList();

            foreach (UsingDirectiveWithCodeAnalysis directive in usingDirectives)
            {
                string directiveName = directive.Name;
                if (directiveName.Contains("CSharpDom.Common."))
                {
                    directive.Name = directiveName.Replace("CSharpDom.Common.", "CSharpDom.Common.Editable.");
                }
            }

            if (namespaceName.StartsWith("CSharpDom.Common."))
            {
                UsingDirectiveWithCodeAnalysis usingDirective = new UsingDirectiveWithCodeAnalysis(namespaceName);
                usingDirectives.Insert(
                    ~usingDirectives.BinarySearch(usingDirective, new NameComparer()),
                    usingDirective);
            }

            loadedDocument.UsingDirectives = usingDirectives;
        }
        private async Task TestType(Type type)
        {
            string expectedResult = TypeTextProvider.GetTypeText(type);
            SolutionWithCodeAnalysis       solution = SolutionWithCodeAnalysis.GetSolutionForSourceCode(expectedResult);
            LoadedDocumentWithCodeAnalysis document = await solution.Projects.First().Documents.First().LoadAsync();

            string documentText = document.ToSourceCode();

            documentText.TrimEnd().Replace("\r", string.Empty).Should().Be(expectedResult.TrimEnd().Replace("\r", string.Empty));
        }
Exemplo n.º 4
0
        private static async Task GenerateWrapperImplementations()
        {
            string baseDirectory = Path.GetFullPath(
                Path.Combine(Path.GetDirectoryName(typeof(Program).Assembly.Location), @"..\..\..\.."));
            SolutionWithCodeAnalysis solution = await SolutionWithCodeAnalysis.OpenAsync(
                Path.Combine(baseDirectory, @"CSharpDom.sln"));

            ProjectWithCodeAnalysis project = solution.Projects.First(p => p.Syntax.Name == "CSharpDom");

            project.Lock();
            foreach (DocumentWithCodeAnalysis document in project.Documents
                     .Where(document => document.FullFilePath.Contains(@"CSharpDom\Wrappers\Internal"))
                     .OrderBy(document => document.FullFilePath))
            {
                document.IsLocked = true;
                bool isEdited = false;
                LoadedDocumentWithCodeAnalysis loadedDocument = await document.LoadAsync();

                using (CodeAnalysisSettings.AllowEdits(loadedDocument))
                {
                    SealedClassWithCodeAnalysis @class = loadedDocument.Namespaces.First().Classes.SealedClasses.FirstOrDefault();
                    if (@class == null)
                    {
                        continue;
                    }

                    foreach (SealedClassPropertyWithCodeAnalysis property in @class.Properties
                             .Where(property => property.GetAccessor.Body.Statements.FirstOrDefault() is ThrowStatementWithCodeAnalysis)
                             .ToArray())
                    {
                        isEdited = true;
                        string propertyName = property.Name;
                        string fieldName    = propertyName.Substring(0, 1).ToLower() + propertyName.Substring(1);
                        SealedClassFieldWithCodeAnalysis field = new SealedClassFieldWithCodeAnalysis(
                            ClassMemberVisibilityModifier.Private,
                            new DelegateReferenceWithCodeAnalysis("Func", property.PropertyType),
                            fieldName);
                        @class.Fields.Fields.Add(field);
                        IList <IStatementWithCodeAnalysis> statements = property.GetAccessor.Body.Statements;
                        statements.Clear();
                        statements.Add(
                            StatementFactory.Return(ExpressionFactory.MethodCall(ExpressionFactory.Identifier(fieldName))));
                    }
                }

                if (isEdited)
                {
                    string sourceCode = loadedDocument.ToSourceCode();
                    File.WriteAllText(document.FullFilePath, sourceCode);
                }
            }
        }
Exemplo n.º 5
0
        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);
        }
Exemplo n.º 6
0
        private static async Task LoadImplementInterfaceAsync()
        {
            var assembly      = Assembly.Load("Microsoft.CodeAnalysis.CSharp.Features");
            var configuration = new ContainerConfiguration().WithAssembly(assembly);
            var container     = configuration.CreateContainer();
            var test          = container.GetExports <CodeFixProvider>().ToArray();
            var test2         = test.FirstOrDefault(provider =>
                                                    (Attribute.GetCustomAttribute(provider.GetType(), typeof(ExportCodeFixProviderAttribute)) as ExportCodeFixProviderAttribute)?.Name == "ImplementInterface");
            string solutionFile = Path.Combine(
                Path.GetDirectoryName(typeof(Program).Assembly.Location),
                @"..\..\..\..\CSharpDom.sln");

            solutionFile = Path.GetFullPath(solutionFile);
            SolutionWithCodeAnalysis solution = await SolutionWithCodeAnalysis.OpenAsync(solutionFile);

            //(Workspace, ProjectWithCodeAnalysis) project = await ProjectWithCodeAnalysis.OpenWithWorkspaceAsync(projectFile);
            DocumentWithCodeAnalysis document = solution.Projects
                                                .First(project => project.Syntax.Name == "CSharpDom.EditableInterfaceGenerator")
                                                .Documents.First();
            Compilation compilation = await document.Syntax.Project.GetCompilationAsync();

            //SyntaxGenerator generator = document.Syntax.get
            LoadedDocumentWithCodeAnalysis loadedDocument = await document.LoadAsync();

            var syntax = loadedDocument.Namespaces.First().Classes.SealedClasses.First().ImplementedInterfaces.First().Syntax;
            List <CodeAction> actions = new List <CodeAction>();
            var            descriptor = new DiagnosticDescriptor("CS0535", "CS0535", "CS0535", "CS0535", DiagnosticSeverity.Error, true);
            CodeFixContext context    = new CodeFixContext(
                document.Syntax,
                Diagnostic.Create(descriptor, Location.Create(syntax.SyntaxTree, syntax.Span)),
                (action, diagnostics) => actions.Add(action),
                CancellationToken.None);
            await test2.RegisterCodeFixesAsync(context);

            var operations = await actions[0].GetOperationsAsync(CancellationToken.None);

            foreach (var operation in operations)
            {
                operation.Apply(solution.Syntax.Workspace, CancellationToken.None);
            }
            actions.GetHashCode();
        }
        internal static PartialClassCollectionWithCodeAnalysis Create(LoadedDocumentWithCodeAnalysis document)
        {
            var members         = document.Members;
            var abstractClasses = new LoadedDocumentMemberListWrapper <AbstractPartialClassWithCodeAnalysis, ClassDeclarationSyntax>(
                document.Node,
                () => new AbstractPartialClassWithCodeAnalysis(document.Document),
                ClassDeclarationSyntaxExtensions.IsAbstractPartialClass);
            var classes = new LoadedDocumentMemberListWrapper <PartialClassWithCodeAnalysis, ClassDeclarationSyntax>(
                document.Node,
                () => new PartialClassWithCodeAnalysis(document.Document),
                ClassDeclarationSyntaxExtensions.IsPartialClass);
            var sealedClasses = new LoadedDocumentMemberListWrapper <SealedPartialClassWithCodeAnalysis, ClassDeclarationSyntax>(
                document.Node,
                () => new SealedPartialClassWithCodeAnalysis(document.Document),
                ClassDeclarationSyntaxExtensions.IsSealedPartialClass);
            var staticClasses = new LoadedDocumentMemberListWrapper <StaticPartialClassWithCodeAnalysis, ClassDeclarationSyntax>(
                document.Node,
                () => new StaticPartialClassWithCodeAnalysis(document.Document),
                ClassDeclarationSyntaxExtensions.IsStaticPartialClass);

            return(new PartialClassCollectionWithCodeAnalysis(members, abstractClasses, classes, sealedClasses, staticClasses));
        }
Exemplo n.º 8
0
        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);
                }
            }
        }
Exemplo n.º 9
0
        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);
        }
Exemplo n.º 10
0
        private static async Task GenerateForwardingVisitor()
        {
            string visitorFileName = Path.Combine(
                Path.GetDirectoryName(typeof(Program).Assembly.Location),
                @"..\..\..\..\CSharpDom\Common\Statements\GenericStatementChildVisitor.cs");

            visitorFileName = Path.GetFullPath(visitorFileName);
            LoadedDocumentWithCodeAnalysis loadedDocument =
                await LoadedDocumentWithCodeAnalysis.LoadFromFileAsync(visitorFileName);

            StaticClassWithCodeAnalysis visitorClass = loadedDocument.Namespaces.First().Classes.StaticClasses.First();

            using (CodeAnalysisSettings.AllowEdits(visitorClass))
            {
                foreach (StaticClassMethodWithCodeAnalysis method in
                         visitorClass.Methods.Where(method => method.GenericParameters.LastOrDefault()?.Name != "TVisitor"))
                {
                    Console.WriteLine($"Editing: {method.Name}");
                    UnspecifiedTypeReferenceWithCodeAnalysis visitableType =
                        (UnspecifiedTypeReferenceWithCodeAnalysis)method.Parameters[0].ParameterType;
                    InterfaceReferenceWithCodeAnalysis visitorType = new InterfaceReferenceWithCodeAnalysis(
                        "IVisitable",
                        TypeReferenceFactory.GenericParameter("TVisitor"));
                    foreach (GenericParameterDeclarationWithCodeAnalysis genericParameter in
                             method.GenericParameters)
                    {
                        string genericParameterName = genericParameter.Name;
                        if (genericParameterName != "TDocument" &&
                            genericParameterName != "TProject" &&
                            genericParameterName != "TSolution")
                        {
                            genericParameter.InterfaceConstraints.Add(visitorType);
                        }
                    }

                    string newName = Regex.Replace(visitableType.Name, "^I", "T");
                    method.Parameters[0].ParameterType = TypeReferenceFactory.GenericParameter(newName);
                    method.Parameters[1].ParameterType = TypeReferenceFactory.GenericParameter("TVisitor");
                    GenericParameterDeclarationWithCodeAnalysis newGenericParameter =
                        new GenericParameterDeclarationWithCodeAnalysis(newName)
                    {
                        InterfaceConstraints =
                        {
                            new InterfaceReferenceWithCodeAnalysis(visitableType)
                        }
                    };
                    method.GenericParameters.Insert(0, newGenericParameter);
                    method.GenericParameters.Add(new GenericParameterDeclarationWithCodeAnalysis("TVisitor"));
                    int statementIndex = -1;
                    int parameterIndex = 1;
                    foreach (IStatementWithCodeAnalysis statement in method.Body.Statements)
                    {
                        statementIndex++;
                        if (!(statement is ExpressionStatementWithCodeAnalysis expression) ||
                            !(expression.Expression is MethodCallExpressionWithCodeAnalysis methodCall) ||
                            !(methodCall.Expression is MemberExpressionWithCodeAnalysis memberCall) ||
                            !(memberCall.ObjectExpression is NewExpressionWithCodeAnalysis newObjectCall))
                        {
                            continue;
                        }

                        UnspecifiedTypeReferenceWithCodeAnalysis type =
                            newObjectCall.Type as UnspecifiedTypeReferenceWithCodeAnalysis;
                        string typeName        = type.Name.Replace("Wrapper", string.Empty);
                        string genericTypeName = $"T{typeName}";
                        string parameterName   = $"{typeName.Substring(0, 1).ToLower()}{typeName.Substring(1)}Factory";
                        newGenericParameter = new GenericParameterDeclarationWithCodeAnalysis(genericTypeName)
                        {
                            InterfaceConstraints =
                            {
                                new InterfaceReferenceWithCodeAnalysis(
                                    $"I{typeName}",
                                    type.GenericParameters.ToArray()),
                                visitorType
                            }
                        };
                        method.GenericParameters.Insert(parameterIndex, newGenericParameter);
                        ITypeReferenceWithCodeAnalysis parameterType = TypeReferenceFactory.Delegate(
                            "Func",
                            TypeReferenceFactory.GenericParameter(newName),
                            TypeReferenceFactory.GenericParameter(genericTypeName));
                        MethodParameterWithCodeAnalysis parameter = new MethodParameterWithCodeAnalysis(
                            parameterType,
                            parameterName);
                        method.Parameters.Insert(parameterIndex, parameter);
                        parameterIndex++;
                        memberCall.ObjectExpression = ExpressionFactory.MethodCall(
                            ExpressionFactory.Identifier(parameterName),
                            ExpressionFactory.Identifier(method.Parameters[0].Name));
                    }
                }
            }

            const int maximumLineLength = 120;
            string    sourceCode        = loadedDocument.ToSourceCode(
                new IndentMethodParametersIfTooLongRule(maximumLineLength));

            File.WriteAllText(visitorFileName, sourceCode);
        }