xztaityozx / katatsumuri

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

katatsumuri

Perlのパッケージを別の言語の型に変換する実験

Perlのコードから型情報、型に定義されてるメソッド情報をJSONに書き出します。 関数・メソッドの情報はFunction::ParametersFunction::Returnのメタ情報だけじゃなく、Data::ValidatorやASTから引数名や型などをできるだけ取り出しています。

元のPerlコード

My::Namespace::B

package My::Namespace::B;
use strictures 2;
use Function::Parameters;
use Function::Return;
use Types::Standard -types;
use Data::Validator;

use Mouse;

has name => (is => 'ro', isa => Str, default => 'this is name');
has age => (is => 'ro', isa => Int, required => 1);
has union => (is => 'ro', isa => Str|Int, required => 1);

no Mouse;
__PACKAGE__->meta->make_immutable;

sub a {
    return 10;
}

fun b() :Return(Int) {
    return 10;
};

method c() :Return(Int) {
    return 10;
};

method d(Str $str, $x, Int $y //= 1) {
    return 10;
};

sub e {
    my $rule = Data::Validator->new(
        str => { isa => Str },
        x => { isa => Any },
        y => { isa => Int, default => 1 },
    );

    $rule->validate(@_);

    return 10;
}

sub f :Return(Str, Int) {
    my ($self, $str, $x, $y) = @_;

    return [$str, $x+$y];
}

1;

C#での例

生成されたJSONからC#のASTを構築してC#のソースコードを出力してます。ベース部分はJSON Schemaから生成しているので、アノテーションがついたままになっています。

生成のためのコード

//----------------------
// <auto-generated>
//     Generated using the NJsonSchema v10.9.0.0 (Newtonsoft.Json v9.0.0.0) (http://NJsonSchema.org)
// </auto-generated>
//----------------------
namespace My.Namespace
{
#pragma warning disable // Disable all warnings

    [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.9.0.0 (Newtonsoft.Json v9.0.0.0)")]
    public partial class B
    {
        /// <summary>
        /// original Perl type: Int
        /// </summary>
        [System.Text.Json.Serialization.JsonPropertyName("age")]
        [System.Text.Json.Serialization.JsonIgnore(Condition = System.Text.Json.Serialization.JsonIgnoreCondition.Never)]
        public int Age { get; set; }

        /// <summary>
        /// original Perl type: Dict[age=&gt;Int,name=&gt;Str]
        /// </summary>
        [System.Text.Json.Serialization.JsonPropertyName("dict")]
        [System.Text.Json.Serialization.JsonIgnore(Condition = System.Text.Json.Serialization.JsonIgnoreCondition.Never)]
        public Dict Dict { get; set; } = new Dict();

        /// <summary>
        /// original Perl type: Str
        /// </summary>
        [System.Text.Json.Serialization.JsonPropertyName("name")]
        [System.Text.Json.Serialization.JsonIgnore(Condition = System.Text.Json.Serialization.JsonIgnoreCondition.Never)]
        public string Name { get; set; } = "this is name";

        /// <summary>
        /// original Perl type: Str|Int
        /// </summary>
        [System.Text.Json.Serialization.JsonPropertyName("union")]
        [System.Text.Json.Serialization.JsonIgnore(Condition = System.Text.Json.Serialization.JsonIgnoreCondition.Never)]
        public Union Union { get; set; }

        private System.Collections.Generic.IDictionary<string, object> _additionalProperties;
        [System.Text.Json.Serialization.JsonExtensionData]
        public System.Collections.Generic.IDictionary<string, object> AdditionalProperties
        {
            get
            {
                return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary<string, object>());
            }

            set
            {
                _additionalProperties = value;
            }
        }

        ///<summary></summary> 
        ///<returns></returns>
        public object a()
        {
            throw new NotImplementedException();
        }

        ///<summary></summary> 
        ///<param name = "str">original Perl type: Str</param> 
        ///<param name = "x">original Perl type: Any</param> 
        ///<param name = "y">original Perl type: Int</param> 
        ///<returns></returns>
        public object e(string str, object x, int y = 1)
        {
            throw new NotImplementedException();
        }

        ///<summary></summary> 
        ///<returns>original Perl type: Str, Int</returns>
        public object f()
        {
            throw new NotImplementedException();
        }

        ///<summary></summary> 
        ///<returns></returns>
        public void g()
        {
            throw new NotImplementedException();
        }

        ///<summary></summary> 
        ///<param name = "a">original Perl type: Any</param> 
        ///<returns></returns>
        public object h(object a)
        {
            throw new NotImplementedException();
        }

        ///<summary></summary> 
        ///<returns>original Perl type: Int</returns>
        public int b()
        {
            throw new NotImplementedException();
        }

        ///<summary></summary> 
        ///<returns>original Perl type: Int</returns>
        public int c()
        {
            throw new NotImplementedException();
        }

        ///<summary></summary> 
        ///<param name = "str">original Perl type: Str</param> 
        ///<param name = "x">original Perl type: Any</param> 
        ///<param name = "y">original Perl type: Int</param> 
        ///<returns></returns>
        public object d(string str, object x, int y)
        {
            throw new NotImplementedException();
        }
    }

    [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.9.0.0 (Newtonsoft.Json v9.0.0.0)")]
    public partial class Dict
    {
        [System.Text.Json.Serialization.JsonPropertyName("age")]
        [System.Text.Json.Serialization.JsonIgnore(Condition = System.Text.Json.Serialization.JsonIgnoreCondition.Never)]
        public int Age { get; set; }

        [System.Text.Json.Serialization.JsonPropertyName("name")]
        [System.Text.Json.Serialization.JsonIgnore(Condition = System.Text.Json.Serialization.JsonIgnoreCondition.Never)]
        public string Name { get; set; }

        private System.Collections.Generic.IDictionary<string, object> _additionalProperties;
        [System.Text.Json.Serialization.JsonExtensionData]
        public System.Collections.Generic.IDictionary<string, object> AdditionalProperties
        {
            get
            {
                return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary<string, object>());
            }

            set
            {
                _additionalProperties = value;
            }
        }
    }

    [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.9.0.0 (Newtonsoft.Json v9.0.0.0)")]
    public partial class Union
    {
        private System.Collections.Generic.IDictionary<string, object> _additionalProperties;
        [System.Text.Json.Serialization.JsonExtensionData]
        public System.Collections.Generic.IDictionary<string, object> AdditionalProperties
        {
            get
            {
                return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary<string, object>());
            }

            set
            {
                _additionalProperties = value;
            }
        }
    }
}

これから

  • メソッド情報以外の情報はJSON Schemaから得ることにして、メソッド情報はASTやメタ情報からとるようにする
  • 型のひな型はJSON Schemaから生成して、メソッドはそこに追加するように書き換える
  • メソッドの型情報もJSON Schema準拠?にしたので、上手いこと生成できるとうれしいかもしれない

わからんこと

PerlのパッケージってJSON Schema生成できるんですか? ↑自力でやるしかなかった

About

License:MIT License


Languages

Language:Perl 76.8%Language:C# 23.2%