feat(extract): add ActionScript 3 and MXML extractors#2035
Open
nitrobear wants to merge 1 commit into
Open
Conversation
ActionScript/Flex has no extractor today, and because `classify_file` returns None for an unknown extension, a `.as` or `.mxml` file currently produces no node at all — not even a file node. Pointing graphify at a Flex or AIR application yields a graph with no application structure in it. There is no tree-sitter grammar to build on: the two on GitHub are unmaintained and one targets decompiler output, so this follows the regex route dart.py, razor.py and pascal.py already take. The pairing mirrors pascal.py + pascal_forms.py — a legacy language plus its UI format. Three things carry the value: - Node identity. AS3 requires the package path to mirror the directory layout, so `com.example.util.Tools` resolves to its defining file and the import edge points at that file's own node. Reference nodes are attributed to the file that DEFINES the symbol, and shared entities with no defining file (SDK types, events, singletons) are marked `type: "module"`, so `_disambiguate_colliding_node_ids` leaves them alone. Without both, one event dispatched from N files becomes N nodes. - Event wiring. Flex couples components through string constants, which no import graph records. Dispatch sites usually write the literal and listen sites the constant, so constants are resolved to their value (reading the declaring file, cached) and both halves meet on one node. A file that both emits and subscribes to an event gets a single `relays` edge, since the build keeps one edge per node pair and arbitrating would report a dispatcher with no listener. - MXML. `xmlns:ui="com.example.ui.*"` maps a tag prefix to a package, so a `<ui:Widget/>` is a reference with no import line; `includeIn=` binds a component to a view state; `@Embed(...)`, `skinClass=` and `resourceManager.getString()` are compile-time dependencies. Script blocks are handed to the ActionScript extractor rather than re-parsed, so the two cannot drift. Tags in SDK namespaces and Spark skin interaction states (`up`, `over`, `disabled`) are skipped: they would bury an application's own components under hundreds of layout nodes. Relations emitted: imports, inherits, implements, contains, instantiates, references, embeds, dispatches, listens, relays, declares_event, uses_global, declares_state, renders, references_i18n. Validated on a 264-file Flex point-of-sale application: 1536 of 1536 import statements extracted, 163 of 163 files with `extends`, and 78% of events resolved to both a dispatcher and a listener (the rest are SDK events whose constants live outside the corpus). tests/test_actionscript.py adds 17 tests, covering declarations, node identity, event convergence, edge arbitration and MXML. Full suite on v8: 3401 passed / 15 failed. With this branch: 3418 passed / 15 failed — the same 15 (test_skillgen.py, test_ollama_retry_cap.py) fail on a clean v8 worktree and are unrelated to extraction.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ActionScript/Flex has no extractor today, and because
classify_filereturns None for an unknown extension, a.asor.mxmlfile currently produces no node at all — not even a file node. Pointing graphify at a Flex or AIR application yields a graph with no application structure in it.There is no tree-sitter grammar to build on: the two on GitHub are unmaintained and one targets decompiler output, so this follows the regex route dart.py, razor.py and pascal.py already take. The pairing mirrors pascal.py + pascal_forms.py — a legacy language plus its UI format.
Three things carry the value:
Node identity. AS3 requires the package path to mirror the directory layout, so
com.example.util.Toolsresolves to its defining file and the import edge points at that file's own node. Reference nodes are attributed to the file that DEFINES the symbol, and shared entities with no defining file (SDK types, events, singletons) are markedtype: "module", so_disambiguate_colliding_node_idsleaves them alone. Without both, one event dispatched from N files becomes N nodes.Event wiring. Flex couples components through string constants, which no import graph records. Dispatch sites usually write the literal and listen sites the constant, so constants are resolved to their value (reading the declaring file, cached) and both halves meet on one node. A file that both emits and subscribes to an event gets a single
relaysedge, since the build keeps one edge per node pair and arbitrating would report a dispatcher with no listener.MXML.
xmlns:ui="com.example.ui.*"maps a tag prefix to a package, so a<ui:Widget/>is a reference with no import line;includeIn=binds a component to a view state;@Embed(...),skinClass=andresourceManager.getString()are compile-time dependencies. Script blocks are handed to the ActionScript extractor rather than re-parsed, so the two cannot drift. Tags in SDK namespaces and Spark skin interaction states (up,over,disabled) are skipped: they would bury an application's own components under hundreds of layout nodes.Relations emitted: imports, inherits, implements, contains, instantiates, references, embeds, dispatches, listens, relays, declares_event, uses_global, declares_state, renders, references_i18n.
Validated on a 264-file Flex point-of-sale application: 1536 of 1536 import statements extracted, 163 of 163 files with
extends, and 78% of events resolved to both a dispatcher and a listener (the rest are SDK events whose constants live outside the corpus).tests/test_actionscript.py adds 17 tests, covering declarations, node identity, event convergence, edge arbitration and MXML.
Full suite on v8: 3401 passed / 15 failed. With this branch: 3418 passed / 15 failed — the same 15 (test_skillgen.py, test_ollama_retry_cap.py) fail on a clean v8 worktree and are unrelated to extraction.