/// <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); }