2016-08-29 13 views
1

私が覚えている限り、私はいつもJavaでタイプエイリアス(C++のtypedefやhaskellのnewtypeなど)を見逃していました。 AndroidのSDKで タイプ別名のJava注釈プロセッサー

、私たちは、私たちは、コンパイル時に整数/文字列値の可能な誤用を見つけ出す手助け @IntDef@StringDefと様々なリソースタイプの注釈を含める support annotationsを持っています。私はあなたに短いアイデアを与えるためにAndroidのドキュメントからのコードの一部を挿入しています:

@IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS}) 
@Retention(RetentionPolicy.SOURCE) 
public @interface NavigationMode {} 

public static final int NAVIGATION_MODE_STANDARD = 0; 
public static final int NAVIGATION_MODE_LIST = 1; 
public static final int NAVIGATION_MODE_TABS = 2; 

@NavigationMode 
public abstract int getNavigationMode(); 

public abstract void setNavigationMode(@NavigationMode int mode); 

は実は、私はタイプエイリアシングを望ん例の95%は、ソートのと同じです:私は、データベースの行IDのいくつかの種類を得たとき通常はlongまたはStringです。その結果、名前に関する変数に関する型情報(たとえば、long folderIdlong messageId)をエンコードする必要があります。しかし、StringDef/IntDefアノテーションの煩わしい制限があります。何らかの理由で、あらかじめ定義された定数のセットが必要なため、DB識別子としては不十分な、有限の値しか記述できません。私が欲しいもの

は、同様の注釈のいくつかの種類@TypeAliasを言うと、リントチェックですので、私は何ができる:

@TypeAlias 
@Retention(RetentionPolicy.SOURCE) 
public @interface FolderId { } 

@FolderId 
public long getFolderIdByName(Database db, String name) { 
    long id = db.foldersTable().findByName(name).getId(); 
    return id; 
    /* 
     we might need to suppress the check here 
     (because we pass long as a @FolderId long), 
     but that's okay, since we are aware of 
     what we are doing here, and it's the only 
     possible injection point for @FolderId 
    */ 
} 

public void deleteMessagesIn(Database db, @FolderId long folder) { 
    // whatever 
} 

public void deleteMessagesInInbox(Database db) { 
    deleteMessagesIn(db, 1); // rejected by Lint, trying to pass long as @FolderId long 
    deleteMessagesIn(db, getFolderIdByName(db, "Inbox")); // ok, passes Lint check 
} 

私は有限のセットにタイプエイリアシング注釈を制限するための何らかの正当な理由が表示されません上記のように抑止するか、型のエイリアスを提供する関数用の別の注釈を導入することで回避できます。

さらに、これはAndroidアノテーションの制限事項ではありません。普通のJavaアプリケーションでも、この種のエイリアスの恩恵を受ける可能性があります。私はリモートで同様のものをGoogleに管理しませんでした。私たちはTYPE_PARAMETERターゲットを使うことで恩恵を受けることもできます。これにより、すべてが本当のタイプのエイリアスに似ているように見えます。

だから質問は以下のとおりです。チェックのこれらの種類を実装する静的アナライザは

  • ありますか?
  • もしそうでなければ、それが実装されるのを妨げる基本的な制限はありますか?再び、私はこれが非常に便利だと思うので、もし何もなかったら、誰かがそれをやったでしょう。

P. @mernstは、チェッカーの枠組みで私を指摘し、私は比較的簡単な方法でAndroidのとそれを統合するための管理:https://github.com/karlicoss/checker-fenum-android-demo

答えて

1

型の別名(型定義)の正しい使用をチェックする静的アナライザはChecker Frameworkと一緒に配布されFake Enum Checkerです。 SwingとJabRefのバグを見つけるために使われています。

+0

ありがとうございました!私が期待していたほど便利ではありませんでしたが、私はAndroidプロジェクトのためにそれを素晴らしいものにしました。 – karlicoss

関連する問題