/// <summary> /// Generate the code from the custom tool. /// </summary> /// <param name="wszInputFilePath">The name of the input file.</param> /// <param name="bstrInputFileContents">The contents of the input file.</param> /// <param name="wszDefaultNamespace">The namespace FluidTrade.Core.Client the generated code.</param> /// <param name="pbstrOutputFileContents">The generated code.</param> /// <param name="pbstrOutputFileContentSize">The buffer size of the generated code.</param> /// <param name="pGenerateProgress">An indication of the tools progress.</param> /// <returns>0 indicates the tool handled the command.</returns> public int Generate(string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace, IntPtr[] rgbOutputFileContents, out uint pcbOutput, IVsGeneratorProgress pGenerateProgress) { // Throw an execption if there is nothing to process. if (bstrInputFileContents == null) { throw new ArgumentNullException(bstrInputFileContents); } // This schema describes the data model that is to be generated. PresentationSchema presentationSchema = new PresentationSchema(wszInputFilePath, bstrInputFileContents); // This is where all the work is done to translate the input schema into the CodeDOM for the data model and the CodeDOM // for the interface to that data model. CodeCompileUnit codeCompileUnit = new CodeCompileUnit(); // This creates an association between an XAML namespace and the CLR namespace in the target assembly. codeCompileUnit.AssemblyCustomAttributes.Add(new CodeAttributeDeclaration( new CodeTypeReference(typeof(System.Windows.Markup.XmlnsDefinitionAttribute)), new CodeAttributeArgument(new CodePrimitiveExpression(presentationSchema.SourceNamespace)), new CodeAttributeArgument(new CodePrimitiveExpression(presentationSchema.TargetNamespace)))); // Most of the work to create the target assembly takes place in creating the namespace. codeCompileUnit.Namespaces.Add(new Namespace(presentationSchema)); // If a handler was provided for the generation of the code, then call it with an update. if (pGenerateProgress != null) { pGenerateProgress.Progress(50, 100); } // This will generate the target source code in the language described by the CodeDOM provider. StringWriter stringWriter = new StringWriter(); //There is no elegant way to generate preprocessor directives through CodeDom. All the solutions //require string replacement after the fact. So not elegant but effective. //This pragma suppresses build errors from uncommented files - which generated files are. this.codeProvider.GenerateCodeFromCompileUnit(codeCompileUnit, stringWriter, this.codeGeneratorOptions); // If a handler was provided for the progress, then let it know that the task is complete. if (pGenerateProgress != null) { pGenerateProgress.Progress(100, 100); } // This will pack the generated buffer into an unmanaged block of memory that can be passed back to Visual Studio. byte[] generatedBuffer = System.Text.Encoding.UTF8.GetBytes(stringWriter.ToString()); rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(generatedBuffer.Length); Marshal.Copy(generatedBuffer, 0, rgbOutputFileContents[0], generatedBuffer.Length); pcbOutput = (uint)generatedBuffer.Length; // At this point the code generation was a success. return(VSConstants.S_OK); }
/// <summary> /// The description of a class. /// </summary> /// <param name="presentationSchema">The PresentationSchema to which this class belongs.</param> /// <param name="xmlSchemaComplexType">The XML Schema description of the class.</param> public ClassSchema(PresentationSchema presentationSchema, XmlSchemaComplexType xmlSchemaComplexType) { // Initialize the object. this.name = xmlSchemaComplexType.QualifiedName.Name; this.presentationSchema = presentationSchema; this.propertyList = new List <PropertySchema>(); this.targetNamespace = xmlSchemaComplexType.QualifiedName.Namespace; this.type = xmlSchemaComplexType.QualifiedName.ToString(); // This will create the list of properties of this type. if (xmlSchemaComplexType.Particle is XmlSchemaSequence) { XmlSchemaSequence xmlSchemaSequence = xmlSchemaComplexType.Particle as XmlSchemaSequence; foreach (XmlSchemaObject item in xmlSchemaSequence.Items) { if (item is XmlSchemaElement) { this.propertyList.Add(new PropertySchema(this, item as XmlSchemaElement)); } } } // This will create and initialize a description of the constructor for the class from the XML Schema extensions. this.constructorSchema = new ConstructorSchema(this); if (xmlSchemaComplexType.Annotation != null) { foreach (XmlSchemaObject xmlSchemaObject in xmlSchemaComplexType.Annotation.Items) { if (xmlSchemaObject is XmlSchemaAppInfo) { XmlSchemaAppInfo xmlSchemaAppInfo = xmlSchemaObject as XmlSchemaAppInfo; foreach (XmlNode constructorNode in xmlSchemaAppInfo.Markup) { if (QualifiedName.Constructor == new XmlQualifiedName(constructorNode.LocalName, constructorNode.NamespaceURI)) { this.constructorSchema = new ConstructorSchema(this, constructorNode); } } } } } }
/// <summary> /// Generates the namespace used by the Presentation classes. /// </summary> /// <param name="presentationSchema">A description of the presentation layer.</param> public Namespace(PresentationSchema presentationSchema) { //namespace FluidTrade.Sandbox.WorkingOrderHeader //{ this.Name = presentationSchema.TargetNamespace; // Import Namespaces foreach (string import in presentationSchema.Imports) { this.Imports.Add(new CodeNamespaceImport(import)); } // Classes foreach (ClassSchema classSchema in presentationSchema.Classes) { if (classSchema.TargetNamespace == this.Name) { this.Types.Add(new PresentationClass.PresentationClass(classSchema)); } } //} }