MPS 2019.2ヘルプ

SModel言語クエリ

比較

:式:およびne:演算子を使用して、ノードの同等性を比較できます。演算子はnullセーフであり、2つの比較されたノードによって表されるサブツリー全体を比較します。

照会

名前でノードを取得する

node-ptr /.../コンストラクトを使用して、名前を使用してノードへの参照を取得します。

ndptr1

ノードが特定のものであることを確認するために、「is」操作が使用可能です。

equals.is(Object->equals);

ノードへのポインターを取得するには、ポインター構造を使用します。

ndptr2

名前で概念を取得する

概念/.../コンストラクトを使用して、名前を指定して概念宣言を取得します。

concept<CommandList> myConcept = concept/CommandList/;  

コンセプトスイッチコンストラクトは、手元のコンセプトに応じて、ロジックをブランチでオフにするために使用できます。

ConceptSwitch

機能へのアクセス

SModel言語を使用して、次の機能にアクセスできます。

  • プロパティー

  • 子供

  • 参照

それらにアクセスするには、次の構文が使用されます。

<node expression>.featureName.

フィーチャがプロパティーである場合、式全体のタイプはプロパティーのタイプです。フィーチャーが参照または0..1またはカーディナリティーの子である場合、この式のタイプはnode <LinkTarget>です(LinkTargetは参照または子宣言のターゲットコンセプトです)。フィーチャーが0..nカーディナリティーの子である場合、この式のタイプはnlist <LinkTarget>です。

いわゆる暗黙的な選択を使用して、子ノードの機能にアクセスできます: 例:次のクエリ:

thisNode.children.grandChildren

MPSによって次のようなものに自動的に変換されます。

thisNode.children.selectMany({~it => it.grandChildren; })

その結果、指定されたリンク宣言のチェーンを介してアクセス可能なすべての非nullモデル要素のプレーンコレクションが作成されます。

nullチェック

MPSではnullは自由に扱われるため、null値をチェックする方法が必要です。isNullおよびisNotNull操作は、ここで私たちの友達です。

IsInstanceOfチェックと型キャスト

多くの場合、ノードが特定の概念のインスタンスであるかどうかを確認する必要があります。Javaのinstanceof演算子は、MPSノードではなく、javaオブジェクトのみを理解するため使用できません。このタイプのチェックを実行するには、次の構文を使用する必要があります。

<node expression>.isInstanceOf(Concept)

また、ノードの概念がユーザーが指定したものと正確に一致するかどうかを確認するisExactly操作があります。

コンセプトに対してノードのタイプを確認したら、通常、コンセプトインスタンスに式をキャストし、このコンセプトの機能の一部にアクセスする必要があります。そのためには、次の構文を使用する必要があります。

<node expression> : Concept


ノードを特定の概念インスタンスにキャストする別の方法は、asキャスト式を使用することです。

<node expression> as Concept

通常のキャスト(コロンを使用)とasキャストの違いは、左側の式の結果を指定されたConceptインスタンスに安全にキャストできない場合の状況を処理する方法にあります:NullPointer例外がレギュラーによってスローされますこの場合はキャストしますが、asキャストによってnullが返されます。

これをsmodel言語のnullセーフドット演算子と組み合わせると、モデルをナビゲートする非常に便利な方法が得られます。

node.parent as BinaryOperation.leftExpression as BinaryOperation.leftExpression.isLValue()

ノードコレクションキャスト

ノードのコレクションは、ofConceptコンストラクトを使用して、ノードの概念によってフィルタリングおよびキャストできます。

node.statements.ofConcept<LocalVariableDeclaration>

seq.ofConcept<MyConcept>seq.ofType<node<MyConcept>>と同等です

アスペクトコレクションキャスト

seq.ofAspect<structure> は特定の側面のノードをフィルターする

ノードの親を見つけるために、すべてのノードで操作を使用できます。

children操作は、現在のノードのすべての直接の子ノードにアクセスするために使用できます。この操作には、オプションのパラメーターlinkQualifierがあります。このパラメーターを使用すると、children <linkQualifier>操作の結果はnode.linkQualifier操作の呼び出しに相当するため、linkQualifierグループ/ロールに属する子のみをリコールします。例:classDef.children <注釈、メンバー>

兄弟クエリ

ASTを操作するとき、ノードの兄弟(つまり、検討中のノードと同じロールと親を持つノード)にアクセスすることがよくあります。このタスクには、次の操作があります。

  • next-sibling / prev-sibling-ノードの次/前の兄弟を返します。そのような兄弟が存在しない場合、nullが返されます。

  • next-siblings / prev-siblings-ノードの次/前の兄弟のnlistを返します。これらの操作には、現在のノードを含めるかどうかを指定するオプションのパラメーターがあります。

  • 兄弟-ノードのすべての兄弟のnlistを返します。これらの操作には、現在のノードを含めるかどうかを指定するオプションのパラメーターがあります。

上位

モデルの操作中、指定されたノードのすべての祖先(親、親の親、親の親の親など)を見つけるのが一般的です。このような場合、2つの操作があります。

  • 祖先 - ノードの単一の祖先を返します

  • ancestors-ノードのすべての祖先を返します
    どちらにも、リストを絞り込むための次のパラメーターがあります。

  • コンセプトタイプの制約: concept = Concept、[ConceptList]のコンセプト

  • 現在のノードを含めるかどうかを示すフラグ: +

例: myNode.ancestors <concept = InstanceMethodDeclaration、+>

子孫

また、指定されたノードのすべての子孫(直接の子、子の子など)を見つけることも役立ちます。このような目的のために子孫操作があります。以下のパラメーターがあります。

  • コンセプトタイプの制約: concept = Concept、[ConceptList]のコンセプト

  • 現在のノードを含めるかどうかを示すフラグ: +

例: myNode.descendants <concept = InstanceMethodDeclaration>

ルートとモデルを含む

指定されたノードの最上位の祖先ノードにアクセスするには、包含ルート操作を利用できます。モデル操作の結果として、包含モデルが使用可能になります。

以下に例を示します。

  • node <> containsRoot = myNode.taining root

  • モデルowningModel = myNode.model

モデルクエリ

model-ptr /.../式は、モデルへの解決可能な参照を取得します。リポジトリを使用すると、モデル<>タイプに解決できます。

多くの場合、特定の条件を満たすモデル内のすべてのノードを検索する必要があります。model <>タイプの式に適用可能ないくつかの操作があります。

  • roots(Concept)-モデル内のすべてのルートを返します: これは指定されたコンセプトのインスタンスです

  • nodes(Concept)-指定されたConceptのインスタンスであるモデル内のすべてのノードを返します

例: model.roots(<all>)またはmodel.nodes(IfStatement)

検索範囲クエリ

状況によっては、指定されたノードにどの参照を設定できるかを調べたいことがあります。このような場合には、検索範囲操作があります。次の構文で呼び出すことができます。

<node expression>.search scope(link, operationContext)

コンセプトリテラル

多くの場合、指定された概念への参照が必要です。このタスクには、概念リテラルがあります。次の構文があります。

concept/ConceptName/

例: concept <IfStatement> concept = concept / IfStatement /

コンセプト操作

特定のノードの概念を検索する場合は、ノードで概念操作を呼び出すことができます。

例: concept <IfStatement> concept = myNode.concept

非推奨の型からの移行

conceptNode <>タイプとconceptNode操作は非推奨になりました。asConcept操作は、conceptNode <>コンセプト<>に変換します。一方、asNode操作は逆の変換を行い、コンセプト<>に対してnode <AbstractConceptDeclaration>を返します。

概念階層クエリ

概念タイプを使用して、式のスーパー/サブコンセプトを照会できます。次の操作を自由に行えます。

  • スーパーコンセプト/すべて - 指定されたコンセプトのすべてのスーパーコンセプトを返します。現在のコンセプトを含める/除外するオプションがあります。スーパーコンセプト/すべて<+>

  • スーパーコンセプト/ダイレクト - 指定された概念のすべての直接的なスーパーコンセプトを返します。繰り返しますが、現在のコンセプトを含める/除外するオプションがあります。スーパーコンセプト/ダイレクト<+>

  • sub-concepts - サブコンセプトを返します

例:

concept <IfStatement> concept = myNode.concept;
list <concept <>> superConceptsAll = concept.super-concepts / all;
concept.super-concepts / direct <+>;
concept.sub-concepts(model);
concept <IfStatement> concept = myNode.concept;
list <concept <>> superConceptsAll = concept.super-concepts / all;
concept.super-concepts / direct <+>;
concept.sub-concepts(model、myScope);

hasRole操作

ノードに特定のロールがあるかどうかを確認したい場合があります。このために、次の構文があります。

<node expression>.hasRole(Concept : child)

以下に例を示します。

myNode.hasRole(IfStatement: elsifClauses)

リンククエリ

linklinkName、およびlinkNode操作により、ノード間のリンクの詳細にアクセスできます。

node<LinkDeclaration> decl = linkNode/ClassCreator : constructorDeclaration/; decl.sourceCardinality; decl.metaClass; decl.role; decl.target; decl.unordered;  ... string name = linkName/ClassCreator : constructorDeclaration/; SReferenceLink link = link/ClassCreator : constructorDeclaration/; link.isOptional(); link.getDeclarationNode(); link.getOwner(); link.getName(); link.getTargetConcept(); link.getScope(decl/); ...

リンククエリを含む

次の式を使用して、あるノードが別のノード(親)に追加された場合:

parent.childLinkRole.add(node)

その後、次の操作を呼び出して、包含関係情報にアクセスできます。

  • containsRole-このノードを含む親ノードの子ロールを表す文字列を返します (上記の場合の「childLinkRole」)

  • containingLink -戻るノード<LinkDeclaration>このノードを含む親ノードのリンク宣言を表する

  • index-対応するロールを持つ子のリストでこのノードのインデックスを表すint値を返します。上記のモデルに対する次のクエリと同じです。

parent.childLinkRole.indexOf(node)

ダウンキャスト

より低い意味レベルへのダウンキャスト

SModel言語は、生のMPSクラスで機能するコードを生成します。これらのクラスは通常の作業では非常に低レベルですが、例外的な場合にはそれらにアクセスする必要があります。低レベルのオブジェクトにアクセスするには、ダウンキャストを使用してセマンティックレベルの構造を下げます。次の構文があります。

<node expression>/

以下に例を示します。

myNode / .getConcept(): findProperty( "name" )

最終更新日: 2019年8月30日