Ejemplo n.º 1
0
        /// <summary>
        /// 各ルールから生成される結果用メソッドのシグネチャを,ルールの要素から牽けるようにしてを返します
        /// </summary>
        /// <param name="generator"></param>
        /// <returns></returns>
        public IDictionary <ElementsElement, MethodSignature> GetReturnParameterSignaturesAndElements(ScriptParserGenerator generator)
        {
            Dictionary <ElementsElement, MethodSignature> methodList = new Dictionary <ElementsElement, MethodSignature>();

            foreach (ElementsElement elems in this.Expression.Selection.Candidates)
            {
                // ひとつのルールに対してメソッドを一個生成する
                MethodSignature method = new MethodSignature();
                foreach (ElementElement elem in elems.Elements)
                {
                    ParameterSignature sig = elem.GetReturnParameterSignature(generator);
                    sig.ParamName = sig.ParamName.TrimStart('_');
                    sig.ParamName = sig.ParamName.TrimEnd('_');
                    if (sig.ParamName.Length >= 1)
                    {
                        if (char.IsUpper(sig.ParamName[0]))
                        {
                            sig.ParamName = sig.ParamName[0].ToString().ToLower() + sig.ParamName.Substring(1);
                        }
                    }
                    method.Parameters.Add(sig);
                    method.AddEbnfString(elem.ToString());
                }
                // おなじParamNameを持つものを探す
                HashSet <string> duplicativeNames = new HashSet <string>(from sig in method.Parameters
                                                                         group sig.ParamName by sig.ParamName into nameSet
                                                                         where nameSet.Count() >= 2
                                                                         select nameSet.Key);
                Dictionary <string, int> countUpPerName = duplicativeNames.ToDictionary(n => n, n => 1);
                foreach (ParameterSignature sig in method.Parameters)
                {
                    if (duplicativeNames.Contains(sig.ParamName))
                    {
                        string name = sig.ParamName;
                        sig.ParamName = string.Format("{0}_{1}", name, countUpPerName[name]);
                        countUpPerName[name]++;
                    }
                }
                method.MethodName = generator.GetReturnMethodIdentifier(this.DefinitionName);
                methodList[elems] = method;
            }
            // 引数の重複性を確認する
            var groupBy = methodList.Values.GroupBy(method => method, new MethodSignatureParametersComparer());
            Dictionary <MethodSignature, List <MethodSignature> > duplicativeMethods = groupBy.ToDictionary(m => m.Key, m => m.ToList());

            // 同じ引数のメソッドがある場合にはそれぞれにパラメータから作成される識別子を後置する.
            foreach (List <MethodSignature> dupMethods in duplicativeMethods.Values)
            {
                if (dupMethods.Count >= 2)
                {
                    foreach (MethodSignature dupMethod in dupMethods)
                    {
                        dupMethod.MethodName += "_" + dupMethod.GetMangledName();
                    }
                }
            }
            // C#のキーワードが識別子になる場合には頭に@を付ける
            foreach (MethodSignature method in methodList.Values)
            {
                foreach (ParameterSignature sig in method.Parameters)
                {
                    if (_keywords.Contains(sig.ParamName))
                    {
                        sig.ParamName = "@" + sig.ParamName;
                    }
                }
            }
            return(methodList);
        }