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); }
public StatusController(BaseControllerServices services, IWebHostEnvironment environment, IRuntimeInformation rinfo, StatusControllerConfig config) : base(services) { this.environment = environment; this.runtimeInformation = rinfo; this.config = config; }
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"); }
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); }
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); }
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; } }
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)); } } } }
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); }
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); }
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)); }
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); }
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); } }
/// <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)); }
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); }
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); }