読者です 読者をやめる 読者になる 読者になる

ひだまりソケットは壊れない

ソフトウェア開発に関する話を書きます。 最近は主に Android アプリ、Windows アプリ (UWP アプリ)、Java 関係です。

まじめなことを書くつもりでやっています。 適当なことは 「一角獣は夜に啼く」 に書いています。

WinJS.Promise のような非同期コールバックに IntelliSense を提供する方法

Windows ストアアプリを JavaScript で開発する際の、Visual Studio における入力支援機構 (IntelliSense) の話です。

IntelliSense と XML ドキュメントコメントについて

Visual Studio には、IntelliSense とよばれる入力支援機能が搭載されています。 JavaScript 用の補完機能等もあり (Visual Studio 2012 で確認)、Windows ストアアプリを JavaScript で書く場合には大いに助けになります。

ただ、JavaScript は静的型付け言語ではないので、やはりコードを書くだけでは補完が十分でないことが多いです。 そのため、XML ドキュメントコメントを用いて、オブジェクトのプロパティの情報や関数の返り値の情報を IntelliSense に与えることができるようになっています。

例えば、ある関数が文字列を返す場合は、以下のように returns タグで返り値の情報を与えることができます。

function doSomething () {
    /// <returns type="String">何らかの処理によって生成された文字列</returns>

    // 何らかの処理...
    return "...";
}

詳細は下記ページをご覧ください。

WinJS.Promise のような非同期コールバックのための returns の書き方

上に書いた例では文字列を XML ドキュメントコメントとして returns タグを書いて文字列を返すことを明示していますが、単に文字列を返すような単純な関数の場合は、XML ドキュメントコメントを書かなくても文字列を返す関数であることを IntelliSense はちゃんと認識してくれます。

しかし、WinJS.Promise で非同期コールバックをするような複雑な関数の場合は自動的には解析してくれないので、XML ドキュメントコメントを書く必要があります。 具体的には、XML ドキュメントコメントの return 要素に value 属性を与えてやり、その中に返り値に相当する値を生成する式を書いてやればよいです。

value 属性については、以下のように説明があります。

value
省略可能。 関数コードではなく、IntelliSense によって評価自体に対して使用する必要のあるコードを指定します。 たとえば、Promiseのような非同期コールバックに IntelliSense を提供するために、この属性を使用できます。 <returns> の要素で value の属性を使用して、長いコードの実行をバイパスすることにより、IntelliSense のパフォーマンスが向上します。

<returns> の説明 (MSDN)

例えば、WinJS.Promise でラップされた TemporaryCredentials オブジェクトを返す requestTemporaryCredentials という関数を考えてみます。 XML ドキュメントコメントの returns 要素の value 属性には、WinJS.Promise でラップされた TemporaryCredentials オブジェクト を生成する式を与えてやればよいです。 すなわち、WinJS.Promise.wrap( new TemporaryCredentials() ) という式です。

var TemporaryCredentials = WinJS.Class.define(function (token, secret) {
    /// <field name="token" type="String">The temporary credentials identifier</field>
    /// <field name="secret" type="String">The temporary credentials shared-secret</field>

    this.token = token;
    this.secret = secret;
});

function requestTemporaryCredentials() {
    /// <returns value='WinJS.Promise.wrap(new TemporaryCredentials())'>取得した OAuth の Request Token の情報</returns>

    return WinJS.Promise.wrap().
    then(function () {
        // ...
    }).
    then(function () {
        // ...
    }).
    then(function (credentialsInfo) {
        // 最終的に TemporaryCredentials オブジェクトを返す
        return new TemporaryCredentials(credentialsInfo.token, credentialsInfo.secret)
    });
}

requestTemporaryCredentials().then(function (creds) {
    // XML ドキュメントコメントにより creds が TemporaryCredentials オブジェクトであることを
    // IntelliSense が認識するので, creds のプロパティの補完候補として "token" や "secret" が出現する
});

実際に動かしてみると、以下のように補完候補が表示されます。

f:id:nobuoka:20121027225557p:plain

WinJS.Promise を使う機会は結構あるので、補完が働かなくて不便だと思ったときには XML ドキュメントコメントをちょこちょこ入れていくと良さそうだと思いました。