public void Build(
            XDocument doc, ITextSource textSource,
            MSBuildParserContext context)
        {
            var project = doc.Nodes.OfType <XElement> ().FirstOrDefault(x => x.Name == xnProject);

            if (project == null)
            {
                //TODO: error
                return;
            }

            var sdks = ResolveSdks(context, project).ToList();

            var pel = MSBuildLanguageElement.Get("Project");

            GetPropertiesToTrack(context.PropertyCollector, project);

            var importResolver = context.CreateImportResolver(Filename);

            AddSdkProps(sdks, context.PropertyCollector, importResolver);

            var resolver = new MSBuildSchemaBuilder(IsToplevel, context, importResolver);

            resolver.Run(doc, textSource, this);

            AddSdkTargets(sdks, context.PropertyCollector, importResolver);
        }
Пример #2
0
        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);
        }
        void ResolveAndVisit(XElement element, MSBuildLanguageElement parent)
        {
            var resolved = MSBuildLanguageElement.Get(element.Name.Name, parent);

            if (resolved != null)
            {
                VisitResolvedElement(element, resolved);
            }
            else
            {
                VisitUnknownElement(element);
            }
        }
        public static MSBuildResolveResult Resolve(
            XmlParser parser,
            ITextSource textSource,
            MSBuildDocument context,
            IFunctionTypeProvider functionTypeProvider)
        {
            int offset = parser.Position;

            //clones and connects nodes to their parents
            parser = parser.GetTreeParser();

            var nodePath = parser.Nodes.ToList();

            nodePath.Reverse();

            //capture incomplete names, attributes and element values
            int i = offset;

            if (parser.CurrentState is XmlRootState && parser.Nodes.Peek() is XElement unclosedEl)
            {
                while (i < textSource.Length && InRootOrClosingTagState() && !unclosedEl.IsClosed)
                {
                    parser.Push(textSource.GetCharAt(i++));
                }
            }
            else
            {
                while (i < textSource.Length && InNameOrAttributeState())
                {
                    parser.Push(textSource.GetCharAt(i++));
                }
            }

            //if nodes are incomplete, they won't get connected
            //HACK: the only way to reconnect them is reflection
            if (nodePath.Count > 1)
            {
                for (int idx = 1; idx < nodePath.Count; idx++)
                {
                    var node = nodePath[idx];
                    if (node.Parent == null)
                    {
                        var parent = nodePath[idx - 1];
                        ParentProp.SetValue(node, parent);
                    }
                }
            }

            //need to look up element by walking how the path, since at each level, if the parent has special children,
            //then that gives us information to identify the type of its children
            MSBuildLanguageElement   languageElement   = null;
            MSBuildLanguageAttribute languageAttribute = null;
            XElement   el  = null;
            XAttribute att = null;

            foreach (var node in nodePath)
            {
                if (node is XAttribute xatt && xatt.Name.Prefix == null)
                {
                    att = xatt;
                    languageAttribute = languageElement?.GetAttribute(att.Name.Name);
                    break;
                }

                //if children of parent is known to be arbitrary data, don't go into it
                if (languageElement != null && languageElement.ValueKind == MSBuildValueKind.Data)
                {
                    break;
                }

                //code completion is forgiving, all we care about best guess resolve for deepest child
                if (node is XElement xel && xel.Name.Prefix == null)
                {
                    el = xel;
                    languageElement = MSBuildLanguageElement.Get(el.Name.Name, languageElement);
                    if (languageElement != null)
                    {
                        continue;
                    }
                }

                languageElement = null;
            }

            if (languageElement == null)
            {
                return(null);
            }

            var rr = new MSBuildResolveResult {
                LanguageElement   = languageElement,
                LanguageAttribute = languageAttribute,
                XElement          = el,
                XAttribute        = att
            };

            var rv = new MSBuildResolveVisitor(offset, rr, functionTypeProvider);

            rv.Run(el, languageElement, textSource, context);

            return(rr);

            bool InNameOrAttributeState() =>
            parser.CurrentState is XmlNameState ||
            parser.CurrentState is XmlAttributeState ||
            parser.CurrentState is XmlAttributeValueState;

            bool InRootOrClosingTagState() =>
            parser.CurrentState is XmlRootState ||
            parser.CurrentState is XmlNameState ||
            parser.CurrentState is XmlClosingTagState;
        }