예제 #1
0
파일: RdParser.cs 프로젝트: xoriath/RTVS
        private static IReadOnlyList <IFunctionInfo> ParseFunctions(RdParseContext context)
        {
            IReadOnlyList <ISignatureInfo>       signatureInfos       = null;
            IReadOnlyDictionary <string, string> argumentDescriptions = null;
            string functionDescription = null; // Description is normally one for all similar functions
            bool   isInternal          = false;
            string returnValue         = null;

            while (!context.Tokens.IsEndOfStream() && argumentDescriptions == null)
            {
                RdToken token = context.Tokens.CurrentToken;

                if (context.IsAtKeywordWithParameters())
                {
                    if (string.IsNullOrEmpty(functionDescription) && context.IsAtKeyword(@"\description"))
                    {
                        functionDescription = RdText.GetText(context);
                    }
                    else if (context.IsAtKeyword(@"\keyword"))
                    {
                        string keyword = RdText.GetText(context);
                        if (!string.IsNullOrEmpty(keyword) && keyword.Contains("internal"))
                        {
                            isInternal = true;
                        }
                    }
                    else if (string.IsNullOrEmpty(returnValue) && context.IsAtKeyword(@"\value"))
                    {
                        returnValue = RdText.GetText(context);
                    }
                    else if (argumentDescriptions == null && context.IsAtKeyword(@"\arguments"))
                    {
                        // Extract arguments and their descriptions
                        argumentDescriptions = RdArgumentDescription.ExtractArgumentDecriptions(context);
                    }
                    else if (signatureInfos == null && context.IsAtKeyword(@"\usage"))
                    {
                        // Extract signatures with function names
                        signatureInfos = RdFunctionSignature.ExtractSignatures(context);
                    }
                    else
                    {
                        context.Tokens.Advance(2);
                    }
                }
                else
                {
                    context.Tokens.MoveToNextToken();
                }
            }

            // Merge descriptions into signatures. Add all arguments
            // listed in the \arguments{} section since function signature
            // does not always list all possible arguments.
            if (argumentDescriptions != null && signatureInfos != null)
            {
                foreach (ISignatureInfo sigInfo in signatureInfos)
                {
                    // Add missing arguments from the \arguments{} section
                    foreach (string name in argumentDescriptions.Keys)
                    {
                        // TODO: do we need HashSet here instead? Generally arguments
                        // list is relatively short, about 10 items on average.
                        if (sigInfo.Arguments.FirstOrDefault(x => x.Name.Equals(name)) == null)
                        {
                            sigInfo.Arguments.Add(new ArgumentInfo(name));
                        }
                    }
                    // Relocate ..., if any, to the end
                    var ellipsisArgument = sigInfo.Arguments.FirstOrDefault(x => x.IsEllipsis);
                    if (ellipsisArgument != null)
                    {
                        int index = sigInfo.Arguments.IndexOf(ellipsisArgument);
                        sigInfo.Arguments.RemoveAt(index);
                        sigInfo.Arguments.Add(ellipsisArgument);
                    }

                    // Add description if it is not there yet
                    foreach (var arg in sigInfo.Arguments.Where(x => string.IsNullOrEmpty(x.Description)))
                    {
                        string description;
                        if (argumentDescriptions.TryGetValue(arg.Name, out description))
                        {
                            ((NamedItemInfo)arg).Description = description ?? string.Empty;
                        }
                    }
                }
            }

            // Merge signatures into function infos
            Dictionary <string, FunctionInfo> functionInfos = new Dictionary <string, FunctionInfo>();

            if (signatureInfos != null)
            {
                Dictionary <string, List <ISignatureInfo> > functionSignatures = new Dictionary <string, List <ISignatureInfo> >();
                foreach (ISignatureInfo sigInfo in signatureInfos)
                {
                    FunctionInfo          functionInfo;
                    List <ISignatureInfo> sigList;
                    if (!functionInfos.TryGetValue(sigInfo.FunctionName, out functionInfo))
                    {
                        // Create function info
                        functionInfo = new FunctionInfo(sigInfo.FunctionName, functionDescription);
                        functionInfos[sigInfo.FunctionName] = functionInfo;
                        functionInfo.IsInternal             = isInternal;
                        functionInfo.ReturnValue            = returnValue;
                        // Create list of signatures for this function
                        sigList = new List <ISignatureInfo>();
                        functionSignatures[sigInfo.FunctionName] = sigList;
                        functionInfo.Signatures = sigList;
                    }
                    else
                    {
                        sigList = functionSignatures[sigInfo.FunctionName];
                    }

                    sigList.Add(sigInfo);
                }
            }

            return(functionInfos.Values.ToList());
        }
예제 #2
0
        private static IReadOnlyList <IFunctionInfo> ParseFunctions(RdParseContext context)
        {
            IReadOnlyList <ISignatureInfo>       signatureInfos       = null;
            IReadOnlyDictionary <string, string> argumentDescriptions = null;
            var    aliases             = new List <string>();
            string functionDescription = null; // Description is normally one for all similar functions
            bool   isInternal          = false;
            string returnValue         = null;
            string primaryName         = null;

            while (!context.Tokens.IsEndOfStream() &&
                   (functionDescription == null || argumentDescriptions == null ||
                    signatureInfos == null || returnValue == null))
            {
                RdToken token = context.Tokens.CurrentToken;

                if (context.IsAtKeywordWithParameters())
                {
                    if (string.IsNullOrEmpty(functionDescription) && context.IsAtKeyword(@"\description"))
                    {
                        functionDescription = RdText.GetText(context);
                    }
                    else if (context.IsAtKeyword(@"\keyword"))
                    {
                        string keyword = RdText.GetText(context);
                        if (!string.IsNullOrEmpty(keyword) && keyword.Contains("internal"))
                        {
                            isInternal = true;
                        }
                    }
                    else if (string.IsNullOrEmpty(returnValue) && context.IsAtKeyword(@"\value"))
                    {
                        returnValue = RdText.GetText(context);
                    }
                    else if (argumentDescriptions == null && context.IsAtKeyword(@"\arguments"))
                    {
                        // Extract arguments and their descriptions
                        argumentDescriptions = RdArgumentDescription.ExtractArgumentDecriptions(context);
                    }
                    else if (signatureInfos == null && context.IsAtKeyword(@"\usage"))
                    {
                        // Extract signatures with function names
                        signatureInfos = RdFunctionSignature.ExtractSignatures(context);
                    }
                    else if (context.IsAtKeyword(@"\alias"))
                    {
                        var alias = RdText.GetText(context);
                        if (!string.IsNullOrWhiteSpace(alias))
                        {
                            aliases.Add(alias);
                        }
                    }
                    else if (primaryName == null && context.IsAtKeyword(@"\name"))
                    {
                        primaryName = RdText.GetText(context);
                    }
                    else
                    {
                        context.Tokens.Advance(2);
                    }
                }
                else
                {
                    context.Tokens.MoveToNextToken();
                }
            }

            // Merge descriptions into signatures
            if (argumentDescriptions != null && signatureInfos != null)
            {
                foreach (ISignatureInfo sigInfo in signatureInfos)
                {
                    // Add missing arguments from the \arguments{} section
                    foreach (var arg in sigInfo.Arguments)
                    {
                        string description;
                        if (argumentDescriptions.TryGetValue(arg.Name, out description))
                        {
                            ((NamedItemInfo)arg).Description = description ?? string.Empty;
                        }
                    }
                }
            }

            // Merge signatures into function infos
            var functionInfos = new Dictionary <string, FunctionInfo>();

            if (signatureInfos != null)
            {
                var functionSignatures = new Dictionary <string, List <ISignatureInfo> >();
                foreach (ISignatureInfo sigInfo in signatureInfos)
                {
                    FunctionInfo          functionInfo;
                    List <ISignatureInfo> sigList;
                    if (!functionInfos.TryGetValue(sigInfo.FunctionName, out functionInfo))
                    {
                        // Create function info
                        functionInfo = CreateFunctionInfo(sigInfo.FunctionName, functionDescription, returnValue, isInternal);
                        functionInfos[sigInfo.FunctionName] = functionInfo;

                        // Create list of signatures for this function
                        sigList = new List <ISignatureInfo>();
                        functionSignatures[sigInfo.FunctionName] = sigList;
                        functionInfo.Signatures = sigList;
                    }
                    else
                    {
                        sigList = functionSignatures[sigInfo.FunctionName];
                    }

                    sigList.Add(sigInfo);
                }
            }

            // Propage to aliases
            if (!string.IsNullOrWhiteSpace(primaryName))
            {
                FunctionInfo functionInfo;
                if (functionInfos.TryGetValue(primaryName, out functionInfo))
                {
                    foreach (var alias in aliases)
                    {
                        if (!functionInfos.ContainsKey(alias))
                        {
                            functionInfos[alias] = new FunctionInfo(alias, functionInfo);
                        }
                    }
                }
            }

            return(functionInfos.Values.ToList());
        }