MPS 2024.1 ヘルプ

データフロー

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

値を読む

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

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

値を書く

同様に、書き込み操作は、値が書き込まれることを示します。この例では、初期化子を使用した変数宣言は、最初にコマンドのコードを介して初期化子を実行し、次にノードに初期化子の結果が書き込まれていることを示します。

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

コード

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

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 の 場合にノードの後へ無条件に移動するためです。

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 を使用して、特定のタイプの命令(それぞれ、リターン、移動、操作なし)を除外します。他の場所から移動できるデータフロー命令セット内に名前付きの場所を作成するためのラベル。最後に、既存のデータフロー命令セットに新しいコマンドを挿入するための挿入コマンド。

関連ページ:

データフロー

言語のデータフローの側面では、到達不能なステートメントの検索、未使用の代入の検出、変数が読み込まれる前に初期化されていない可能性があるかどうかの確認などを行うことができます。また、「抽出メソッド」リファクタリングなど、いくつかのコード変換を実行することもできます。データフロー分析のほとんどのユーザーは、その内部作業の詳細には関心がありませんが、必要な結果を得ることには関心があります。彼らはどのステートメントに到達できないのか、それが初期化される前に何を読むことができるのかを知りたがっています。こ...

正規表現

正規表現言語の概要:導入正規表現言語(テキスト操作を大幅に簡素化する言語)は、現在最も使用されているドメイン固有の言語の 1 つです。ほとんどすべての開発者が少なくとも 1 回は使用しています。Perl や Python などの一部の言語には、サポートが組み込まれています。Java などの一部は、ライブラリを介して使用します。MPS の実装に使用する言語である Java には、正規表現の言語レベルのサポートがないため、DSL を実装するのが自然であったため、正規表現ライブラリの代わりに DSL...

データフローエンジンとの統合方法

データフロー:データフロー分析は、静的制約またはタイプチェックを使用して「モデルを見る」ことでは簡単に見つけることができないエラーの検出をサポートします。例としては、デッドコードの検出、メソッド本体の一部のブランチでの戻り値の欠落、値の静的な検索、null ポインター例外の防止などがあります。データフロー分析の基盤は、いわゆるデータフローグラフです。これは、プログラムのコードを介したデータの流れを記述するデータ構造です。例: では、42 はローカル変数宣言の init 式から変数に「流れ」、1...