MPS 2020.1 ヘルプ

データフロー

このクックブックでは、あなたの言語用のデータフローを設計する際の素早い答えとガイドラインを提供するべきです。型システムの詳細な説明については、ユーザーガイドのデータフローセクションを参照してください。

値を読む

読み取り操作は、特定の値が読み取られることをデータフローエンジンに指示します。

data flow builder for LocalVariableReference {   (node)->void {     if (node.isVariableDefinedInThisMethod()) {       read node.localVariableDeclaration     }   } }

値を書く

同様に、書き込み操作は値が書き込まれることを示します。この例では、イニシャライザを使用した変数宣言は、最初 command for コードを介してイニシャライザを実行し、次にイニシャライザの結果が書き込まれたものとしてノードにマークを付けます。

data flow builder for LocalVariableDeclaration {   (node)->void {     nop     if (node.initializer.isNotNull) {       code for node.initializer       write node = node.initializer     }   } }

のコード

LocalVariableDeclaration データフローの上またはドット式データフローに見られるように、command のコードは実行されるノードとそのタイミングを示します。たとえば、ドット式では、オペランドのコードは実際のドット演算の前に実行されます。

data flow builder for DotExpression {   (node)->void {     code for node.operand     code for node.operation   } }

ジャンプ

TernaryOperatorExpression のデータフローは、条件付きジャンプと無条件ジャンプの両方を使用する非常に簡単な例です。条件が評価されたら、オプションで ifFalse ブランチにジャンプできます。同様に、ifTrue ブランチが完了すると、無条件にノードの範囲から飛び出します。

data flow builder for TernaryOperatorExpression {   (node)->void {     code for node.condition     ifjump before node.ifFalse     code for node.ifTrue     jump after node     code for node.ifFalse   } }

イフジャンプ

WhileStatement はデータフロー言語のより複雑な使用箇所を示しています。ブール定数の組み込み検出もありません。そのため、while(false) を使おうとすると、MPS によって本体に到達できない while ループとして正しく報告されます。これは、定数が false の場合に無条件に after ノードの後にジャンプするためです。

data flow builder for WhileStatement {   (node)->void {     code for node.condition     if (node.condition.isInstanceOf(BooleanConstant)) {       node<BooleanConstant> constant = node.condition : BooleanConstant;       if (!(constant.value)) {         jump after node       }     } else {       ifjump after node     }     code for node.body     { jump before node }   } }

指示を挿入する

TryStatement はデータフロー言語からさらに多くのニーズを持っています。コード内で特定の例外がスローされる可能性がある場所には、catch 句にジャンプするための追加の ifjump 命令を挿入する必要があります。

data flow builder for TryStatement {   (node)->void {     try       for (node<CatchClause> c : node.catchClause) {         ifjump before c       }       code for node.body       for (instruction instruction : get code for (node.body)) {         if (instruction.isRet || instruction.isJump || instruction.isNop) { continue; }         for (node<CatchClause> catchClause : DataFlowTryCatchUtil.getPossibleCatches(instruction.getSource, node.catchClause)) {           insert ifjump before catchClause after instruction         }         insert ifjump after afterCatches after instruction       }       { jump after afterCatches }       for (node<CatchClause> c : node.catchClause) {         code for c         { jump after afterCatches }       }       label afterCatches     finally       code for node.finallyBody     end   } }

ここでは、他のいくつかのヘルパーメソッドとコマンドを使用しています。ノードのデータフロー命令セット isRetisJump、および isNop を取得するためのコードを取得して、特定のタイプの命令を返します(それぞれリターン、ジャンプ、ノーオペレーション)。ラベルを付けて、データフロー命令セット内に別の場所からジャンプできる名前付きの場所を作成し、最後に insert コマンドを使用して既存のデータフロー命令セットに新しいコマンドを挿入します。

最終更新日 : 2020 年 6 月 18 日