protected override void GenerateInternal(Module module)
        {
            m_selectClassName = ClassNameBase + "Select";
            m_whereClassName = ClassNameBase + "Where";
            m_orderByClassName = ClassNameBase + "OrderBy";

            var parameters = module.Parameters.ToList();

            var sortParameters = RemoveAndReturnByNames(parameters, "sort", "dir");

            var methodParameters = parameters.RemoveAndReturn(p => p.Required);

            // don't belong anywhere, are used in a special way
            RemoveAndReturnByNames(parameters, "continue", "offset", "limit", "prop");

            var whereParameters = parameters;

            var selectClass = GenerateSelect(module.PropertyGroups, module.Name == "revisions");
            var whereClass = GenerateWhere(whereParameters);
            var orderByClass = GenerateOrderBy(sortParameters, module.PropertyGroups.SelectMany(g => g.Properties));

            var codeUnit = SyntaxEx.CompilationUnit(
                SyntaxEx.NamespaceDeclaration(Wiki.EntitiesNamespace, selectClass, whereClass, orderByClass),
                "System", "System.Globalization", "System.Xml.Linq", "LinqToWiki", "LinqToWiki.Collections",
                "LinqToWiki.Internals");

            Wiki.Files.Add(ClassNameBase, codeUnit);

            string queryTypeName = "WikiQuery";
            var queryTypeGenericParameters = new List<string> { m_whereClassName, m_selectClassName };

            if (orderByClass != null)
            {
                queryTypeName += "Sortable";
                queryTypeGenericParameters.Insert(1, m_orderByClassName);
            }

            if (module.Generator)
            {
                queryTypeName += "Generator";
                queryTypeGenericParameters.Insert(0, Wiki.Names.Page);
            }

            m_queryType = SyntaxEx.GenericName(queryTypeName, queryTypeGenericParameters);

            SortType? sortType = null;

            var dirParameter = sortParameters.SingleOrDefault(p => p.Name == "dir");

            if (dirParameter != null)
            {
                var type = (EnumParameterType)dirParameter.Type;
                if (type.Values.Any(x => x == "ascending"))
                    sortType = SortType.Ascending;
                else if (type.Values.Any(x => x == "newer"))
                    sortType = SortType.Newer;
            }

            GenerateMethod(module, methodParameters, m_selectClassName, m_selectProps, MethodClassName, false, sortType);
        }
        /// <summary>
        /// Creates a field that holds <see cref="QueryTypeProperties{T}"/> for the module.
        /// </summary>
        protected FieldDeclarationSyntax CreatePropertiesField(
            Module module, string resultClassName, FieldDeclarationSyntax propsField, SortType? sortType)
        {
            var queryTypePropertiesType = SyntaxEx.GenericName("QueryTypeProperties", resultClassName);

            var propertiesInitializer = SyntaxEx.ObjectCreation(
                queryTypePropertiesType,
                SyntaxEx.Literal(module.Name),
                SyntaxEx.Literal(module.Prefix),
                module.QueryType == null
                    ? (ExpressionSyntax)SyntaxEx.NullLiteral()
                    : SyntaxEx.MemberAccess("QueryType", module.QueryType.ToString()),
                sortType == null
                    ? (ExpressionSyntax)SyntaxEx.NullLiteral()
                    : SyntaxEx.MemberAccess("SortType", sortType.ToString()),
                CreateTupleListExpression(GetBaseParameters(module)),
                propsField == null ? (ExpressionSyntax)SyntaxEx.NullLiteral() : (NamedNode)propsField,
                resultClassName == "object"
                    ? (ExpressionSyntax)SyntaxEx.LambdaExpression("_", SyntaxEx.NullLiteral())
                    : SyntaxEx.MemberAccess(resultClassName, "Parse"));

            return SyntaxEx.FieldDeclaration(
                new[] { SyntaxKind.PrivateKeyword, SyntaxKind.StaticKeyword, SyntaxKind.ReadOnlyKeyword },
                queryTypePropertiesType, ClassNameBase + "Properties", propertiesInitializer);
        }
        protected override void GenerateInternal(Module module)
        {
            ResultClassName = ClassNameBase + "Result";

            var resultType = GenerateResultClass(GetPropertyGroups(module));

            if (resultType == null)
            {
                ResultClassName = "object";
                m_voidResult = true;
            }
            else
            {
                var codeUnit = SyntaxEx.CompilationUnit(
                    SyntaxEx.NamespaceDeclaration(Wiki.EntitiesNamespace, resultType),
                    "System", "System.Linq", "System.Globalization", "System.Xml.Linq", "LinqToWiki",
                    "LinqToWiki.Internals");

                Wiki.Files.Add(ClassNameBase, codeUnit);
            }

            m_listResult = module.ListResult;

            GenerateMethod(module);
        }
        /// <summary>
        /// Creates the property that can used to access the information from the given module.
        /// </summary>
        private PropertyDeclarationSyntax CreateProperty(Module module)
        {
            var summary = SyntaxEx.DocumentationSummary(module.Description);

            return SyntaxEx.AutoPropertyDeclaration(
                new[] { SyntaxKind.PublicKeyword, SyntaxKind.AbstractKeyword }, GenerateMethodResultType(),
                ClassNameBase, isAbstract: true, setModifier: SyntaxKind.PrivateKeyword)
                .WithLeadingTrivia(SyntaxFactory.Trivia(SyntaxEx.DocumentationComment(summary)));
        }
        protected override void GenerateMethod(Module module)
        {
            var propsField = CreatePropsField(GetPropertyGroups(module));

            var propertiesField = CreatePropertiesField(module, ResultClassName, propsField, null);

            var moduleProperty = CreateProperty(module);

            AddMembersToClass(Wiki.Names.Page, propsField, propertiesField, moduleProperty);
        }
        /// <summary>
        /// Generates code for the module.
        /// </summary>
        public void Generate(Module module)
        {
            if (module.PropertyGroups == null)
                return;

            ClassNameBase = module.Name;

            GenerateInternal(module);

            Wiki.ModuleFinished();
        }
 protected override IEnumerable<Tuple<string, string>> GetBaseParameters(Module module)
 {
     return Wiki.QueryBaseParameters.Concat(
         new TupleList<string, string>
         {
             { module.QueryType.ToString().ToLowerInvariant(), module.Name },
             {
                 module.Prefix + "prop",
                 module.PropertyGroups.Select(g => g.Name).Where(n => n != string.Empty).ToQueryString()
             }
         });
 }
 /// <summary>
 /// Returns the property groups of the module.
 /// </summary>
 protected virtual IEnumerable<PropertyGroup> GetPropertyGroups(Module module)
 {
     return module.PropertyGroups;
 }
 protected override IEnumerable<Tuple<string, string>> GetBaseParameters(Module module)
 {
     return new TupleList<string, string> { { "action", module.Name } };
 }
 protected override IEnumerable<Tuple<string, string>> GetBaseParameters(Module module)
 {
     return new TupleList<string, string>();
 }
Beispiel #11
0
 /// <summary>
 /// Actually generates code specific to the module.
 /// </summary>
 protected abstract void GenerateInternal(Module module);
 protected override void GenerateMethod(Module module)
 {
     GenerateMethod(
         module, module.Parameters.Where(p => p.Name != "prop"), ResultClassName, null, Wiki.Names.QueryAction,
         true, null);
 }
Beispiel #13
0
 /// <summary>
 /// Gets parameters that are used in all queries for this module.
 /// </summary>
 protected abstract IEnumerable<Tuple<string, string>> GetBaseParameters(Module module);
Beispiel #14
0
        /// <summary>
        /// Creates an entry method, that is used to execute query for normal modules
        /// or that can be used as a base for a query for query modules.
        /// </summary>
        protected void GenerateMethod(
            Module module, IEnumerable<Parameter> methodParameters, string resultClassName,
            FieldDeclarationSyntax propsField, string fileName, bool nullableParameters, SortType? sortType)
        {
            var propertiesField = CreatePropertiesField(module, resultClassName, propsField, sortType);

            ExpressionSyntax queryParameters = SyntaxEx.Invocation(
                SyntaxEx.MemberAccess("QueryParameters", SyntaxEx.GenericName("Create", resultClassName)));

            var queryParametersLocal = SyntaxEx.LocalDeclaration("var", "queryParameters", queryParameters);

            var documentationElements = new List<XmlElementSyntax>();

            var summary = SyntaxEx.DocumentationSummary(module.Description);
            documentationElements.Add(summary);

            var parameters = new List<ParameterSyntax>();
            IList<StatementSyntax> statements = new List<StatementSyntax>();

            statements.Add(queryParametersLocal);

            methodParameters = methodParameters.Where(p => !p.Deprecated)
                .OrderByDescending(p => p.Required);

            foreach (var methodParameter in methodParameters)
            {
                var nullable = nullableParameters && !methodParameter.Required;
                var typeName = Wiki.TypeManager.GetTypeName(methodParameter, ClassNameBase, nullable, false);
                var parameterName = GetPropertyName(methodParameter.Name);
                var parameter = SyntaxEx.Parameter(typeName, parameterName, nullable ? SyntaxEx.NullLiteral() : null);

                parameters.Add(parameter);

                ExpressionSyntax valueExpression = (NamedNode)parameter;

                if (nullable && typeName.EndsWith("?"))
                    valueExpression = SyntaxEx.MemberAccess(valueExpression, "Value");

                var queryParametersAssignment = SyntaxEx.Assignment(
                    queryParametersLocal, SyntaxEx.Invocation(
                        SyntaxEx.MemberAccess(queryParametersLocal, "AddSingleValue"),
                        SyntaxEx.Literal(methodParameter.Name),
                        SyntaxEx.Invocation(SyntaxEx.MemberAccess(valueExpression, "ToQueryString"))));

                if (nullable)
                {
                    var assignmentWithCheck = SyntaxEx.If(
                        SyntaxEx.NotEquals((NamedNode)parameter, SyntaxEx.NullLiteral()), queryParametersAssignment);

                    statements.Add(assignmentWithCheck);
                }
                else
                    statements.Add(queryParametersAssignment);

                var parameterDocumentation = SyntaxEx.DocumentationParameter(
                    parameterName, new System.Xml.Linq.XText(methodParameter.Description).ToString());

                documentationElements.Add(parameterDocumentation);
            }

            statements = GenerateMethodBody(
                SyntaxEx.ObjectCreation(
                    SyntaxEx.GenericName("QueryProcessor", resultClassName),
                    Syntax.IdentifierName("m_wiki"),
                    (NamedNode)propertiesField), (NamedNode)queryParametersLocal, statements);

            var modifiers = new List<SyntaxKind> { SyntaxKind.PublicKeyword };
            if (statements == null)
                modifiers.Add(SyntaxKind.AbstractKeyword);

            var method = SyntaxEx.MethodDeclaration(
                modifiers, GenerateMethodResultType(), ClassNameBase, parameters, statements)
                .WithLeadingTrivia(Syntax.Trivia(SyntaxEx.DocumentationComment(documentationElements)));

            AddMembersToClass(fileName, propertiesField, method);
        }
 protected override IEnumerable<Tuple<string, string>> GetBaseParameters(Module module)
 {
     return Wiki.QueryBaseParameters.Concat(
         new TupleList<string, string> { { module.QueryType.ToString().ToLowerInvariant(), module.Name } });
 }
 /// <summary>
 /// Generates the method that can be called to use this module.
 /// </summary>
 protected virtual void GenerateMethod(Module module)
 {
     GenerateMethod(module, module.Parameters, ResultClassName, null, Wiki.Names.Wiki, true, null);
 }
Beispiel #17
0
 protected override IEnumerable<PropertyGroup> GetPropertyGroups(Module module)
 {
     return new[] { SpecialProperties }.Concat(base.GetPropertyGroups(module));
 }