Quoting Alex Harui <aha...@adobe.com>:
Very nice. Have you figured out the role of the generated CMCEmitter in
this process?
Yes,
The CmcJSEmitter (autogenerated by cmc-js.jbg) is used to traverse the
ISWF that is created.
The CmcJSEmitter and JSGeneratingReducer are created in the
JSGenerator constructor.
The actual CmcJSEmitter is used during the
JSClassDirectiveProcessor.delcareVariable() etc. methods.
Basically the processor is using the emitter to create SWF
instructions that ultimately end up creating class traits. Once the
tratis are created, they just keep getting recursively visited and
more instructions created.
So it's like
- JSCompilationUnit.processABCBytesRequest()
- handleABCBytesRequest()
- JSGenerator.generate()
- then see below ....
When it gets to methods called declarePackage() for instance, block
code instructions are created using the cmc emitter. Traits are then
created based of them.
For FalconJS this process is totally bound to SWF format.
This was my point. For any developer to fix bugs here they have to
know the SWF format. Which I don't.
This is why I propsed another solution using pure AST like Jangaroo does.
I am not skilled enough to understand the trade offs currently. But I
am going to try and see if I can create the same JS code using a
different algorithm.
Mike
On 11/29/12 7:30 AM, "Michael Schmalle" <apa...@teotigraphix.com> wrote:
Hi,
For those asking question about "where to alter" code, it's not pretty
but I think I know exactly what is going on now.
If you can understand below, you will now have some insight to where
and how the JS code actually gets created.
! Call the compiler load config compile().
JSGenerator.generate() - creates the package, class, member traits
- DirectiveProcessor.processNode(IFileNode)
- recusrsivly fill traits
-----------------------------------------------------
Basically a snippet of the recursion;
DirectiveProcessor.processNode(IFileNode)
- declarePackage(PackageNode)
- emitter.visitPackage(packageName)
- data.registerPackage(packageName)
- super.declarePackage(PackageNode)
- DirectiveProcessor.traverse(p.getScopedNode()) <- ClassNode (class
{})
- for each ClassNode.getChild(i)
- processNode(ScopedBlockNode)
- JSGlobalDirectiveProcessor.declareClass(ClassNode)
- verifyClassModifiers(ClassNode)
- skins
- JSClassDirectiveProcessor cp =
backend.createClassDirectiveProcessor()
- cp.traverse(ClassNode.getScopedNode()) <- TypeScope
- for each TypeScope.getChild(i)
- processNode(TypeScope)
-
JSGlobalDirectiveProcessor.declareFunction(FunctionNode)
--------------------------------------------------------
!!!!
JavaScript source code creation after class traits have been traversed
and created;
JSEmiter.emit()
- emitClass(EmitterClassVisitor)
- IClassDefinition = getDefinition(ii.name)
- write class JSDoc
- JSEmitter.emitClass()
- Line: 3267 - 3269 is What creates a class
- "MainCode=adobe.extend("MainCode",Object,{ ... });"
- JSEmitter.emitInstanceTraits() is then called to write out the
class traits
- emitTraits() is then called to do the specific if the closure
compiler flag is not set
1. emitCtor() emit constructor
- emit comma
2. emit all variables before methods
- assembles the code "MainCode.foo"
- warns if there is a private namespace collision
-
3. emit all methods other than constructor
- emit ",\n"
- emitMethod()
- emitJSDocForMethod()
- write("\tget_baz")
- write(" : ") <- assignmentOp
- write("function(")
- emitParameters(methodInfo)
- write("baz")
- write(")")
- if (returnType != null)
- write(JSDoc for return type)
- if interface method
- write(" {};\n")
- else
- write("\n")
- write(" {")
- write("\n")
- emitMethodBody()
... you get the drift
- write(" }")
- After all traits are written, control flow goes back to
JSEmitter.emitClass() line 3269
- write("\n});\n\n") // end class
- add _CLASS member to instance
- add JSDoc for prototype._CLASS
- write("MainCode.prototype._CLASS = MainCode;\n")
It will then go onto
- emitClassInfo()
- emitNamespaceInfo()
- emitJSONInfo()
if (JSSharedData.JS_FRAMEWORK_NAME)
- emitFrameworkInit();
It will then finally emit register class
- "adobe.classes.MainCode=MainCode;"
---------------
MainCode._PACKAGE=adobe.globals;MainCode._NAME="MainCode";
MainCode._FULLNAME="MainCode";
MainCode._SUPER=Object;
MainCode._NAMESPACES={"foo::2":!0,"bar::7:MainCode":!0,"baz::2":!0,"baz::2":!0
};
adobe.classes.MainCode=MainCode;
---------------
Mike
--
Alex Harui
Flex SDK Team
Adobe Systems, Inc.
http://blogs.adobe.com/aharui
--
Michael Schmalle - Teoti Graphix, LLC
http://www.teotigraphix.com
http://blog.teotigraphix.com