internal StaticPartialClassWithCodeAnalysis(DocumentWithCodeAnalysis document)
        {
            this.document = document;
            var type = new InternalStaticTypeWithCodeAnalysis <StaticPartialClassWithCodeAnalysis>(this);

            classType = new StaticClassWithCodeAnalysis(document, type);
            classes   = new StaticPartialClassNestedClassCollectionWithCodeAnalysis(classType.Classes);
            delegates = new WrappedCollection <StaticClassNestedDelegateWithCodeAnalysis, StaticPartialClassNestedDelegateWithCodeAnalysis>(
                classType.Delegates,
                parent => new StaticPartialClassNestedDelegateWithCodeAnalysis(parent),
                child => child.Delegate,
                value => classType.Delegates = value);
            enums = new WrappedCollection <StaticClassNestedEnumWithCodeAnalysis, StaticPartialClassNestedEnumWithCodeAnalysis>(
                classType.Enums,
                parent => new StaticPartialClassNestedEnumWithCodeAnalysis(parent),
                child => child.Enum,
                value => classType.Enums = value);
            events     = new StaticPartialClassEventCollectionWithCodeAnalysis(classType.Events);
            fields     = new StaticPartialClassFieldCollectionWithCodeAnalysis(classType.Fields);
            interfaces = new WrappedCollection <StaticClassNestedInterfaceWithCodeAnalysis, StaticPartialClassNestedInterfaceWithCodeAnalysis>(
                classType.Interfaces,
                parent => new StaticPartialClassNestedInterfaceWithCodeAnalysis(parent),
                child => child.Interface,
                value => classType.Interfaces = value);
            methods    = new StaticPartialClassMethodCollectionWithCodeAnalysis(type);
            properties = new StaticPartialClassPropertyCollectionWithCodeAnalysis(classType.Properties);
            structs    = new StaticPartialClassNestedStructCollectionWithCodeAnalysis(classType.Structs);
            members    = type.Members;
        }
Пример #2
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);
        }