Esempio n. 1
0
        /// <summary>
        /// Returns an expression that converts to a <see cref="SimpleParameterType"/>,
        /// using <see cref="LinqToWiki.Internals.ValueParser"/>.
        /// </summary>
        private static ExpressionSyntax CreateSimpleConverter(
            SimpleParameterType simpleType, string propertyName, ExpressionSyntax value, ExpressionSyntax wiki)
        {
            if (simpleType.Name == "namespace")
            {
                return(SyntaxEx.Invocation(SyntaxEx.MemberAccess("ValueParser", "ParseNamespace"), value, wiki));
            }

            string typeName;

            switch (simpleType.Name)
            {
            case "string":
            case "user":
                typeName = "String";
                break;

            case "timestamp":
                typeName = "DateTime";
                break;

            case "boolean":
                typeName = "Boolean";
                break;

            case "integer":
                typeName = propertyName.EndsWith("id") ? "Int64" : "Int32";
                break;

            default:
                throw new InvalidOperationException(string.Format("Unknown type {0}", simpleType.Name));
            }

            return(SyntaxEx.Invocation(SyntaxEx.MemberAccess("ValueParser", "Parse" + typeName), value));
        }
Esempio n. 2
0
 /// <summary>
 /// Creates file that holds all enums.
 /// </summary>
 private void CreateEnumsFile()
 {
     Files.Add(
         Names.Enums,
         SyntaxEx.CompilationUnit(
             SyntaxEx.NamespaceDeclaration(Namespace), "LinqToWiki.Internals"));
 }
Esempio n. 3
0
        /// <summary>
        /// Creates the <c>Wiki</c> class, that is used as an entry point for the whole API.
        /// It can be used to access non-query modules directly and non-prop query mdoules
        /// indirectly though its <c>Query</c> property.
        /// </summary>
        private void CreateWikiClass(string baseUri, string apiPath)
        {
            var wikiField = SyntaxEx.FieldDeclaration(
                new[] { SyntaxKind.PrivateKeyword, SyntaxKind.ReadOnlyKeyword }, Names.WikiInfo, "m_wiki");

            var queryProperty = SyntaxEx.AutoPropertyDeclaration(
                new[] { SyntaxKind.PublicKeyword }, Names.QueryAction, "Query", SyntaxKind.PrivateKeyword);

            var pagesSourcePageSizePropertyName      = "PagesSourcePageSize";
            var wikiFieldPagesSourcePageSizeProperty = SyntaxEx.MemberAccess(wikiField, pagesSourcePageSizePropertyName);
            var pagesSourcePageSizeProperty          = SyntaxEx.PropertyDeclaration(
                new[] { SyntaxKind.PublicKeyword }, SyntaxFactory.ParseTypeName("int"), pagesSourcePageSizePropertyName,
                getStatements: new[] { SyntaxEx.Return(wikiFieldPagesSourcePageSizeProperty) },
                setStatements:
                new[] { SyntaxEx.Assignment(wikiFieldPagesSourcePageSizeProperty, SyntaxFactory.IdentifierName("value")) });

            var userAgentParameter = SyntaxEx.Parameter("string", "userAgent");
            var baseUriParameter   = SyntaxEx.Parameter("string", "baseUri", SyntaxEx.NullLiteral());
            var apiPathParameter   = SyntaxEx.Parameter("string", "apiPath", SyntaxEx.NullLiteral());

            var wikiAssignment = SyntaxEx.Assignment(
                wikiField,
                SyntaxEx.ObjectCreation(
                    Names.WikiInfo,
                    (NamedNode)userAgentParameter,
                    SyntaxEx.Coalesce((NamedNode)baseUriParameter, SyntaxEx.Literal(baseUri)),
                    SyntaxEx.Coalesce((NamedNode)apiPathParameter, SyntaxEx.Literal(apiPath))));

            var queryAssignment = SyntaxEx.Assignment(
                queryProperty, SyntaxEx.ObjectCreation(Names.QueryAction, (NamedNode)wikiField));

            var ctor = SyntaxEx.ConstructorDeclaration(
                new[] { SyntaxKind.PublicKeyword }, Names.Wiki,
                new[] { userAgentParameter, baseUriParameter, apiPathParameter },
                new StatementSyntax[] { wikiAssignment, queryAssignment });

            var members = new List <MemberDeclarationSyntax>
            {
                wikiField,
                queryProperty,
                pagesSourcePageSizeProperty,
                ctor
            };

            members.AddRange(CreatePageSourceMethods(wikiField));

            var wikiClass = SyntaxEx.ClassDeclaration(Names.Wiki, members);

            Files.Add(
                Names.Wiki,
                SyntaxEx.CompilationUnit(
                    SyntaxEx.NamespaceDeclaration(Namespace, wikiClass),
                    "System", "System.Collections.Generic", "LinqToWiki", "LinqToWiki.Collections",
                    "LinqToWiki.Internals", "LinqToWiki.Parameters", EntitiesNamespace));
        }
Esempio n. 4
0
        /// <summary>
        /// Creates the <c>Page</c> class that used to access prop query modules.
        /// </summary>
        private void CreatePageClass()
        {
            var pageClass = SyntaxEx.ClassDeclaration(SyntaxKind.AbstractKeyword, Names.Page)
                            .AddPrivateConstructor();

            Files.Add(
                Names.Page,
                SyntaxEx.CompilationUnit(
                    SyntaxEx.NamespaceDeclaration(Namespace, pageClass),
                    "System", "System.Collections.Generic", "LinqToWiki", "LinqToWiki.Collections",
                    "LinqToWiki.Internals", EntitiesNamespace));
        }
Esempio n. 5
0
        /// <summary>
        /// Creates the <c>PageResult</c> class that can be used as a named (non-anonymous) type
        /// for the result of PageSource queries.
        /// </summary>
        private void CreatePageResultClass()
        {
            var infoResultClassName = Files["info"].SingleDescendant <ClassDeclarationSyntax>().Identifier.ValueText;
            var typeParameterName   = "TData";
            var dataPropertyType    = SyntaxEx.GenericName("IEnumerable", typeParameterName);

            var infoProperty = SyntaxEx.AutoPropertyDeclaration(
                new[] { SyntaxKind.PublicKeyword }, infoResultClassName, "Info", SyntaxKind.PrivateKeyword);

            var dataProperty = SyntaxEx.AutoPropertyDeclaration(
                new[] { SyntaxKind.PublicKeyword }, dataPropertyType, "Data", SyntaxKind.PrivateKeyword);

            var infoParameter = SyntaxEx.Parameter(infoResultClassName, "info");
            var dataParameter = SyntaxEx.Parameter(dataPropertyType, "data");

            var ctorBody =
                new StatementSyntax[]
            {
                SyntaxEx.Assignment(infoProperty, infoParameter),
                SyntaxEx.Assignment(dataProperty, dataParameter)
            };

            var ctor = SyntaxEx.ConstructorDeclaration(
                new[] { SyntaxKind.PublicKeyword }, Names.PageResult, new[] { infoParameter, dataParameter }, ctorBody);

            var pageResultClass = SyntaxEx.ClassDeclaration(
                Names.PageResult, new[] { SyntaxEx.TypeParameter(typeParameterName) }, null,
                new MemberDeclarationSyntax[] { infoProperty, dataProperty, ctor });

            var pageResultType = SyntaxEx.GenericName(Names.PageResult, typeParameterName);

            var createMethodBody = SyntaxEx.Return(
                SyntaxEx.ObjectCreation(pageResultType, (NamedNode)infoParameter, (NamedNode)dataParameter));

            var createMethod = SyntaxEx.MethodDeclaration(
                new[] { SyntaxKind.PublicKeyword, SyntaxKind.StaticKeyword }, pageResultType, "Create",
                new[] { SyntaxEx.TypeParameter(typeParameterName) }, new[] { infoParameter, dataParameter },
                createMethodBody);

            var pageResultHelperClass = SyntaxEx.ClassDeclaration(SyntaxKind.StaticKeyword, Names.PageResult, createMethod);

            Files.Add(
                Names.PageResult,
                SyntaxEx.CompilationUnit(
                    SyntaxEx.NamespaceDeclaration(Namespace, pageResultClass, pageResultHelperClass),
                    "System.Collections.Generic", EntitiesNamespace));
        }
Esempio n. 6
0
        /// <summary>
        /// Creates the <c>QueryAction</c> class that is used to access non-prop query modules.
        /// </summary>
        private void CreateQueryActionClass()
        {
            var wikiField = SyntaxEx.FieldDeclaration(
                new[] { SyntaxKind.PrivateKeyword, SyntaxKind.ReadOnlyKeyword }, Names.WikiInfo, "m_wiki");

            var wikiParameter = SyntaxEx.Parameter(Names.WikiInfo, "wiki");

            var ctor = SyntaxEx.ConstructorDeclaration(
                new[] { SyntaxKind.InternalKeyword }, Names.QueryAction,
                new[] { wikiParameter },
                new StatementSyntax[] { SyntaxEx.Assignment(wikiField, wikiParameter) });

            var queryActionClass = SyntaxEx.ClassDeclaration(Names.QueryAction, wikiField, ctor);

            Files.Add(
                Names.QueryAction, SyntaxEx.CompilationUnit(
                    SyntaxEx.NamespaceDeclaration(Namespace, queryActionClass),
                    "System", "System.Collections.Generic", "LinqToWiki", "LinqToWiki.Collections",
                    "LinqToWiki.Parameters", "LinqToWiki.Internals", EntitiesNamespace));
        }
Esempio n. 7
0
        /// <summary>
        /// Creates methods to create <see cref="ListSourceBase{TPage}"/> page sources
        /// for the <c>Wiki</c> class.
        /// </summary>
        private static IEnumerable <MethodDeclarationSyntax> CreatePageSourceMethods(FieldDeclarationSyntax wikiField)
        {
            var pageSources =
                new[]
            {
                new { type = "string", name = "titles", sourceType = typeof(TitlesSource <>) },
                new { type = "long", name = "pageIds", sourceType = typeof(PageIdsSource <>) },
                new { type = "long", name = "revIds", sourceType = typeof(RevIdsSource <>) }
            };

            foreach (var pageSource in pageSources)
            {
                string sourceTypeName = pageSource.sourceType.Name;
                sourceTypeName = sourceTypeName.Substring(0, sourceTypeName.IndexOf('`'));

                var parameterVersions =
                    new[]
                {
                    SyntaxEx.Parameter(SyntaxEx.GenericName("IEnumerable", pageSource.type), pageSource.name),
                    SyntaxEx.Parameter(
                        pageSource.type + "[]", pageSource.name, modifiers: new[] { SyntaxKind.ParamsKeyword })
                };

                foreach (var parameter in parameterVersions)
                {
                    var returnStatement = SyntaxEx.Return(
                        SyntaxEx.ObjectCreation(
                            SyntaxEx.GenericName(sourceTypeName, Names.Page),
                            (NamedNode)wikiField, (NamedNode)parameter));

                    yield return(SyntaxEx.MethodDeclaration(
                                     new[] { SyntaxKind.PublicKeyword }, SyntaxEx.GenericName("PagesSource", Names.Page),
                                     "Create" + sourceTypeName, new[] { parameter }, returnStatement));
                }
            }
        }
 /// <summary>
 /// Returns the given class with a private parameterless constructor added.
 /// </summary>
 public static ClassDeclarationSyntax AddPrivateConstructor(this ClassDeclarationSyntax classDeclaration)
 {
     return(classDeclaration.AddMembers(
                SyntaxEx.ConstructorDeclaration(
                    new[] { SyntaxKind.PrivateKeyword }, classDeclaration.Identifier.ValueText)));
 }
 public static TNode WithDocumentationSummary <TNode>(this TNode node, string summary) where TNode : SyntaxNode
 {
     return(node.WithLeadingTrivia(Syntax.Trivia(SyntaxEx.DocumentationComment(SyntaxEx.DocumentationSummary(summary)))));
 }
Esempio n. 10
0
        /// <summary>
        /// Returns an expression that converts to an <see cref="EnumParameterType"/>.
        /// </summary>
        private ExpressionSyntax CreateEnumConverter(EnumParameterType type, string moduleName, ExpressionSyntax value)
        {
            var typeName = m_enumTypeNames[moduleName, type];

            return(SyntaxEx.ObjectCreation(typeName, value));
        }
Esempio n. 11
0
        /// <summary>
        /// Creates a type representing the given <see cref="EnumParameterType"/>.
        /// </summary>
        private string GenerateType(EnumParameterType enumType, string propertyName, string moduleName)
        {
            string typeName = moduleName + propertyName;

            Dictionary <EnumParameterType, string> moduleTypes;

            if (m_enumTypeNames.TryGetValue(moduleName, out moduleTypes))
            {
                int i = 2;
                while (moduleTypes.Values.Contains(typeName))
                {
                    typeName = moduleName + propertyName + i++;
                }
            }

            var fixedMemberNameMapping = new TupleList <string, string>();
            var memberNames            = new List <string>();

            foreach (var name in enumType.Values)
            {
                var fixedName = FixEnumMemberName(name);

                if (name != fixedName.TrimStart('@'))
                {
                    fixedMemberNameMapping.Add(fixedName, name);
                }

                memberNames.Add(fixedName);
            }

            var members = enumType.Values.Select(
                memberName =>
                SyntaxEx.FieldDeclaration(
                    new[] { SyntaxKind.PublicKeyword, SyntaxKind.StaticKeyword, SyntaxKind.ReadOnlyKeyword },
                    typeName, FixEnumMemberName(memberName),
                    SyntaxEx.ObjectCreation(typeName, SyntaxEx.Literal(memberName))));

            var constructorParameter = SyntaxEx.Parameter("string", "value");
            var contructor           = SyntaxEx.ConstructorDeclaration(
                new[] { SyntaxKind.InternalKeyword }, typeName, new[] { constructorParameter },
                constructorInitializer: SyntaxEx.BaseConstructorInitializer((NamedNode)constructorParameter));

            var firstParameter  = SyntaxEx.Parameter(typeName, "first");
            var secondParameter = SyntaxEx.Parameter(typeName, "second");

            Func <SyntaxKind, ExpressionSyntax, OperatorDeclarationSyntax> createOperator =
                (op, result) => SyntaxEx.OperatorDeclaration(
                    Syntax.ParseTypeName("bool"), op,
                    new[] { firstParameter, secondParameter },
                    new[] { SyntaxEx.Return(result) });

            var equalsExpression = SyntaxEx.Invocation(
                Syntax.IdentifierName("Equals"), (NamedNode)firstParameter, (NamedNode)secondParameter);
            var notEqualsExpression = SyntaxEx.Not(equalsExpression);

            var equalsOperator    = createOperator(SyntaxKind.EqualsEqualsToken, equalsExpression);
            var notEqualsOPerator = createOperator(SyntaxKind.ExclamationEqualsToken, notEqualsExpression);

            var equalsParameter = SyntaxEx.Parameter("object", "obj");
            var equalsMethod    = SyntaxEx.MethodDeclaration(
                new[] { SyntaxKind.PublicKeyword, SyntaxKind.OverrideKeyword }, "bool", "Equals",
                new[] { equalsParameter },
                SyntaxEx.Return(
                    SyntaxEx.Invocation(SyntaxEx.MemberAccess("base", "Equals"), (NamedNode)equalsParameter)));

            var getHashCodeMethod = SyntaxEx.MethodDeclaration(
                new[] { SyntaxKind.PublicKeyword, SyntaxKind.OverrideKeyword }, "int", "GetHashCode",
                new ParameterSyntax[0],
                SyntaxEx.Return(SyntaxEx.Invocation(SyntaxEx.MemberAccess("base", "GetHashCode"))));

            var classDeclaration =
                SyntaxEx.ClassDeclaration(typeName, Syntax.ParseTypeName("StringValue"), contructor)
                .AddMembers(equalsOperator, notEqualsOPerator, equalsMethod, getHashCodeMethod)
                .AddMembers(members.ToArray <MemberDeclarationSyntax>());

            var namespaceDeclaration = m_wiki.Files[Wiki.Names.Enums].SingleDescendant <NamespaceDeclarationSyntax>();

            m_wiki.Files[Wiki.Names.Enums] = m_wiki.Files[Wiki.Names.Enums].ReplaceNode(
                namespaceDeclaration, namespaceDeclaration.AddMembers(classDeclaration));

            m_enumTypeNames.Add(moduleName, enumType, typeName);

            return(typeName);
        }