示例#1
0
        /// <summary>
        /// Reports a warning or error message to the VS IDE.
        /// </summary>
        /// <param name="isError">Indicates if the message is an error or a warning.</param>
        /// <param name="line">The line number.</param>
        /// <param name="column">The column number.</param>
        /// <param name="message">The message.</param>
        /// <param name="arguments">The optional arguments to add to the message if <paramref name="message"/> contains formatting placeholders.</param>
        /// <returns><c>true</c>, if error reporting succeeded; <c>false</c>, otherwise.</returns>
        private bool ReportMessage(bool isWarning, int line, int column, string message)
        {
            message = !string.IsNullOrEmpty(message) ? message : ("Unknown " + (isWarning ? "warning" : "error"));
            line    = line >= 0 ? line : 0;
            column  = column >= 0 ? column : 0;

            uint mLine   = 0;
            uint mColumn = 0;

            ProgressReporter.MapLocation(line, column, out mLine, out mColumn);
            int vsStatus = 0;
            int level    = (isWarning ? 1 : 0);

            this.bridge.GeneratorError(level, 0, message, mLine, mColumn);
            return(ProgressReporter.MapStatus(vsStatus));
        }
        private void PrintFlags(
            string file,
            IEnumerable <Flag> flags,
            ProgressReporter reporter)
        {
            foreach (var f in flags)
            {
                switch (f.Severity)
                {
                case SeverityKind.Info:
                    reporter.Info(
                        file,
                        f.Span.StartLine,
                        f.Span.StartCol,
                        string.Format("{0} (Code {1})", f.Message, f.Code));
                    break;

                case SeverityKind.Warning:
                    reporter.Warning(
                        file,
                        f.Span.StartLine,
                        f.Span.StartCol,
                        string.Format("{0} (Code {1})", f.Message, f.Code));
                    break;

                case SeverityKind.Error:
                    reporter.Error(
                        file,
                        f.Span.StartLine,
                        f.Span.StartCol,
                        string.Format("{0} (Code {1})", f.Message, f.Code));
                    break;

                default:
                    throw new NotImplementedException();
                }
            }
        }
        /// <summary>
        /// Generates the specified WSZ input file path.
        /// </summary>
        /// <param name="wszInputFilePath">The input file path.</param>
        /// <param name="bstrInputFileContents">The input file contents.</param>
        /// <param name="wszDefaultNamespace">The default namespace.</param>
        /// <param name="outputFileContents">The encoded byte array containing the generated content.</param>
        /// <param name="pcbOutput">The length of the content array <paramref name="outputFileContents"/>.</param>
        /// <param name="pGenerateProgress">The callback to invoke to report on the progress of the generation.</param>
        /// <returns></returns>
        int IVsSingleFileGenerator.Generate(
            string wszInputFilePath,
            string bstrInputFileContents,
            string wszDefaultNamespace,
            IntPtr[] rgbOutputFileContents,
            out uint pcbOutput,
            IVsGeneratorProgress pGenerateProgress)
        {
            pcbOutput = 0;
            ProgressReporter reporter = new ProgressReporter(pGenerateProgress);
            var writer = new StringWriter();

            if (Compile(wszInputFilePath, wszDefaultNamespace, writer, reporter))
            {
                writer.Close();
                EncodeStubOutput(writer.ToString(), rgbOutputFileContents, out pcbOutput);
                return(VSConstants.S_OK);
            }
            else
            {
                return(VSConstants.E_FAIL);
            }
        }
        private void PrintFlags(
            IEnumerable <Tuple <AST <Microsoft.Formula.API.Nodes.Program>, Flag> > flags,
            ProgressReporter reporter)
        {
            foreach (var f in flags)
            {
                switch (f.Item2.Severity)
                {
                case SeverityKind.Info:
                    reporter.Info(
                        f.Item1.Node.Name.ToString(),
                        f.Item2.Span.StartLine,
                        f.Item2.Span.StartCol,
                        string.Format("{0} (Code {1})", f.Item2.Message, f.Item2.Code));
                    break;

                case SeverityKind.Warning:
                    reporter.Warning(
                        f.Item1.Node.Name.ToString(),
                        f.Item2.Span.StartLine,
                        f.Item2.Span.StartCol,
                        string.Format("{0} (Code {1})", f.Item2.Message, f.Item2.Code));
                    break;

                case SeverityKind.Error:
                    reporter.Error(
                        f.Item1.Node.Name.ToString(),
                        f.Item2.Span.StartLine,
                        f.Item2.Span.StartCol,
                        string.Format("{0} (Code {1})", f.Item2.Message, f.Item2.Code));
                    break;

                default:
                    throw new NotImplementedException();
                }
            }
        }
        public bool Compile(
            string filename,
            string nameSpace,
            TextWriter writer,
            ProgressReporter reporter)
        {
            GenerateConfig config;

            if (!configMap.TryGetValue(filename, out config))
            {
                config = new GenerateConfig();
            }

            var env = new Env();

            try
            {
                InstallResult ires;
                var           progName = new ProgramName(filename);
                env.Install(filename, out ires);
                PrintFlags(ires.Flags, reporter);
                if (!ires.Succeeded)
                {
                    return(false);
                }

                AST <API.Nodes.Program> program = null;
                foreach (var touched in ires.Touched)
                {
                    if (touched.Program.Node.Name.Equals(progName))
                    {
                        program = touched.Program;
                        break;
                    }
                }

                if (program == null)
                {
                    reporter.Error(filename, 0, 0, "Could not find input file");
                    return(false);
                }

                string name;
                string modName     = null;
                var    moduleQuery = new NodePred[] { NodePredFactory.Instance.Star, NodePredFactory.Instance.Module };
                program.FindAll(
                    moduleQuery,
                    (ch, n) =>
                {
                    if (n.TryGetStringAttribute(AttributeKind.Name, out name))
                    {
                        if (modName == null)
                        {
                            modName = name;
                        }
                        else
                        {
                            reporter.Warning(
                                filename,
                                n.Span.StartLine,
                                n.Span.StartCol,
                                string.Format("Code will only be generated for module {0}; ignoring module {1}.", modName, name));
                        }
                    }
                });

                if (modName == null)
                {
                    reporter.Warning(filename, 0, 0, "Could not find any modules in input file.");
                    return(true);
                }

                var opts = new GeneratorOptions(
                    GeneratorOptions.Language.CSharp,
                    config.IsThreadSafe,
                    config.IsNewOnly,
                    modName,
                    nameSpace);

                Task <GenerateResult> gres;
                env.Generate(progName, modName, writer, opts, out gres);
                gres.Wait();
                PrintFlags(filename, gres.Result.Flags, reporter);
                return(gres.Result.Succeeded);
            }
            catch (Exception e)
            {
                reporter.Error(filename, 0, 0, e.Message);
                return(false);
            }
        }