List <(int Offset, int Length, ReferenceUsage Usage)> FindReferences(string docString, MSBuildReferenceKind kind, object reference) { var textDoc = new StringTextSource(docString); var xmlParser = new XmlTreeParser(new XmlRootState()); var(xdoc, _) = xmlParser.Parse(new StringReader(docString)); var doc = MSBuildTestHelpers.CreateEmptyDocument(); var parseContext = new MSBuildParserContext(new NullRuntimeInformation(), null, null, null, null, new PropertyValueCollector(false), null, null, default); var sb = new MSBuildSchemaBuilder(true, parseContext, null); sb.Run(xdoc, textDoc, doc); var functionTypeProvider = new RoslynFunctionTypeProvider(null); var results = new List <(int Offset, int Length, ReferenceUsage Usage)> (); var collector = MSBuildReferenceCollector.Create(new MSBuildResolveResult { ReferenceKind = kind, Reference = reference, }, functionTypeProvider, results.Add); collector.Run(xdoc, textDoc, doc); return(results); }
public void IncompleteTags() { var parser = new XmlTreeParser(CreateRootState()); parser.Parse(@" <doc> <tag.a att1 > <tag.b att2="" > <tag.c att3 = ' <tag.d $ att4 = > <tag.e att5='' att6=' att7 = > <tag.f id='$foo' /> </tag.e> </tag.d> </tag.c> </tag.b> </tag.a> </doc> ", delegate { parser.AssertStateIs <XmlTagState> (); Assert.IsFalse(parser.PeekSpine(1).IsComplete); parser.AssertNodeDepth(6); parser.AssertPath("//doc/tag.a/tag.b/tag.c/tag.d"); }, delegate { parser.AssertStateIs <XmlAttributeValueState> (); parser.AssertNodeDepth(9); Assert.IsTrue(parser.PeekSpine(3) is XElement eld && eld.Name.Name == "tag.d" && eld.IsComplete); Assert.IsTrue(parser.PeekSpine(2) is XElement ele && ele.Name.Name == "tag.e" && !ele.IsComplete); Assert.IsTrue(parser.PeekSpine(1) is XElement elf && elf.Name.Name == "tag.f" && !elf.IsComplete); Assert.IsTrue(parser.PeekSpine() is XAttribute att && !att.IsComplete); parser.AssertPath("//doc/tag.a/tag.b/tag.c/tag.d/tag.e/tag.f/@id"); }
public Import ParseImport(Import import) { Token.ThrowIfCancellationRequested(); var xmlParser = new XmlTreeParser(new XmlRootState()); ITextSource textSource; XDocument doc; try { textSource = new StringTextSource(File.ReadAllText(import.Filename)); (doc, _) = xmlParser.Parse(textSource.CreateReader()); } catch (Exception ex) when(IsNotCancellation(ex)) { LoggingService.LogError("Unhandled error parsing xml document", ex); return(import); } import.Document = new MSBuildDocument(import.Filename, false); import.Document.Build(doc, this); try { import.Document.Schema = SchemaProvider.GetSchema(import.Filename, import.Sdk); } catch (Exception ex) { LoggingService.LogError($"Error loading schema for '{import.Filename}'", ex); } return(import); }
public static void Parse(string txt, params Action <XNode>[] asserts) { var p = new XmlTreeParser(new XmlRootState()); var context = p.GetContext(); //parse and capture span info var list = new List <int> (); p.Parse(txt, Array.ConvertAll(asserts, a => (Action)(() => list.Add(context.Position)))); var doc = (XDocument)context.Nodes.Last(); for (int i = 0; i < asserts.Length; i++) { asserts[i] (doc.AllDescendentNodes.FirstOrDefault(n => n.Span.Contains(list[i]))); } }
protected override Task <XmlParseResult> StartOperationAsync(ITextSnapshot input, XmlParseResult previousOutput, ITextSnapshot previousInput, CancellationToken token) { var parser = new XmlTreeParser(StateMachine); return(Task.Run(() => { var length = input.Length; for (int i = 0; i < length; i++) { parser.Push(input[i]); } var(doc, diagnostics) = parser.FinalizeDocument(); return new XmlParseResult(doc, diagnostics, input); }, token)); }
public void Attributes() { var parser = new XmlTreeParser(CreateRootState()); parser.Parse(@" <doc> <tag.a name=""foo"" arg=5 wibble = 6 bar.baz = 'y.ff7]' $ /> </doc> ", delegate { parser.AssertStateIs <XmlTagState> (); parser.AssertAttributes("name", "foo", "arg", "5", "wibble", "6", "bar.baz", "y.ff7]"); } ); parser.AssertEmpty(); parser.AssertErrorCount(0); }
public void AttributeName() { var parser = new XmlTreeParser(CreateRootState()); parser.Parse(@" <doc> <tag.a> <tag.b id=""$foo"" /> </tag.a> </doc> ", delegate { parser.AssertStateIs <XmlAttributeValueState> (); parser.AssertPath("//doc/tag.a/tag.b/@id"); } ); parser.AssertEmpty(); parser.AssertErrorCount(0); }
public void AttributeRecovery() { var parser = new XmlTreeParser(CreateRootState()); parser.Parse(@" <doc> <tag.a> <tag.b arg='fff' sdd = sdsds= 'foo' ff = 5 $ /> </tag.a> <a><b valid/></a> </doc> ", delegate { parser.AssertStateIs <XmlTagState> (); parser.AssertAttributes("arg", "fff", "sdd", "sdsds", "ff", "5"); parser.AssertErrorCount(3); } ); parser.AssertEmpty(); parser.AssertErrorCount(4); }
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 void Parse(string doc, params Action <XmlParser>[] asserts) { var p = new XmlTreeParser(new XmlRootState()); p.Parse(doc, Array.ConvertAll(asserts, a => (Action)(() => a(p)))); }