private static IFilter AnalysisMethodAndArgs(MethodAndArgsTuple methodAndArgsTuple, Type filter, string filterInfo, bool terminal) { if (methodAndArgsTuple.MethodName.Type != Token.TokenType.Literal) throw new InvalidOperationException("内部エラー: 型が一致しません(メソッド"); var methods = QueryCandidateMethods(filter); var arguments = GetCTSTypedArguments(methodAndArgsTuple.Arguments).ToArray(); List<MethodInfo> foundMethods = new List<MethodInfo>(); foreach (var m in methods) { if (m.Name == methodAndArgsTuple.MethodName.Value) { var param = m.GetParameters(); if(param.Length == arguments.Length) { bool succ = true; for(int i = 0; i < param.Length; i++) { if(!param[i].ParameterType.Equals(arguments[i].GetType())) { succ = false; break; } } if(succ) { // 見つかりました return CreateFilterInstance(filter, m, arguments); } } foundMethods.Add(m); } } if (terminal) { if (foundMethods.Count > 0) { throw new ArgumentException( "指定のオーバーロードを持つメソッド " + methodAndArgsTuple.MethodName.Value + " は、フィルタ " + filterInfo + " には見つかりませんでした。" + Environment.NewLine + "フィルタ " + filterInfo + " が実装するメソッド:" + Environment.NewLine + " - " + String.Join(Environment.NewLine + " - ", from m in methods select m.Name + "(" + String.Join(", ", (from p in m.GetParameters() select p.ParameterType.ToString())) + ")")); } else { throw new ArgumentException( "メソッド \"" + methodAndArgsTuple.MethodName.Value + "\"は、フィルタ " + filterInfo + " には見つかりませんでした。" + Environment.NewLine + "フィルタ " + filterInfo + " が実装するメソッド:" + Environment.NewLine + " - " + String.Join(Environment.NewLine + " - ", methods.Select(m => m.Name).Distinct())); } } else { return null; } }
private static MethodAndArgsTuple MakeMethodAndArgs(ref TokenReader reader) { var mname = AssertNext(ref reader, Token.TokenType.Literal); if (TryLookAhead(ref reader, Token.TokenType.OpenBracket)) { // 引数付きメソッド呼び出し var ret = new MethodAndArgsTuple() { MethodName = mname, Arguments = MakeArguments(ref reader) }; AssertNext(ref reader, Token.TokenType.CloseBracket); return ret; } else { // 引数を省略したメソッド呼び出し return new MethodAndArgsTuple() { MethodName = mname }; } }