Exemple #1
0
        public SignatureHelp GetSignatureHelp(Position position, PageInfoStore store)
        {
            var  node     = TraceNode(position);
            Node lastNode = null;

            while (node != null)
            {
                switch (node)
                {
                case Template template:
                    var templateName = MwParserUtility.NormalizeTitle(template.Name);
                    if (string.IsNullOrEmpty(templateName))
                    {
                        return(null);
                    }
                    // i.e. redirect target
                    var redirectSource = store.TryGetTransclusionPageInfo(templateName);
                    if (redirectSource == null)
                    {
                        return(null);
                    }
                    var templateInfo = store.ResolveRedirectTarget(redirectSource);
                    if (templateInfo == null)
                    {
                        templateInfo   = redirectSource;
                        redirectSource = null;
                    }
                    var help = new SignatureHelp
                    {
                        Signatures      = new[] { templateInfo.ToSignatureInformation(redirectSource) },
                        ActiveSignature = 0,
                        ActiveParameter = -1,
                    };
                    if (lastNode is TemplateArgument arg)
                    {
                        // Magic Words are always positional, while it can fake "named arguments"
                        if (templateInfo.Type == PageType.MagicWord)
                        {
                            var pos = template.Arguments.IndexOf(arg);
                            help.ActiveParameter = pos;
                        }
                        else
                        {
                            var argName = arg.ArgumentName();
                            help.ActiveParameter = templateInfo.Arguments.IndexOf(p => p.Name == argName);
                        }
                    }
                    return(help);

                case WikiLink wikiLink:
                    return(null);
                }
                lastNode = node;
                node     = node.ParentNode;
            }
            return(null);
        }
Exemple #2
0
        GetCompletionItems(Position position, PageInfoStore store)
        {
            var  innermostNode      = TraceNode(position);
            var  innermostPlainText = innermostNode as PlainText;
            var  node     = innermostNode;
            Node lastNode = null;
            // ... when the innermostPlainText is also the first node of all parent nodes
            var isSimpleIdentifier         = innermostPlainText != null;
            var lastNodeIsSimpleIdentifier = isSimpleIdentifier;

            // Trace the node from innermost to outermost.
            while (node != null)
            {
                lastNodeIsSimpleIdentifier = isSimpleIdentifier;
                isSimpleIdentifier         = isSimpleIdentifier &&
                                             (node is PlainText || lastNode.PreviousNode == null);
                switch (node)
                {
                case Template template:
                    if (lastNodeIsSimpleIdentifier && lastNode == template.Name)
                    {
                        var enteredName = MwParserUtility.NormalizeTitle(GetTypedLhsText(innermostPlainText, position));
                        return(store.GetTransclusionCompletionItems(enteredName), true);
                    }
                    return(null, false);

                case TemplateArgument argument:
                    // Do not show auto-completion for obvious argument values.
                    if (lastNodeIsSimpleIdentifier && (
                            lastNode == argument.Name ||  // | abc$ = def
                            argument.Name == null && lastNode == argument.Value        // Anonymous argument, or unfinished argument name
                            ))
                    {
                        var template     = (Template)argument.ParentNode;
                        var templateInfo = store.TryGetTransclusionPageInfo(MwParserUtility.NormalizeTitle(template.Name));
                        return(templateInfo.Arguments
                               .Select(a => new CompletionItem(a.Name, CompletionItemKind.Property, a.Summary, a.Name + "=")),
                               false);
                    }
                    return(null, false);

                case WikiLink wikiLink:
                    if (lastNodeIsSimpleIdentifier && lastNode == wikiLink.Target)
                    {
                        var enteredName = MwParserUtility.NormalizeTitle(GetTypedLhsText(innermostPlainText, position));
                        return(store.GetWikiLinkCompletionItems(enteredName), true);
                    }
                    return(null, false);
                }
                lastNode = node;
                node     = node.ParentNode;
            }
            return(null, false);
        }
 public SessionState(ClientProxy clientProxy, ILoggerFactory loggerFactory)
 {
     this.loggerFactory = loggerFactory;
     if (clientProxy == null)
     {
         throw new ArgumentNullException(nameof(clientProxy));
     }
     ClientProxy = clientProxy;
     logger      = loggerFactory.CreateLogger <SessionState>();
     PageInfoStore.LoadLocalStore();
 }
Exemple #4
0
        /// <summary>
        /// Infers linked/transcluded pages information, and stores it into global store.
        /// </summary>
        public int InferTemplateInformation(PageInfoStore store)
        {
            if (store == null)
            {
                throw new ArgumentNullException(nameof(store));
            }
            // template, argument
            var dict = new Dictionary <string, Dictionary <string, TemplateArgumentInfo> >();

            foreach (var template in _Root.EnumDescendants().OfType <Template>())
            {
                if (template.IsMagicWord)
                {
                    continue;
                }
                var name = template.Name?.ToString();
                if (string.IsNullOrEmpty(name))
                {
                    continue;
                }
                name = MwParserUtility.NormalizeTitle(name);
                if (name.Contains('{') || name.Contains('}'))
                {
                    continue;
                }
                name = Utility.ExpandTransclusionTitle(name);
                // Start to infer it.
                if (!dict.TryGetValue(name, out var parameters))
                {
                    if (store.ContainsPageInfo(name))
                    {
                        continue;
                    }
                    parameters = new Dictionary <string, TemplateArgumentInfo>();
                    dict.Add(name, parameters);
                }
                foreach (var p in template.Arguments.EnumNameArgumentPairs())
                {
                    if (parameters.ContainsKey(p.Key))
                    {
                        continue;
                    }
                    // TODO: Insert documentation here.
                    parameters.Add(p.Key, new TemplateArgumentInfo(p.Key, null));
                }
            }
            foreach (var p in dict)
            {
                var    isTemplate = Utility.IsTemplateTitle(p.Key);
                string transclusionName;
                if (isTemplate)
                {
                    Debug.Assert(p.Key.StartsWith("Template:"));
                    transclusionName = p.Key.Substring(9);
                }
                else
                {
                    transclusionName = ":" + p.Key;
                }
                store.UpdatePageInfo(new PageInfo(p.Key, transclusionName, null, Prompts.InferredPageInfo,
                                                  p.Value.OrderBy(p1 => p1.Key, TemplateArgumentNameComparer.Default)
                                                  .Select(p1 => p1.Value).ToArray(), isTemplate ? PageType.Template : PageType.Page, true));
            }
            return(dict.Count);
        }