MPS 2019.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コマンドを使用して既存のデータフロー命令セットに新しいコマンドを挿入します。

最終更新日: 2019年7月5日