Elements Silver で Swift を Java にコンパイル

Swift で書いたコードを Java にコンパイルして Android で動作させられる [Silver](http://www.elementscompiler.com/elements/silver/) を試してみた。

環境

1. Mac OS X 10.11.5 (英語)
2. RemObjects Fire 8.3.93.1987
3. Oracle JDK 1.8.0_91

Silver の主張

1. [2016 年後半に Swift 3.0 をサポート予定](https://docs.elementscompiler.com/Silver/Swift30/)
2. [Elements 8.3.91 は Swift 2.2 の大部分をサポートしてる](https://docs.elementscompiler.com/Silver/Swift20/)
3. [Elements 8.2 は Swift 2.1 をサポートしてる](https://docs.elementscompiler.com/Silver/)

手順

1. Fire with Elemnts for Mac をダウンロード
    1. Fire は RemObjects 社の IDE
    2. Elements は RemObjects 社のコンパイラ
    3. Swift は Free だが C# と独自言語 Oxygene は有料
    4. Windows では Fire ではなく Visual Studio を使う

2. 起動画面
![Screen Shot 2016-07-06 at 15.57.31.png](https://qiita-image-store.s3.amazonaws.com/0/131106/faea32b3-ecf3-83e9-3e15-3cdc6feb8260.png)

    1. About Fire で確認すると、インストールされている最新の JDK が選択されてる
![Screen Shot 2016-07-06 at 16.08.23.png](https://qiita-image-store.s3.amazonaws.com/0/131106/98fb52c4-f0ce-5a1c-d880-f5b57c0e9ad5.png)
        1. Android SDK も勝手に見つかってる

3. Start a new Project で Platform を .NET から Java へ変更、テンプレートはまず Console Application を選んでみる
![Screen Shot 2016-07-06 at 16.05.28.png](https://qiita-image-store.s3.amazonaws.com/0/131106/8074441d-1eca-7944-34d9-46502949567f.png)

4. ディレクトリを選択して Create Project
![Screen Shot 2016-07-06 at 16.06.13.png](https://qiita-image-store.s3.amazonaws.com/0/131106/b310d81c-53a5-b729-9b25-395840f32bd0.png)

5. プロジェクト初期状態
![Screen Shot 2016-07-06 at 16.06.51.png](https://qiita-image-store.s3.amazonaws.com/0/131106/95bb3148-822d-9122-7011-92fecdf98531.png)

6. 生成されたファイル構成はシンプル

    1. 下 3 つの sln は Visual Studio 用で、実質 2 個

    ```
$ find SilverConsoleApp
SilverConsoleApp
SilverConsoleApp/Program.swift
SilverConsoleApp/SilverConsoleApp.elements
SilverConsoleApp/SilverConsoleApp.sln
SilverConsoleApp/SilverConsoleApp.sln.fire.cache
SilverConsoleApp/SilverConsoleApp.sln.fire.user
```

    1. プロジェクトファイルの構造も綺麗な感じ

    ```
$ cat SilverConsoleApp/SilverConsoleApp.elements
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build" ToolsVersion="4.0">
    <PropertyGroup>
        <ProductVersion>3.5</ProductVersion>
        <ProjectGuid>D5543A07-76CC-45B6-9AB2-684CC4594AA4</ProjectGuid>
        <OutputType>exe</OutputType>
        <Configuration Condition="'$(Configuration)' == ''">Release</Configuration>
        <AllowLegacyCreate>False</AllowLegacyCreate>
        <AllowLegacyOutParams>False</AllowLegacyOutParams>
        <MinFrameworkVersionRequired>4.0</MinFrameworkVersionRequired>
    </PropertyGroup>
    <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
        <Optimize>false</Optimize>
        <OutputPath>.\bin\Debug</OutputPath>
        <DefineConstants>DEBUG;TRACE;</DefineConstants>
        <GenerateDebugInfo>True</GenerateDebugInfo>
        <EnableAsserts>True</EnableAsserts>
        <TreatWarningsAsErrors>False</TreatWarningsAsErrors>
        <CaptureConsoleOutput>False</CaptureConsoleOutput>
        <StartMode>Project</StartMode>
        <RegisterForComInterop>False</RegisterForComInterop>
        <CpuType>anycpu</CpuType>
        <RuntimeVersion>v25</RuntimeVersion>
        <XmlDoc>False</XmlDoc>
        <XmlDocWarningLevel>WarningOnPublicMembers</XmlDocWarningLevel>
        <WarnOnCaseMismatch>True</WarnOnCaseMismatch>
        <EnableUnmanagedDebugging>False</EnableUnmanagedDebugging>
    </PropertyGroup>
    <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
        <Optimize>true</Optimize>
        <OutputPath>.\bin\Release</OutputPath>
        <GenerateDebugInfo>False</GenerateDebugInfo>
        <EnableAsserts>False</EnableAsserts>
        <TreatWarningsAsErrors>False</TreatWarningsAsErrors>
        <CaptureConsoleOutput>False</CaptureConsoleOutput>
        <StartMode>Project</StartMode>
        <RegisterForComInterop>False</RegisterForComInterop>
        <CpuType>anycpu</CpuType>
        <RuntimeVersion>v25</RuntimeVersion>
        <XmlDoc>False</XmlDoc>
        <XmlDocWarningLevel>WarningOnPublicMembers</XmlDocWarningLevel>
        <WarnOnCaseMismatch>True</WarnOnCaseMismatch>
        <EnableUnmanagedDebugging>False</EnableUnmanagedDebugging>
    </PropertyGroup>
    <ItemGroup>
        <Reference Include="rt"/>
        <Reference Include="swift">
            <Private>True</Private>
        </Reference>
        <Reference Include="cooper">
            <Private>True</Private>
        </Reference>
    </ItemGroup>
    <ItemGroup>
        <Compile Include="Program.swift"/>
    </ItemGroup>
    <Import Project="$(MSBuildExtensionsPath)\RemObjects Software\Elements\RemObjects.Elements.Cooper.targets"/>
```

7. しかし、エディタで日本語入力ができない！
    1. 日本語をペーストはできた
![Screen Shot 2016-07-06 at 16.14.41.png](https://qiita-image-store.s3.amazonaws.com/0/131106/01092bd4-08a0-b680-e8d5-d30eb1c15513.png)

8. Run してみたら java.security.PrivilegedActionException が起きて動かない
![Screen Shot 2016-07-06 at 16.21.05.png](https://qiita-image-store.s3.amazonaws.com/0/131106/294d1b81-487e-e5a1-e307-887cace2ce3d.png)

    1. jar が出来ているので、直接実行してみるとちゃんと動くので IDE の問題っぽい

        ```
$ find SilverConsoleApp/bin
SilverConsoleApp/bin
SilverConsoleApp/bin/Debug
SilverConsoleApp/bin/Debug/cooper.jar
SilverConsoleApp/bin/Debug/SilverConsoleApp.jar
SilverConsoleApp/bin/Debug/swift.jar
$ java -jar SilverConsoleApp/bin/Debug/SilverConsoleApp.jar
The 魔法 happens here.
```

        1. お供の swift.jar は 109KB
        2. お供の cooper.jar は 83KB

    1. jar には class ファイルが 1 個含まれている

        ```
$ mkdir jar
$ cd jar
$ tar xzvf ../SilverConsoleApp/bin/Debug/SilverConsoleApp.jar
x silverconsoleapp/
x silverconsoleapp/__Global.class
x DEBUG_INFO/
x DEBUG_INFO/silverconsoleapp.__Global.di
x METADATA/
x METADATA/.metadata.fx
x META-INF/
x META-INF/MANIFEST.MF
```

    1. swift.jar と cooper.jar に依存してる

        ```
$ more META-INF/MANIFEST.MF 
Manifest-Version: 1.0
Implementation-Vendor: RemObjects Software
Class-Path: swift.jar cooper.jar 
Main-Class: silverconsoleapp.__Global
Name: silverconsoleapp/__Global.class
```

    1. jd-gui-1.4.0.jar でデコンパイル

        ```
package silverconsoleapp;
public abstract class __Global {
  public static void main(String[] __args) {
swift.__Global.$$setArgV((String[])__args);swift.__Global.print__separator__terminator("The 魔法 happens here.", " ", null);
  }
}
```

        1. swift API を Java で実装してて、それを呼び出してる感じ

9. 今度は Android Application を試してみた
![Screen Shot 2016-07-06 at 16.44.19.png](https://qiita-image-store.s3.amazonaws.com/0/131106/105e08a6-eea6-4b58-f050-0318ae619a2d.png)

10. Android っぽいリソースが色々出来てる
![Screen Shot 2016-07-06 at 16.46.34.png](https://qiita-image-store.s3.amazonaws.com/0/131106/52ec3de8-599c-d107-b649-29a69851daa2.png)

11. そのまま Run すると generic Android device では deploy 出来ないので CrossBox で device を選択しろと出てしまう
![Screen Shot 2016-07-06 at 17.13.09.png](https://qiita-image-store.s3.amazonaws.com/0/131106/2bd7a1e6-5534-f6a6-e62e-b81fb79a175e.png)

12. Settings にそれらしい設定が見つかったが Generic Android Device しか選択肢がない
![Untitled.png](https://qiita-image-store.s3.amazonaws.com/0/131106/c9431a3e-8779-2a88-c20c-fec4df689dd6.png)

13. と思ったら、タイトルバー真下のプルダウンで USB 接続済みのデバイスを選択できた
![Untitled.png](https://qiita-image-store.s3.amazonaws.com/0/131106/1078de5f-5e86-d970-3c86-7a8450000ee2.png)
    1. 何回かデバイス側でデバッグ許可をし直したら動いた

参考リンク

1. https://talk.remobjects.com/