public virtual IVsExpansionFunction GetExpansionFunction()

in vsintegration/src/FSharp.LanguageService.Base/ExpansionProvider.cs [319:392]


        public virtual IVsExpansionFunction GetExpansionFunction(XmlElement xmlFunctionNode, string fieldName) {
            string functionName = null;
            ArrayList rgFuncParams = new ArrayList();

            // first off, get the function string from the node
            string function = xmlFunctionNode.InnerText;

            if (function == null || function.Length == 0)
                return null;

            bool inIdent = false;
            bool inParams = false;
            int token = 0;

            // initialize the vars needed for our super-complex function parser :-)
            for (int i = 0, n = function.Length; i < n; i++) {
                char ch = function[i];

                // ignore and skip whitespace
                if (!Char.IsWhiteSpace(ch)) {
                    switch (ch) {
                        case ',':
                            if (!inIdent || !inParams)
                                i = n; // terminate loop
                            else {
                                // we've hit a comma, so end this param and move on...
                                string name = function.Substring(token, i - token);
                                rgFuncParams.Add(name);
                                inIdent = false;
                            }
                            break;
                        case '(':
                            if (!inIdent || inParams)
                                i = n; // terminate loop
                            else {
                                // we've hit the (, so we know the token before this is the name of the function
                                functionName = function.Substring(token, i - token);
                                inIdent = false;
                                inParams = true;
                            }
                            break;
                        case ')':
                            if (!inParams)
                                i = n; // terminate loop
                            else {
                                if (inIdent) {
                                    // save last param and stop
                                    string name = function.Substring(token, i - token);
                                    rgFuncParams.Add(name);
                                    inIdent = false;
                                }
                                i = n; // terminate loop
                            }
                            break;
                        default:
                            if (!inIdent) {
                                inIdent = true;
                                token = i;
                            }
                            break;
                    }
                }
            }

            if (functionName != null && functionName.Length > 0) {
                ExpansionFunction func = this.source.LanguageService.CreateExpansionFunction(this, functionName);
                if (func != null) {
                    func.FieldName = fieldName;
                    func.Arguments = (string[])rgFuncParams.ToArray(typeof(string));
                    return func;
                }
            }
            return null;
        }