예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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);
                            }
                        }
                    }
                }
            }
        }
예제 #3
0
        /// <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));
                }
            }

            //}
        }