/// <summary> /// メソッド定義情報を取得する。 /// </summary> /// <param name="constant">モジュールまたはクラスのRubyオブジェクト。</param> /// <param name="attributes">メソッド取得対象を表すスイッチ。</param> /// <param name="objectDefinition">オブジェクト定義のインスタンス。</param> /// <param name="singleton">シングルトンメソッドか?</param> private static void GetMethodDefinitions( RubyModule constant, RubyMethodAttributes attributes, RubyObjectDefinition objectDefinition, bool singleton) { constant.ForEachMember(false, attributes | RubyMethodAttributes.VisibilityMask, (methodName, module, memberInfo) => { if (memberInfo is RubyAttributeAccessorInfo) { var accessorInfo = (RubyAttributeAccessorInfo)memberInfo; var accessorName = methodName; if (accessorInfo is RubyAttributeWriterInfo) { accessorName = accessorName.Substring(0, accessorName.Length - 1); } var accessorDefinition = ( from a in objectDefinition.Accessors where a.Name == accessorName select a ).FirstOrDefault(); if (accessorDefinition == null) { accessorDefinition = new RubyAccessorDefinition() { Name = accessorName }; objectDefinition.Accessors.Add(accessorDefinition); } if (accessorInfo is RubyAttributeWriterInfo) { accessorDefinition.Writable = true; } else if (accessorInfo is RubyAttributeReaderInfo) { accessorDefinition.Readable = true; } else { throw new NotImplementedException(); } } else if (memberInfo is RubyMethodInfo) { var methodInfo = (RubyMethodInfo)memberInfo; var methodDefinition = new RubyMethodDefinition() { Name = methodName, Singleton = singleton }; foreach (LocalVariable argument in methodInfo.Parameters.Mandatory) { methodDefinition.Arguments.Add( new RubyMethodArgumentDefinition() { Name = argument.Name, Optional = false } ); } foreach (SimpleAssignmentExpression argument in methodInfo.Parameters.Optional) { var argumentDefinition = new RubyMethodArgumentDefinition() { Name = ((LocalVariable)argument.Left).Name, Optional = true }; if (argument.Right is Literal) { argumentDefinition.DefaultValue = ((Literal)argument.Right).Value; } else if (argument.Right is ClassVariable) { argumentDefinition.DefaultValue = ((ClassVariable)argument.Right).Name; argumentDefinition.ClassVariable = true; } methodDefinition.Arguments.Add(argumentDefinition); } objectDefinition.Methods.Add(methodDefinition); } else { throw new NotImplementedException(); } }); }
/// <summary> /// Rubyオブジェクト定義のマップを取得する再帰処理。 /// </summary> /// <param name="map">定義マップのインスタンス。</param> /// <param name="definition">Rubyオブジェクト定義のインスタンス。</param> private void GetObjectDefinitionMapRecursive( Dictionary<string, RubyObjectDefinition> map, RubyObjectDefinition definition) { map.Add(definition.FullName, definition); foreach (var child in definition.Children) { GetObjectDefinitionMapRecursive(map, child); } }