static void GetPropertiesToTrack(PropertyValueCollector propertyVals, MSBuildProjectElement project) { foreach (var el in project.Elements) { if (el is MSBuildImportElement imp) { var impAtt = imp.ProjectAttribute?.Value; if (impAtt != null) { MarkProperties(impAtt); } } else if (el is MSBuildUsingTaskElement ut) { var afAtt = ut.AssemblyFileAttribute?.Value; if (afAtt != null) { MarkProperties(afAtt); } } } void MarkProperties(ExpressionNode expr) { foreach (var prop in expr.WithAllDescendants().OfType <ExpressionProperty> ()) { propertyVals.Mark(prop.Name); } } }
void ResolveImports(MSBuildProjectElement project, MSBuildParserContext context) { var sdks = ResolveSdks(project, context).ToList(); //tag the properties we need to track for the imports GetPropertiesToTrack(context.PropertyCollector, project); var importResolver = context.CreateImportResolver(Filename); AddSdkProps(sdks, context.PropertyCollector, importResolver); void ExtractProperties(MSBuildPropertyGroupElement pg) { foreach (var prop in pg.Elements) { context.PropertyCollector.Collect(prop.ElementName, prop.Value); } } foreach (var el in project.Elements) { switch (el) { case MSBuildPropertyGroupElement pg: ExtractProperties(pg); break; case MSBuildChooseElement choose: foreach (var c in choose.Elements) { foreach (var pg in c.GetElements <MSBuildPropertyGroupElement> ()) { ExtractProperties(pg); } } break; case MSBuildImportElement imp: ResolveImport(imp, context, importResolver); break; } } AddSdkTargets(sdks, context.PropertyCollector, importResolver); }
IEnumerable <(string id, string path, TextSpan span)> ResolveSdks(MSBuildProjectElement project, MSBuildParserContext context) { var sdksAtt = project.SdkAttribute?.XAttribute; if (sdksAtt == null) { yield break; } string sdks = sdksAtt.Value; if (string.IsNullOrEmpty(sdks)) { yield break; } int offset = IsToplevel ? sdksAtt.ValueOffset : sdksAtt.Span.Start; foreach (var sdk in SplitSdkValue(offset, sdksAtt.Value)) { if (sdk.id == null) { if (IsToplevel) { Diagnostics.Add(CoreDiagnostics.EmptySdkAttribute, sdk.span); } } else { var sdkPath = context.GetSdkPath(this, sdk.id, sdk.span); if (sdkPath != null) { yield return(sdk.id, sdkPath, sdk.span); } if (IsToplevel) { Annotations.Add(sdksAtt, new NavigationAnnotation(sdkPath, sdk.span) { IsSdk = true }); } } } }
public void Build(XDocument doc, MSBuildParserContext context) { var project = doc.Nodes.OfType <XElement> ().FirstOrDefault(x => x.NameEquals("Project", true)); if (project == null) { //TODO: error return; } var projectElement = new MSBuildProjectElement(project); if (IsToplevel) { ProjectElement = projectElement; } ResolveImports(projectElement, context); InferredSchema = MSBuildInferredSchema.Build(projectElement, Filename, IsToplevel, context); }