コード例 #1
0
        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);
        }
コード例 #2
0
        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");
            }
コード例 #3
0
        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);
        }
コード例 #4
0
        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])));
            }
        }
コード例 #5
0
        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));
        }
コード例 #6
0
        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);
        }
コード例 #7
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);
        }
コード例 #8
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);
        }
コード例 #9
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);
        }
コード例 #10
0
        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))));
        }