Use when defining or debugging MPS dataflow builders for a concept — control/data flow declarations that drive reachability analysis and variable-use checking. Covers DataFlowBuilderDeclaration, BuilderBlock, emit instructions (code for, jump, ifjump, label, read, write, ret, mayBeUnreachable), positions (AfterPosition, BeforePosition, LabelPosition), the jetbrains.mps.lang.dataFlow language, the NodeParameter implicit, BL+smodel usage inside builder bodies, and IBuilderMode for advanced analyses such as nullable/non-null tracking.
78
100%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
The dataflow aspect (jetbrains.mps.lang.dataFlow, l:7fa12e9c-b949-4976-b4fa-19accbc320b4) lets a language describe how control and data flow through nodes of a concept. MPS uses that information for reachability analysis, uninitialised-variable checks, and (via IBuilderMode) richer flow analyses such as nullable tracking.
Each DataFlowBuilderDeclaration answers: given a node of concept X, in what order might execution visit its children, and which variables are read or written?
The builder body is a BL StatementList (inside a BuilderBlock). You use normal BL control flow (if, foreach, local variables) to compute which emit instructions to output at runtime. The node implicit parameter (concept NodeParameter) is always in scope — its type is the concept referenced by conceptDeclaration, giving smodel-typed access to children and references.
The MPS dataflow engine builds a control-flow graph from the emitted instructions, then runs analyses (unreachable code, uninitialised variable reads) on that graph. The engine only traces the paths you declare; if no builder exists for a concept, MPS falls back to delegating all children in declaration order.
code for is delegation, not a call. Never use jump for child delegation. Use EmitCodeForStatement to inline a child's own builder at this point.ifjump semantics: the jump is taken when the condition is FALSE. Use it after code for node.condition to model branching.EmitLabelStatement.name is display-only; jumps reference the label node via LabelPosition.label. Two labels with the same string are still distinct targets.0..1 children with BL if (node.child != null) before emitting code for node.child.write node vs write node.link: use write node (just NodeParameter as the variable expression) when the concept node is the variable being declared. Use write node.link (via SLinkAccess) when the node merely references the variable being written..mps dataflow files. Use MPS MCP node tools.mps_mcp_create_model and modelName: "<lang>.dataFlow" if absent. The aspect ID is dataFlow — camelCase, case-sensitive, no @ suffix; spelling it dataflow (lowercase) produces a utility model that MPS will not recognise. See aspect-model-stereotypes.md. Add jetbrains.mps.lang.dataFlow (and transitively jetbrains.mps.baseLanguage) as used languages on the model.DataFlowBuilderDeclaration root node; set conceptDeclaration to the concept being described; give it a name.BuilderBlock child with a body (BL StatementList).EmitCodeForStatement; model branches with EmitIfJumpStatement + EmitLabelStatement; record variable use with EmitReadStatement / EmitWriteStatement; mark exits with EmitRetStatement.BeforePosition/AfterPosition to encode loop-back/exit edges; wrap potentially-unreachable instructions in EmitMayBeUnreachable.mps_mcp_check_root_node_problems. For tricky cases, inspect an existing baseLanguage builder via mps_mcp_print_node with deep: true.mps-model-manipulation — BL + smodel code inside builder bodies (DotExpression, SLinkAccess, NodeParameter, behavior method calls).mps-aspect-behavior — for behavior methods called from builders to compute target nodes (e.g. getLoopOrSwitch, getReturnJumpTarget).mps-aspect-typesystem — when the dataflow you emit must agree with type checks.mps-node-editing — generic JSON-blueprint node creation/replacement workflow.DataFlowBuilderDeclaration, BuilderBlock, every emit statement, every position type, and the abstract bases. See references/concept-catalog.md.mps_mcp_* tools. Includes variable read, single-child delegation, return-with-finally, if/elsif/else, while loop, assignment, variable declaration, break to ancestor, and a custom inverted-condition statement. See references/json-patterns.md.AfterPosition and LabelPosition, or before using modes/IBuilderMode. See references/rules-and-pitfalls.md.IfStatement, WhileStatement, ReturnStatement, BreakStatement, VariableDeclaration, TryFinallyStatement, SwitchStatement, ForStatement, etc. Lists builder names and persistent nodeReferences in r:00000000-0000-4000-0000-011c895902c2. See references/baselanguage-builder-index.md.UnlessStatement_DataFlow). See references/sample-language-reference.md.52c9d63
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.