コード例 #1
0
        public void Build(
            XDocument doc, ITextDocument textDocument,
            IRuntimeInformation runtime, PropertyValueCollector propVals,
            TaskMetadataBuilder taskBuilder,
            ImportResolver resolveImport)
        {
            var project = doc.Nodes.OfType <XElement> ().FirstOrDefault(x => x.Name == xnProject);

            if (project == null)
            {
                //TODO: error
                return;
            }

            var sdks = ResolveSdks(runtime, project, textDocument).ToList();

            var pel = MSBuildLanguageElement.Get("Project");

            GetPropertiesToTrack(propVals, project);

            AddSdkProps(sdks, propVals, resolveImport);

            var resolver = new MSBuildSchemaBuilder(IsToplevel, runtime, propVals, taskBuilder, resolveImport);

            resolver.Run(doc, Filename, textDocument, this);

            AddSdkTargets(sdks, propVals, resolveImport);
        }
コード例 #2
0
 public StatusController(BaseControllerServices services, IWebHostEnvironment environment, IRuntimeInformation rinfo, StatusControllerConfig config)
     : base(services)
 {
     this.environment        = environment;
     this.runtimeInformation = rinfo;
     this.config             = config;
 }
コード例 #3
0
        public MSBuildRuntimeEvaluationContext(IRuntimeInformation runtime)
        {
            if (runtime is Editor.Completion.NullRuntimeInformation)
            {
                return;
            }

            string binPath   = MSBuildEscaping.ToMSBuildPath(runtime.BinPath);
            string toolsPath = MSBuildEscaping.ToMSBuildPath(runtime.ToolsPath);

            Convert("MSBuildExtensionsPath");
            Convert("MSBuildExtensionsPath32");
            Convert("MSBuildExtensionsPath64");

            void Convert(string name)
            {
                if (runtime.SearchPaths.TryGetValue(name, out var vals))
                {
                    values[name] = new MSBuildPropertyValue(vals.ToArray());
                }
            }

            values["MSBuildBinPath"]      = binPath;
            values["MSBuildToolsPath"]    = toolsPath;
            values["MSBuildToolsPath32"]  = toolsPath;
            values["MSBuildToolsPath64"]  = toolsPath;
            values["RoslynTargetsPath"]   = $"{binPath}\\Roslyn";
            values["MSBuildToolsVersion"] = runtime.ToolsVersion;
            values["VisualStudioVersion"] = "15.0";

            values["MSBuildProgramFiles32"] = MSBuildEscaping.ToMSBuildPath(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86));
            values["MSBuildProgramFiles64"] = MSBuildEscaping.ToMSBuildPath(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles));

            var defaultSdksPath = runtime.SdksPath;

            if (defaultSdksPath != null)
            {
                values["MSBuildSDKsPath"] = MSBuildEscaping.ToMSBuildPath(defaultSdksPath, null);
            }

            //these are read from a config file and may be described in terms of other properties
            void Collapse(string name)
            {
                if (values.TryGetValue(name, out var val))
                {
                    values["name"] = val.Collapse(this);
                }
            }

            Collapse("MSBuildExtensionsPath");
            Collapse("MSBuildExtensionsPath32");
            Collapse("MSBuildExtensionsPath64");
        }
コード例 #4
0
 public MSBuildSchemaBuilder(
     bool isToplevel, IRuntimeInformation runtime,
     PropertyValueCollector propertyValues,
     TaskMetadataBuilder taskBuilder,
     ImportResolver resolveImport)
 {
     this.isToplevel          = isToplevel;
     this.runtime             = runtime;
     this.propertyValues      = propertyValues;
     this.taskMetadataBuilder = taskBuilder;
     this.resolveImport       = resolveImport;
 }
 void EnsureInitialized()
 {
     lock (initLocker) {
         if (runtimeInformation != null)
         {
             return;
         }
         try {
             runtimeInformation = new MSBuildEnvironmentRuntimeInformation();
         } catch (Exception ex) {
             LoggingService.LogError("Failed to initialize runtime info for parser", ex);
             runtimeInformation = new NullRuntimeInformation();
         }
         schemaProvider      = new MSBuildSchemaProvider();
         taskMetadataBuilder = new NoopTaskMetadataBuilder();
     }
 }
        static List <(string prefix, string subst)> GetPrefixes(IRuntimeInformation runtimeInfo)
        {
            var list = new List <(string prefix, string subst)> ();

            list.Add((runtimeInfo.GetBinPath(), "$(MSBuildBinPath)"));
            list.Add((runtimeInfo.GetToolsPath(), "$(MSBuildToolsPath)"));
            foreach (var extPath in runtimeInfo.GetExtensionsPaths())
            {
                list.Add((extPath, "$(MSBuildExtensionsPath)"));
            }
            var sdksPath = runtimeInfo.GetSdksPath();

            if (sdksPath != null)
            {
                list.Add((sdksPath, "$(MSBuildSDKsPath)"));
            }
            return(list);
        }
コード例 #7
0
        static List <(string prefix, string subst)> GetPrefixes(IRuntimeInformation runtimeInfo)
        {
            var list = new List <(string prefix, string subst)> {
                (runtimeInfo.BinPath, "$(MSBuildBinPath)"),
                (runtimeInfo.ToolsPath, "$(MSBuildToolsPath)")
            };

            foreach (var extPath in runtimeInfo.SearchPaths["MSBuildExtensionsPath"])
            {
                list.Add((extPath, "$(MSBuildExtensionsPath)"));
            }
            var sdksPath = runtimeInfo.SdksPath;

            if (sdksPath != null)
            {
                list.Add((sdksPath, "$(MSBuildSDKsPath)"));
            }
            return(list);
        }
コード例 #8
0
        public MSBuildBackgroundParser(
            ITextBuffer buffer,
            IRuntimeInformation runtimeInformation,
            MSBuildSchemaProvider schemaProvider,
            ITaskMetadataBuilder taskMetadataBuilder)
        {
            RuntimeInformation  = runtimeInformation ?? throw new ArgumentNullException(nameof(runtimeInformation));
            SchemaProvider      = schemaProvider ?? throw new ArgumentNullException(nameof(schemaProvider));
            TaskMetadataBuilder = taskMetadataBuilder ?? throw new ArgumentNullException(nameof(taskMetadataBuilder));

            XmlParser = XmlBackgroundParser.GetParser(buffer);
            XmlParser.ParseCompleted += XmlParseCompleted;

            if (buffer.Properties.TryGetProperty <ITextDocument> (typeof(ITextDocument), out var doc))
            {
                filepath = doc.FilePath;
                doc.FileActionOccurred += OnFileAction;
            }
        }
コード例 #9
0
        IEnumerable <(string id, string path, DocumentRegion)> ResolveSdks(IRuntimeInformation runtime, XElement project, ITextDocument doc)
        {
            var sdksAtt = project.Attributes.Get(new XName("Sdk"), true);

            if (sdksAtt == null)
            {
                yield break;
            }

            string sdks = sdksAtt?.Value;

            if (string.IsNullOrEmpty(sdks))
            {
                yield break;
            }

            DocumentLocation start = IsToplevel ? sdksAtt.GetValueStart(doc) : sdksAtt.Region.Begin;

            foreach (var sdk in SplitSdkValue(start, sdksAtt.Value))
            {
                if (sdk.id == null)
                {
                    if (IsToplevel)
                    {
                        Errors.Add(new Error(ErrorType.Warning, "Empty value", sdk.loc));
                    }
                }
                else
                {
                    var sdkPath = GetSdkPath(runtime, sdk.id, sdk.loc);
                    if (sdkPath != null)
                    {
                        yield return(sdk.id, sdkPath, sdk.loc);
                    }
                    if (IsToplevel)
                    {
                        Annotations.Add(sdksAtt, new NavigationAnnotation(sdkPath, sdk.loc));
                    }
                }
            }
        }
コード例 #10
0
        public MSBuildParserContext(
            IRuntimeInformation runtimeInformation,
            MSBuildRootDocument doc,
            MSBuildRootDocument previous,
            HashSet <string> importedFiles,
            string projectPath,
            PropertyValueCollector propVals,
            ITaskMetadataBuilder taskBuilder,
            MSBuildSchemaProvider schemaProvider,
            CancellationToken token)
        {
            RuntimeInformation   = runtimeInformation;
            RootDocument         = doc;
            PreviousRootDocument = previous;
            ImportedFiles        = importedFiles;
            ProjectPath          = projectPath;
            PropertyCollector    = propVals;
            TaskBuilder          = taskBuilder;
            SchemaProvider       = schemaProvider;
            Token = token;

            RuntimeEvaluationContext = new MSBuildRuntimeEvaluationContext(runtimeInformation);
        }
コード例 #11
0
        public static IDirectoryService GetDirectoryService(IRuntimeInformation runtimeInformation)
        {
            IDirectoryService result = null;

            switch (runtimeInformation.GetOSPlatform())
            {
            case OS.Windows:
                result = new DirectoryServiceWindows();
                break;

            case OS.Linux:
                result = new DirectoryServiceLinux();
                break;

            case OS.OSX:
                result = new DirectoryServiceOSX();
                break;

            default:
                throw new ArgumentException("XpdfNet currently only supports Linux, Windows and OSX.");
            }

            return(result);
        }
コード例 #12
0
        internal string GetSdkPath(IRuntimeInformation runtime, string sdk, DocumentRegion loc)
        {
            if (!SdkReference.TryParse(sdk, out SdkReference sdkRef))
            {
                string parseErrorMsg = $"Could not parse SDK '{sdk}'";
                LoggingService.LogError(parseErrorMsg);
                if (IsToplevel)
                {
                    AddError(parseErrorMsg);
                }
                return(null);
            }

            //FIXME: filename should be the root project, not this file
            try {
                var sdkPath = runtime.GetSdkPath(sdkRef, Filename, null);
                if (sdk != null)
                {
                    return(sdkPath);
                }
            } catch (Exception ex) {
                LoggingService.LogError("Error in SDK resolver", ex);
                return(null);
            }

            string notFoundMsg = $"Did not find SDK '{sdk}'";

            LoggingService.LogError(notFoundMsg);
            if (IsToplevel)
            {
                AddError(notFoundMsg);
            }
            return(null);

            void AddError(string msg) => Errors.Add(new Error(ErrorType.Error, msg, loc));
        }
 internal void Initialize(IRuntimeInformation runtimeInformation, MSBuildSchemaProvider schemaProvider, ITaskMetadataBuilder taskMetadataBuilder)
 {
     this.runtimeInformation  = runtimeInformation ?? throw new ArgumentNullException(nameof(runtimeInformation));
     this.schemaProvider      = schemaProvider ?? throw new ArgumentNullException(nameof(schemaProvider));
     this.taskMetadataBuilder = taskMetadataBuilder ?? throw new ArgumentNullException(nameof(taskMetadataBuilder));
 }
コード例 #14
0
        public static MSBuildRootDocument Parse(
            ITextSource textSource, string filePath, MSBuildRootDocument previous,
            MSBuildSchemaProvider schemaProvider, IRuntimeInformation runtimeInfo,
            ITaskMetadataBuilder taskBuilder,
            CancellationToken token)
        {
            var xmlParser = new XmlTreeParser(new XmlRootState());

            var(xdocument, _) = xmlParser.Parse(textSource.CreateReader());

            var propVals = new PropertyValueCollector(true);

            var doc = new MSBuildRootDocument(filePath)
            {
                XDocument          = xdocument,
                Text               = textSource,
                RuntimeInformation = runtimeInfo
            };

            var importedFiles = new HashSet <string> (StringComparer.OrdinalIgnoreCase);

            if (filePath != null)
            {
                try {
                    doc.Schema = previous?.Schema ?? schemaProvider.GetSchema(filePath, null);
                } catch (Exception ex) {
                    LoggingService.LogError("Error loading schema", ex);
                }
                importedFiles.Add(filePath);
            }

            var parseContext = new MSBuildParserContext(
                runtimeInfo,
                doc,
                previous,
                importedFiles,
                filePath,
                propVals,
                taskBuilder,
                schemaProvider,
                token);

            if (filePath != null)
            {
                doc.FileEvaluationContext = new MSBuildFileEvaluationContext(parseContext.RuntimeEvaluationContext, filePath, filePath);
            }
            else
            {
                doc.FileEvaluationContext = parseContext.RuntimeEvaluationContext;
            }

            string MakeRelativeMSBuildPathAbsolute(string path)
            {
                var dir = Path.GetDirectoryName(doc.Filename);

                path = path.Replace('\\', Path.DirectorySeparatorChar);
                return(Path.GetFullPath(Path.Combine(dir, path)));
            }

            Import TryImportFile(string label, string possibleFile)
            {
                try {
                    var fi = new FileInfo(possibleFile);
                    if (fi.Exists)
                    {
                        var imp = parseContext.GetCachedOrParse(label, possibleFile, null, fi.LastWriteTimeUtc);
                        doc.AddImport(imp);
                        return(imp);
                    }
                } catch (Exception ex) when(parseContext.IsNotCancellation(ex))
                {
                    LoggingService.LogError($"Error importing '{possibleFile}'", ex);
                }
                return(null);
            }

            Import TryImportSibling(string ifHasThisExtension, string thenTryThisExtension)
            {
                if (filePath == null)
                {
                    return(null);
                }
                var extension = Path.GetExtension(filePath);

                if (string.Equals(ifHasThisExtension, extension, StringComparison.OrdinalIgnoreCase))
                {
                    var siblingFilename = Path.ChangeExtension(filePath, thenTryThisExtension);
                    return(TryImportFile("(implicit)", siblingFilename));
                }
                return(null);
            }

            void TryImportIntellisenseImports(MSBuildSchema schema)
            {
                foreach (var intellisenseImport in schema.IntelliSenseImports)
                {
                    TryImportFile("(from schema)", MakeRelativeMSBuildPathAbsolute(intellisenseImport));
                }
            }

            try {
                //if this is a targets file, try to import the props _at the top_
                var propsImport = TryImportSibling(".targets", ".props");

                // this currently only happens in the root file
                // it's a quick hack to allow files to get some basic intellisense by
                // importing the files _that they themselves expect to be imported from_.
                // we also try to load them from the sibling props, as a paired targets/props
                // will likely share a schema file.
                var schema = doc.Schema ?? propsImport?.Document?.Schema;
                if (schema != null)
                {
                    TryImportIntellisenseImports(doc.Schema);
                }

                doc.Build(xdocument, textSource, parseContext);

                //if this is a props file, try to import the targets _at the bottom_
                var targetsImport = TryImportSibling(".props", ".targets");

                //and if we didn't load intellisense import already, try to load them from the sibling targets
                if (schema == null && targetsImport?.Document?.Schema != null)
                {
                    TryImportIntellisenseImports(targetsImport.Document.Schema);
                }
            } catch (Exception ex) when(parseContext.IsNotCancellation(ex))
            {
                LoggingService.LogError($"Error building document '{filePath ?? "[unnamed]"}'", ex);
            }

            try {
                var binpath = parseContext.RuntimeInformation.BinPath;
                foreach (var t in Directory.GetFiles(binpath, "*.tasks"))
                {
                    doc.LoadTasks(parseContext, "(core tasks)", t);
                }
                foreach (var t in Directory.GetFiles(binpath, "*.overridetasks"))
                {
                    doc.LoadTasks(parseContext, "(core overridetasks)", t);
                }
            } catch (Exception ex) when(parseContext.IsNotCancellation(ex))
            {
                LoggingService.LogError("Error resolving tasks", ex);
            }

            try {
                if (previous != null)
                {
                    // try to recover some values that may have been collected from the imports, as they
                    // will not have been re-evaluated
                    var fx = previous.Frameworks.FirstOrDefault();
                    if (fx != null)
                    {
                        propVals.Collect("TargetFramework", fx.GetShortFolderName());
                        propVals.Collect("TargetFrameworkVersion", FrameworkInfoProvider.FormatDisplayVersion(fx.Version));
                        propVals.Collect("TargetFrameworkIdentifier", fx.Framework);
                    }
                }
                doc.Frameworks = propVals.GetFrameworks();
            } catch (Exception ex) {
                LoggingService.LogError("Error determining project framework", ex);
                doc.Frameworks = new List <NuGetFramework> ();
            }

            try {
                //this has to run in a second pass so that it runs after all the schemas are loaded
                var validator = new MSBuildDocumentValidator();
                validator.Run(doc.XDocument, textSource, doc);
            } catch (Exception ex) when(parseContext.IsNotCancellation(ex))
            {
                LoggingService.LogError("Error in validation", ex);
            }

            return(doc);
        }
コード例 #15
0
        public static MSBuildEvaluationContext Create(IRuntimeInformation runtime, string projectPath, string thisFilePath)
        {
            // MSBuildEvaluationContext can only populate these properties from an MSBuildProject and we don't have one
            // OTOH this isn't a full evaluation anyway. Just set up a bunch of properties commonly used for imports.
            // TODO: add more commonly used properties
            var ctx = new MSBuildEvaluationContext();

            string tvString  = MSBuildToolsVersion.Unknown.ToVersionString();
            string binPath   = MSBuildProjectService.ToMSBuildPath(null, runtime.GetBinPath());
            string toolsPath = MSBuildProjectService.ToMSBuildPath(null, runtime.GetToolsPath());

            var extPaths = runtime.GetExtensionsPaths();

            ctx.extensionPaths = new List <string> (extPaths);

            AddReadOnlyProp("MSBuildBinPath", binPath);
            AddReadOnlyProp("MSBuildToolsPath", toolsPath);
            AddReadOnlyProp("MSBuildToolsPath32", toolsPath);
            AddReadOnlyProp("MSBuildToolsPath64", toolsPath);
            AddReadOnlyProp("RoslynTargetsPath", $"{binPath}\\Roslyn");
            AddReadOnlyProp("MSBuildToolsVersion", tvString);
            var extPath = MSBuildProjectService.ToMSBuildPath(null, extPaths.First());

            AddReadOnlyProp("MSBuildExtensionsPath", extPath);
            AddReadOnlyProp("MSBuildExtensionsPath32", extPath);
            AddReadOnlyProp("VisualStudioVersion", "15.0");

            var defaultSdksPath = runtime.GetSdksPath();

            if (defaultSdksPath != null)
            {
                AddReadOnlyProp("MSBuildSDKsPath", MSBuildProjectService.ToMSBuildPath(null, defaultSdksPath));
            }

            // project path properties
            string escapedProjectDir = MSBuildProjectService.ToMSBuildPath(null, Path.GetDirectoryName(projectPath));

            AddReadOnlyProp("MSBuildProjectDirectory", escapedProjectDir);
            // "MSBuildProjectDirectoryNoRoot" is this actually used for anything?
            AddReadOnlyProp("MSBuildProjectExtension", MSBuildProjectService.EscapeString(Path.GetExtension(projectPath)));
            AddReadOnlyProp("MSBuildProjectFile", MSBuildProjectService.EscapeString(Path.GetFileName(projectPath)));
            AddReadOnlyProp("MSBuildProjectFullPath", MSBuildProjectService.ToMSBuildPath(null, Path.GetFullPath(projectPath)));
            AddReadOnlyProp("MSBuildProjectName", MSBuildProjectService.EscapeString(Path.GetFileNameWithoutExtension(projectPath)));

            //don't have a better value, this is as good as anything
            AddReadOnlyProp("MSBuildStartupDirectory", escapedProjectDir);

            // this file path properties
            AddReadOnlyProp("MSBuildThisFile", MSBuildProjectService.EscapeString(Path.GetFileName(thisFilePath)));
            AddReadOnlyProp("MSBuildThisFileDirectory", MSBuildProjectService.ToMSBuildPath(null, Path.GetDirectoryName(thisFilePath)) + "\\");
            //"MSBuildThisFileDirectoryNoRoot" is this actually used for anything?
            AddReadOnlyProp("MSBuildThisFileExtension", MSBuildProjectService.EscapeString(Path.GetExtension(thisFilePath)));
            AddReadOnlyProp("MSBuildThisFileFullPath", MSBuildProjectService.ToMSBuildPath(null, Path.GetFullPath(thisFilePath)));
            AddReadOnlyProp("MSBuildThisFileName", MSBuildProjectService.EscapeString(Path.GetFileNameWithoutExtension(thisFilePath)));

            //HACK: we don't get a usable value for this without real evaluation so hardcode 'obj'
            var projectExtensionsPath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(projectPath), "obj"));

            AddReadOnlyProp("MSBuildProjectExtensionsPath", MSBuildProjectService.ToMSBuildPath(null, projectExtensionsPath) + "\\");

            return(ctx);

            void AddReadOnlyProp(string key, string val)
            {
                ctx.SetPropertyValue(key, val);
                readonlyProps.Add(key);
            }
        }
コード例 #16
0
        /// <summary>
        /// Shortens filenames by extracting common prefixes into MSBuild properties. Returns null if the name could not be shortened in this way.
        /// </summary>
        public Func <string, (string prefix, string remaining)?> CreateFilenameShortener(IRuntimeInformation runtimeInfo)
        {
            var prefixes = GetPrefixes(runtimeInfo);

            return(s => GetLongestReplacement(s, prefixes));
        }
コード例 #17
0
        public static MSBuildRootDocument Parse(
            string filename, ITextSource textSource, MSBuildRootDocument previous,
            MSBuildSchemaProvider schemaProvider, IRuntimeInformation runtimeInfo,
            CancellationToken token)
        {
            var xmlParser = new XmlParser(new XmlRootState(), true);

            try {
                xmlParser.Parse(textSource.CreateReader());
            } catch (Exception ex) {
                LoggingService.LogError("Unhandled error parsing xml document", ex);
            }

            var xdocument = xmlParser.Nodes.GetRoot();

            if (xdocument != null && xdocument.RootElement != null)
            {
                if (!xdocument.RootElement.IsEnded)
                {
                    xdocument.RootElement.End(xmlParser.Location);
                }
            }

            //FIXME: unfortunately the XML parser's regions only have line+col locations, not offsets
            //so we need to create an ITextDocument to extract tag bodies
            //we should fix this by changing the parser to use offsets for the tag locations
            ITextDocument textDoc = textSource as ITextDocument
                                    ?? TextEditorFactory.CreateNewDocument(textSource, filename, MSBuildTextEditorExtension.MSBuildMimeType);

            var propVals = new PropertyValueCollector(true);

            string projectPath = filename;

            var doc = new MSBuildRootDocument(filename)
            {
                XDocument          = xdocument,
                Text               = textDoc,
                RuntimeInformation = runtimeInfo
            };

            doc.Errors.AddRange(xmlParser.Errors);

            try {
                doc.Schema = previous?.Schema ?? schemaProvider.GetSchema(filename, null);
            } catch (Exception ex) {
                LoggingService.LogError("Error loading schema", ex);
            }

            var importedFiles = new HashSet <string> (StringComparer.OrdinalIgnoreCase)
            {
                filename
            };

            var taskBuilder = new TaskMetadataBuilder(doc);

            var extension = Path.GetExtension(filename);

            string MakeRelativeMSBuildPathAbsolute(string path)
            {
                var dir = Path.GetDirectoryName(doc.Filename);

                path = path.Replace('\\', Path.DirectorySeparatorChar);
                return(Path.GetFullPath(Path.Combine(dir, path)));
            }

            Import TryImportFile(string possibleFile)
            {
                try {
                    var fi = new FileInfo(possibleFile);
                    if (fi.Exists)
                    {
                        var imp = doc.GetCachedOrParse(importedFiles, previous, possibleFile, null, fi.LastWriteTimeUtc, projectPath, propVals, taskBuilder, schemaProvider, token);
                        doc.Imports.Add(possibleFile, imp);
                        return(imp);
                    }
                } catch (Exception ex) {
                    LoggingService.LogError($"Error importing '{possibleFile}'", ex);
                }
                return(null);
            }

            Import TryImportSibling(string ifHasThisExtension, string thenTryThisExtension)
            {
                if (string.Equals(ifHasThisExtension, extension, StringComparison.OrdinalIgnoreCase))
                {
                    var siblingFilename = Path.ChangeExtension(filename, thenTryThisExtension);
                    return(TryImportFile(siblingFilename));
                }
                return(null);
            }

            void TryImportIntellisenseImports(MSBuildSchema schema)
            {
                foreach (var intellisenseImport in schema.IntelliSenseImports)
                {
                    TryImportFile(MakeRelativeMSBuildPathAbsolute(intellisenseImport));
                }
            }

            try {
                //if this is a targets file, try to import the props _at the top_
                var propsImport = TryImportSibling(".targets", ".props");

                // this currently only happens in the root file
                // it's a quick hack to allow files to get some basic intellisense by
                // importing the files _that they themselves expect to be imported from_.
                // we also try to load them from the sibling props, as a paired targets/props
                // will likely share a schema file.
                var schema = doc.Schema ?? propsImport?.Document?.Schema;
                if (schema != null)
                {
                    TryImportIntellisenseImports(doc.Schema);
                }

                doc.Build(
                    xdocument, textDoc, runtimeInfo, propVals, taskBuilder,
                    (imp, sdk) => doc.ResolveImport(importedFiles, previous, projectPath, filename, imp, sdk, propVals, taskBuilder, schemaProvider, token)
                    );

                //if this is a props file, try to import the targets _at the bottom_
                var targetsImport = TryImportSibling(".props", ".targets");

                //and if we didn't load intellisense import already, try to load them from the sibling targets
                if (schema == null && targetsImport?.Document?.Schema != null)
                {
                    TryImportIntellisenseImports(targetsImport.Document.Schema);
                }
            } catch (Exception ex) {
                LoggingService.LogError($"Error building document '{projectPath}'", ex);
            }

            try {
                var binpath = doc.RuntimeInformation.GetBinPath();
                foreach (var t in Directory.GetFiles(binpath, "*.tasks"))
                {
                    doc.LoadTasks(importedFiles, previous, t, propVals, taskBuilder, schemaProvider, token);
                }
                foreach (var t in Directory.GetFiles(binpath, "*.overridetasks"))
                {
                    doc.LoadTasks(importedFiles, previous, t, propVals, taskBuilder, schemaProvider, token);
                }
            } catch (Exception ex) {
                LoggingService.LogError("Error resolving tasks", ex);
            }

            try {
                if (previous != null)
                {
                    // try to recover some values that may have been collected from the imports, as they
                    // will not have been re-evaluated
                    var fx = previous.Frameworks.FirstOrDefault();
                    if (fx != null)
                    {
                        propVals.Collect("TargetFramework", fx.GetShortFolderName());
                        propVals.Collect("TargetFrameworkVersion", FrameworkInfoProvider.FormatDisplayVersion(fx.Version));
                        propVals.Collect("TargetFrameworkIdentifier", fx.Framework);
                    }
                }
                doc.Frameworks = propVals.GetFrameworks();
            } catch (Exception ex) {
                LoggingService.LogError("Error determining project framework", ex);
                doc.Frameworks = new List <NuGetFramework> ();
            }

            try {
                //this has to run in a second pass so that it runs after all the schemas are loaded
                var validator = new MSBuildDocumentValidator();
                validator.Run(doc.XDocument, filename, textDoc, doc);
            } catch (Exception ex) {
                LoggingService.LogError("Error in validation", ex);
            }

            return(doc);
        }
コード例 #18
0
        public static MSBuildRootDocument Parse(
            string filename, ITextSource textSource, MSBuildRootDocument previous,
            MSBuildSchemaProvider schemaProvider, IRuntimeInformation runtimeInfo,
            CancellationToken token)
        {
            var xmlParser = new XmlParser(new XmlRootState(), true);

            try {
                xmlParser.Parse(textSource.CreateReader());
            } catch (Exception ex) {
                LoggingService.LogError("Unhandled error parsing xml document", ex);
            }

            var xdocument = xmlParser.Nodes.GetRoot();

            if (xdocument != null && xdocument.RootElement != null)
            {
                if (!xdocument.RootElement.IsEnded)
                {
                    xdocument.RootElement.End(xmlParser.Location);
                }
            }

            //FIXME: unfortunately the XML parser's regions only have line+col locations, not offsets
            //so we need to create an ITextDocument to extract tag bodies
            //we should fix this by changing the parser to use offsets for the tag locations
            ITextDocument textDoc = textSource as ITextDocument
                                    ?? TextEditorFactory.CreateNewDocument(textSource, filename, MSBuildTextEditorExtension.MSBuildMimeType);

            var propVals = new PropertyValueCollector(true);

            string projectPath = filename;

            var doc = new MSBuildRootDocument(filename);

            doc.XDocument          = xdocument;
            doc.Text               = textDoc;
            doc.RuntimeInformation = runtimeInfo;
            doc.Errors.AddRange(xmlParser.Errors);

            var importedFiles = new HashSet <string> (StringComparer.OrdinalIgnoreCase);

            importedFiles.Add(filename);

            var taskBuilder = new TaskMetadataBuilder(doc);

            try {
                doc.Build(
                    xdocument, textDoc, runtimeInfo, propVals, taskBuilder,
                    (imp, sdk) => doc.ResolveImport(importedFiles, previous, projectPath, filename, imp, sdk, propVals, taskBuilder, schemaProvider, token)
                    );
            } catch (Exception ex) {
                LoggingService.LogError("Error building document", ex);
            }

            try {
                var binpath = doc.RuntimeInformation.GetBinPath();
                foreach (var t in Directory.GetFiles(binpath, "*.tasks"))
                {
                    doc.LoadTasks(importedFiles, previous, t, propVals, taskBuilder, schemaProvider, token);
                }
                foreach (var t in Directory.GetFiles(binpath, "*.overridetasks"))
                {
                    doc.LoadTasks(importedFiles, previous, t, propVals, taskBuilder, schemaProvider, token);
                }
            } catch (Exception ex) {
                LoggingService.LogError("Error resolving tasks", ex);
            }


            try {
                if (previous != null)
                {
                    // try to recover some values that may have been collected from the imports, as they
                    // will not have been re-evaluated
                    var fx = previous.Frameworks.FirstOrDefault();
                    if (fx != null)
                    {
                        propVals.Collect("TargetFramework", fx.GetShortFolderName());
                        propVals.Collect("TargetFrameworkVersion", FrameworkInfoProvider.FormatDisplayVersion(fx.Version));
                        propVals.Collect("TargetFrameworkIdentifier", fx.Framework);
                    }
                }
                doc.Frameworks = propVals.GetFrameworks();
            } catch (Exception ex) {
                LoggingService.LogError("Error determining project framework", ex);
                doc.Frameworks = new List <NuGetFramework> ();
            }

            try {
                doc.Schema = previous?.Schema ?? schemaProvider.GetSchema(filename, null);
            } catch (Exception ex) {
                LoggingService.LogError("Error loading schema", ex);
            }

            try {
                //this has to run in a second pass so that it runs after all the schemas are loaded
                var validator = new MSBuildDocumentValidator();
                validator.Run(doc.XDocument, filename, textDoc, doc);
            } catch (Exception ex) {
                LoggingService.LogError("Error in validation", ex);
            }

            return(doc);
        }