MPS 2020.3 ヘルプ

データフロー

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

値を読む

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

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

値を書く

Similarly the write operation indicates that a value gets written to. In the example, a variable declaration with an initializer first executes the initializer through the code for command and then marks the node as being written the result of the initializer:

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

のコード

As seen above in the LocalVariableDeclaration dataflow or below in the DotExpression dataflow, the code for command indicates nodes that get executed and when. In the DotExpression, for example, code for the operand runs before the actual dot operation:

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

ジャンプ

Dataflow for the TernaryOperatorExpression is a very straightforward example of using both conditional and unconditional jumps. Once the condition gets evaluated we can optionally jump to the ifFalse branch. Similarly, once the ifTrue branch is completed we unconditionally jump out of the scope of the node:

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   } }

イフジャンプ

The WhileStatement shows a more involved usage of the dataflow language. Not also the built-in detection of boolean constants. Trying to use while(false) will thus be correctly reported by MPS as a while-loop with unreachable body. This is thanks to the unconditional jump to after node if the constant is 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 }   } }

指示を挿入する

The TryStatement has even more needs from the dataflow language. It must insert extra ifjump instructions to jump to a catch clause wherever the particular exception can be thrown in the code:

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   } }

Notice, we're using a few other helper methods and commands here - get code for to retrieve the dataflow instruction set for a node, isRet, isJump and isNop to exclude certain types of instructions (returns, jumps and no-operations respectively), label to create named places in the dataflow instruction set that we can jump to from elsewhere, and finally the insert command to insert a new command into an existing dataflow instruction set.

関連ページ:

データフロー

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

正規表現

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

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

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