private void AnalyzePropertiesAndItems(BoundSourceFileBuilder binder, IXmlElement parent) { foreach (var group in parent.Elements("PropertyGroup")) { binder.AddReferences(group.Attribute("Condition").GetAttributeValueExpressionSpans()); foreach (var element in group.Elements) { binder.AddElementNameReferences(element, CreatePropertyReference(element.Name)); ExpressionProcessor propertyValueProcessor = null; if (element.Name.EndsWith("DependsOn")) { propertyValueProcessor = ProcessSemicolonSeparatedTargetList; } binder.AddReferences(element.Attribute("Condition").GetAttributeValueExpressionSpans()); binder.AddReferences(element.GetElementValueExpressionSpans(propertyValueProcessor)); } } foreach (var group in parent.Elements("ItemGroup")) { AnalyzeItemGroup(binder, group); } foreach (var group in parent.Elements("ItemDefinitionGroup")) { AnalyzeItemGroup(binder, group, isDefinition: true); } }
private void AnalyzeChoose(BoundSourceFileBuilder binder, IXmlElement parent) { foreach (var choose in parent.Elements("Choose")) { foreach (var element in parent.Elements("When")) { AnalyzePropertiesAndItems(binder, element); AnalyzeChoose(binder, element); } foreach (var element in parent.Elements("Otherwise")) { AnalyzePropertiesAndItems(binder, element); AnalyzeChoose(binder, element); } } }
public void Analyze( AnalysisServices services, RepoFile file, XmlSourceFileBuilder binder, XmlDocumentSyntax document) { IXmlElement root = document.Root; // corrupt or invalid or empty XML if (root == null) { return; } if (root.Name == null && root.Elements.Count() == 1) { root = root.Elements.First(); } if (root.Name != "Project") { return; } ExpressionProcessor targetListProcessor = ProcessSemicolonSeparatedTargetList; AnalyzeEvaluation(services, file, binder, document); AnalyzePropertiesAndItems(binder, root); AnalyzeChoose(binder, root); foreach (var element in root.Elements("UsingTask")) { binder.AddReferences(element.Attribute("Condition").GetAttributeValueExpressionSpans()); var taskName = element["TaskName"]; if (taskName != null) { string shortName = taskName; string containerName = null; int lastDot = taskName.LastIndexOf("."); if (lastDot > -1) { containerName = taskName.Substring(0, lastDot); shortName = taskName.Substring(lastDot + 1); } binder.AddAttributeValueDefinition(element.Attribute("TaskName"), new DefinitionSymbol() { DisplayName = taskName, ShortName = shortName, ContainerQualifiedName = containerName, Id = GetTaskSymbolId(shortName), Kind = nameof(SymbolKinds.MSBuildTask), ProjectId = MSBuildExtensions.MSBuildProjectId, ReferenceKind = nameof(ReferenceKind.Definition), }); } foreach (var outputElement in element.Elements("Output")) { foreach (var attribute in outputElement.AsSyntaxElement.Attributes) { if (attribute.Name == "ItemName") { binder.AddAttributeValueReferences(attribute, CreateItemReference(attribute.Value)); } else if (attribute.Name == "PropertyName") { binder.AddAttributeValueReferences(attribute, CreatePropertyReference(attribute.Value)); } } } } foreach (var import in root.Elements("Import")) { AnalyzeImport(binder, import); } foreach (var importGroup in root.Elements("ImportGroup")) { binder.AddReferences(importGroup.Attribute("Condition").GetAttributeValueExpressionSpans()); foreach (var import in importGroup.Elements("Import")) { AnalyzeImport(binder, import); } } foreach (var target in root.Elements("Target")) { var targetName = target["Name"]; binder.AddAttributeValueDefinition(target.Attribute("Name"), CreateTargetDefinition(targetName)); binder.AddReferences(target.Attribute("Condition").GetAttributeValueExpressionSpans()); binder.AddReferences(target.Attribute("DependsOnTargets").GetAttributeValueExpressionSpans(targetListProcessor)); binder.AddReferences(target.Attribute("Inputs").GetAttributeValueExpressionSpans()); binder.AddReferences(target.Attribute("Outputs").GetAttributeValueExpressionSpans()); binder.AddReferences(target.Attribute("BeforeTargets").GetAttributeValueExpressionSpans(targetListProcessor)); binder.AddReferences(target.Attribute("AfterTargets").GetAttributeValueExpressionSpans(targetListProcessor)); foreach (var taskElement in target.Elements.Where(el => el.Name != "PropertyGroup" && el.Name != "ItemGroup")) { binder.AddElementNameReferences(taskElement, new ReferenceSymbol() { Id = GetTaskSymbolId(taskElement.Name), Kind = nameof(SymbolKinds.MSBuildTask), ProjectId = MSBuildExtensions.MSBuildProjectId, ReferenceKind = nameof(ReferenceKind.Reference), }); // NOTE: Also parses condition attribute foreach (var taskParameterAttribute in taskElement.AsSyntaxElement.Attributes) { binder.AddReferences(taskParameterAttribute.GetAttributeValueExpressionSpans()); } foreach (var output in taskElement.Elements("Output")) { binder.AddReferences(output.Attribute("Condition").GetAttributeValueExpressionSpans()); var propertyNameAttribute = output.Attribute("PropertyName"); if (propertyNameAttribute != null) { binder.AddAttributeValueReferences(propertyNameAttribute, CreatePropertyReference(propertyNameAttribute.Value)); } var itemNameAttribute = output.Attribute("ItemName"); if (itemNameAttribute != null) { binder.AddAttributeValueReferences(itemNameAttribute, CreateItemReference(itemNameAttribute.Value)); } } } AnalyzePropertiesAndItems(binder, target); } }