/// <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; }
/// <summary> /// Returns a source code type name for the given <see cref="EnumParameterType"/>. /// </summary> private string GetEnumTypeName( EnumParameterType enumType, string propertyName, string moduleName, bool multi, bool useItemOrCollection) { string result; if (!m_enumTypeNames.TryGetValue(moduleName, enumType, out result)) result = GenerateType(enumType, propertyName, moduleName); if (multi) result = string.Format(useItemOrCollection ? "ItemOrCollection<{0}>" : "IEnumerable<{0}>", result); return result; }
/// <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); }