private CodeAttributeDeclaration ReadAnnotation(Annotation annotation, CodeNamespace nameSpace) { var declaration = WellKnownAnnotations[annotation.Name]; if (declaration != null) { return(declaration); } var memberName = annotation.Name; var fqt = new FullyQualifiedType(memberName); var attributeName = fqt.TypeName + "Attribute"; var attributeNamespace = compileUnit.Namespaces() .FirstOrDefault(n => n.Name == fqt.Namespace.Name); if (attributeNamespace == null) { attributeNamespace = fqt.Namespace ?? nameSpace; AddNamespace(attributeNamespace); } ImportNamespace(attributeNamespace.Name, nameSpace); // Declare the Attribute only if it doesn't exist already. var exists = attributeNamespace.Types() .Any(a => a.Name == attributeName); if (!exists) { var typeDeclaration = CodeTypeContainer.CreateAttribute(attributeName); var valueProperty = Declare.Property("Value", CodeTypeContainer.Create(typeof(string)).Reference); var valueParameter = valueProperty.AsParameter(); var constructor = new CodeConstructor(); constructor.Attributes = MemberAttributes.Public; constructor.Parameters.Add(valueParameter); constructor.Statements.Add(new CodeAssignStatement(valueProperty.Reference(), valueParameter.Reference())); typeDeclaration.Members.Add(constructor); typeDeclaration.Members.Add(valueProperty); attributeNamespace.Types.Add(typeDeclaration); ImportNamespaces(typeDeclaration.RequiredImports); } return(Declare.Attribute(fqt.TypeName, annotation.Value)); }
public void GenerateContract(CodeCompileUnit compileUnit) { //Console.WriteLine("IN GENERATE CONTRACT"); foreach (var ns in compileUnit.Namespaces()) { //Console.WriteLine("CODEDOM NS = " + ns.Name); foreach (var typeDeclaration in ns.Types()) { var qualifiedName = GetXmlQualifiedName(typeDeclaration); if (qualifiedName == null) { continue; } //Console.WriteLine("\tCODEDOM TYPE = " + typeDeclaration.Name); var schemaType = GetSchemaType(qualifiedName); if (schemaType == null) { throw new Exception("TODO"); } var xmlComment = GetDocumentation(schemaType.Annotation); if (xmlComment != null) { typeDeclaration.Comments.Clear(); XmlCommentsImporter.AddXmlComment(typeDeclaration, xmlComment, new ImportOptions { Format = XmlCommentFormat.Portable }); } if (typeDeclaration.IsEnum) { var docByMember = GetEnumerationDocumentationByMember(schemaType); foreach (CodeTypeMember member in typeDeclaration.Members) { if (docByMember.TryGetValue(member.Name, out var memberDoc)) { member.Comments.Clear(); XmlCommentsImporter.AddXmlComment(member, memberDoc, new ImportOptions { Format = XmlCommentFormat.Portable }); } } } } } }
void IDataContractGenerationExtension.GenerateContract(CodeCompileUnit compileUnit) { foreach (var ns in compileUnit.Namespaces()) { foreach (var typeDeclaration in ns.Types()) { var dataContractAttribute = typeDeclaration.GetDataContractAttribute(); if (dataContractAttribute != null) { var dataContractNameArgument = dataContractAttribute.FindArgumentByName("Name"); if (dataContractNameArgument != null) { var dataContractName = dataContractNameArgument.GetStringValue(); if (dataContractName != null && dataContractName == typeDeclaration.Name) { dataContractAttribute.Arguments.Remove(dataContractNameArgument); } } } } } }
void IDataContractGenerationExtension.GenerateContract(CodeCompileUnit compileUnit) { if (compileUnit == null) { throw new ArgumentNullException(nameof(compileUnit)); } foreach (var typeRenameEntry in _typeRenames) { var originalTypeName = (CodeTypeName)typeRenameEntry.Key; var newTypeName = (CodeTypeName)typeRenameEntry.Value; var typeDeclaration = compileUnit.FindTypeDeclaration(originalTypeName); if (typeDeclaration == null) { throw new Exception($"Type '{originalTypeName}' does not exist."); } // lookup the original namespace var originalNamespace = compileUnit.Namespaces().Single(n => n.Name == originalTypeName.Namespace); // if both the original and new type name are in the same namespace, then we need to // ensure the new type name doesn't already exist in the original namespace if (originalTypeName.Namespace == newTypeName.Namespace) { if (originalNamespace.Types().SingleOrDefault(t => t.Name == newTypeName.Type) != null) { throw new Exception($"Type '{newTypeName}' already exists."); } } else { var newNamespace = compileUnit.Namespaces().SingleOrDefault(n => n.Name == newTypeName.Namespace); if (newNamespace == null) { newNamespace = new CodeNamespace(newTypeName.Namespace); compileUnit.Namespaces.Add(newNamespace); } else { if (newNamespace.Types().Any(p => p.Name == newTypeName.Type)) { throw new Exception($"Type '{newTypeName}' already exists."); } } // add the type to the new namespace newNamespace.Types.Add(typeDeclaration); // remove the type from the original namespace originalNamespace.Types.Remove(typeDeclaration); // remove the original namespace if we just removed the last type from it if (originalNamespace.Types.Count == 0) { compileUnit.Namespaces.Remove(originalNamespace); } } // modify the name of the type typeDeclaration.Name = newTypeName.Type; var originalFullTypeName = originalTypeName.ToString(); var newFullTypeName = newTypeName.ToString(); // Updating a type declaration in CodeDOM does not update type parameters of that type foreach (var ns in compileUnit.Namespaces()) { foreach (CodeTypeDeclaration type in ns.Types) { foreach (CodeTypeMember member in type.Members) { if (member is CodeMemberField field) { if (field.Type.BaseType == originalFullTypeName) { field.Type.BaseType = newFullTypeName; } else { foreach (CodeTypeReference typeArgument in field.Type.TypeArguments) { if (typeArgument.BaseType == originalFullTypeName) { typeArgument.BaseType = newFullTypeName; } } } continue; } if (member is CodeMemberProperty property) { if (property.Type.BaseType == originalFullTypeName) { property.Type.BaseType = newFullTypeName; } } } } } } }