public static CompilerMessage[] ParseCompilerOutput(NodeFinishedMessage nodeResult)
        {
            // TODO: future improvement opportunity: write a single parser that can parse warning, errors files from all tools that we use.
            if (nodeResult.Node.Annotation.StartsWith("CopyFiles"))
            {
                if (nodeResult.ExitCode == 0)
                {
                    return(Array.Empty <CompilerMessage>());
                }
                return(new[]
                {
                    new CompilerMessage
                    {
                        file = nodeResult.Node.OutputFile,
                        message = $"{nodeResult.Node.OutputFile}: {nodeResult.Output}",
                        type = CompilerMessageType.Error
                    }
                });
            }
            var parser = nodeResult.Node.Annotation.StartsWith("ILPostProcess")
                ? (CompilerOutputParserBase) new PostProcessorOutputParser()
                : (CompilerOutputParserBase) new MicrosoftCSharpCompilerOutputParser();

            return(parser
                   .Parse(
                       (nodeResult.Output ?? string.Empty).Split(new[] { '\r', '\n' },
                                                                 StringSplitOptions.RemoveEmptyEntries),
                       nodeResult.ExitCode != 0).ToArray());
        }
Exemplo n.º 2
0
        public static bool IsAnyPotentiallyUpdatable(CompilerMessage[] messages, NodeFinishedMessage nodeResult, ObjectsFromDisk dataFromBuildProgram)
        {
            var matches   = messages.Select(m => MicrosoftCSharpCompilerOutputParser.sCompilerOutput.Match(m.message)).Where(m => m.Success).ToArray();
            var typeNames = matches.Select(MissingTypeNameFor).Where(t => t != null).ToArray();

            if (!typeNames.Any())
            {
                return(false);
            }

            var assemblyData = Helpers.FindOutputDataAssemblyInfoFor(nodeResult, dataFromBuildProgram);
            var lines        = new NPath(assemblyData.MovedFromExtractorFile).ReadAllLines();

            return(typeNames.Any(t => lines.Contains(t)));
        }
        static CanUpdateAny ContainsUpdatableCompilerMessage(NodeFinishedMessage nodeResult, ObjectsFromDisk dataFromBuildProgram)
        {
            if (!nodeResult.Node.Annotation.StartsWith("Csc"))
            {
                return(CanUpdateAny.No);
            }

            var compilerMessages = BeeScriptCompilation.ParseCompilerOutput(nodeResult);

            bool IsOnlyMessageForThisFileLineAndColumn(CompilerMessage compilerMessage)
            {
                //we want to see if this is the only error on this location.  we will make an enumerable that matches all compilermessages that match this location
                //We do Skip(1).Any() as a bit of an unconventional way to express what we care about: is there more than 1 or not.
                return(!compilerMessages.Where(m => MatchesFileLineAndColumn(compilerMessage, m)).Skip(1).Any());
            }

            var upgradableMessages = compilerMessages.Where(c => c.message.Contains("(UnityUpgradable")).ToArray();

            //Some (UnityUpgradable) errors can be paired with a genuine user error on the same line/column. When this happens it is a known problem
            //that we are unable to upgrade the UnityUpgradable error. So we'll only return Certainly if there is not an other compilermessage pointing to the
            //same file,line,column. otherwise, we return maybe, so that a failure to do the update won't print a console message saying there is a bug.
            if (upgradableMessages.Any(IsOnlyMessageForThisFileLineAndColumn))
            {
                return(CanUpdateAny.Certainly);
            }
            if (upgradableMessages.Any())
            {
                return(CanUpdateAny.Maybe);
            }

            //The "unknown type or namespace" genre of messages we are not sure about. Some of these are legit user programming errors, some of them
            //are caused because we moved/renamed a type. In this case we will run the script updater to figure out, and if no updates were produced then
            //apparently it was a real user programming mistake instead of an updatable error;
            if (PotentiallyUpdatableErrorMessages.IsAnyPotentiallyUpdatable(compilerMessages, nodeResult, dataFromBuildProgram))
            {
                return(CanUpdateAny.Maybe);
            }

            return(CanUpdateAny.No);
        }