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>(); }
/// <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); }
/// <summary> /// Gets parameters that are used in all queries for this module. /// </summary> protected abstract IEnumerable<Tuple<string, string>> GetBaseParameters(Module module);
/// <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); }
protected override IEnumerable<PropertyGroup> GetPropertyGroups(Module module) { return new[] { SpecialProperties }.Concat(base.GetPropertyGroups(module)); }