http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/f938cb72/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSASDocEmitter.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSASDocEmitter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSASDocEmitter.java new file mode 100644 index 0000000..26b3f2a --- /dev/null +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSASDocEmitter.java @@ -0,0 +1,1478 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.flex.compiler.internal.codegen.mxml.flexjs; + + +import java.io.File; +import java.io.FilterWriter; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.apache.flex.abc.semantics.MethodInfo; +import org.apache.flex.abc.semantics.Name; +import org.apache.flex.abc.semantics.Namespace; +import org.apache.flex.compiler.codegen.IASGlobalFunctionConstants; +import org.apache.flex.compiler.codegen.as.IASEmitter; +import org.apache.flex.compiler.codegen.mxml.flexjs.IMXMLFlexJSEmitter; +import org.apache.flex.compiler.common.ASModifier; +import org.apache.flex.compiler.constants.IASKeywordConstants; +import org.apache.flex.compiler.constants.IASLanguageConstants; +import org.apache.flex.compiler.definitions.IClassDefinition; +import org.apache.flex.compiler.definitions.IDefinition; +import org.apache.flex.compiler.definitions.IFunctionDefinition; +import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens; +import org.apache.flex.compiler.internal.codegen.databinding.BindingDatabase; +import org.apache.flex.compiler.internal.codegen.databinding.BindingInfo; +import org.apache.flex.compiler.internal.codegen.databinding.FunctionWatcherInfo; +import org.apache.flex.compiler.internal.codegen.databinding.PropertyWatcherInfo; +import org.apache.flex.compiler.internal.codegen.databinding.StaticPropertyWatcherInfo; +import org.apache.flex.compiler.internal.codegen.databinding.WatcherInfoBase; +import org.apache.flex.compiler.internal.codegen.databinding.WatcherInfoBase.WatcherType; +import org.apache.flex.compiler.internal.codegen.databinding.XMLWatcherInfo; +import org.apache.flex.compiler.internal.codegen.js.JSSessionModel.PropertyNodes; +import org.apache.flex.compiler.internal.codegen.js.JSSessionModel.BindableVarInfo; +import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSASDocEmitter; +import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSEmitterTokens; +import org.apache.flex.compiler.internal.codegen.js.goog.JSGoogEmitterTokens; +import org.apache.flex.compiler.internal.codegen.js.jx.BindableEmitter; +import org.apache.flex.compiler.internal.codegen.js.jx.PackageFooterEmitter; +import org.apache.flex.compiler.internal.codegen.js.utils.EmitterUtils; +import org.apache.flex.compiler.internal.codegen.mxml.MXMLEmitter; +import org.apache.flex.compiler.internal.projects.FlexJSProject; +import org.apache.flex.compiler.internal.projects.FlexProject; +import org.apache.flex.compiler.internal.scopes.ASProjectScope; +import org.apache.flex.compiler.internal.targets.ITargetAttributes; +import org.apache.flex.compiler.internal.tree.as.FunctionCallNode; +import org.apache.flex.compiler.internal.tree.as.IdentifierNode; +import org.apache.flex.compiler.internal.tree.as.MemberAccessExpressionNode; +import org.apache.flex.compiler.internal.tree.mxml.MXMLDocumentNode; +import org.apache.flex.compiler.internal.tree.mxml.MXMLFileNode; +import org.apache.flex.compiler.mxml.IMXMLLanguageConstants; +import org.apache.flex.compiler.projects.ICompilerProject; +import org.apache.flex.compiler.tree.ASTNodeID; +import org.apache.flex.compiler.tree.as.*; +import org.apache.flex.compiler.tree.metadata.IMetaTagNode; +import org.apache.flex.compiler.tree.metadata.IMetaTagsNode; +import org.apache.flex.compiler.tree.mxml.*; +import org.apache.flex.compiler.units.ICompilationUnit; +import org.apache.flex.compiler.utils.NativeUtils; +import org.apache.flex.compiler.visitor.mxml.IMXMLBlockWalker; +import org.apache.flex.swc.ISWC; + +import com.google.common.base.Joiner; + +/** + * @author Erik de Bruin + */ +public class MXMLFlexJSASDocEmitter extends MXMLEmitter implements + IMXMLFlexJSEmitter +{ + + // the instances in a container + private ArrayList<MXMLDescriptorSpecifier> currentInstances; + private ArrayList<MXMLDescriptorSpecifier> currentPropertySpecifiers; + private ArrayList<MXMLDescriptorSpecifier> descriptorTree; + private MXMLDescriptorSpecifier propertiesTree; + private MXMLDescriptorSpecifier currentStateOverrides; + private ArrayList<MXMLEventSpecifier> events; + // all instances in the current document or subdocument + private ArrayList<MXMLDescriptorSpecifier> instances; + // all instances in the document AND its subdocuments + private ArrayList<MXMLDescriptorSpecifier> allInstances = new ArrayList<MXMLDescriptorSpecifier>(); + private ArrayList<MXMLScriptSpecifier> scripts; + //private ArrayList<MXMLStyleSpecifier> styles; + private IClassDefinition classDefinition; + private IClassDefinition documentDefinition; + private ArrayList<String> usedNames = new ArrayList<String>(); + private ArrayList<IMXMLMetadataNode> metadataNodes = new ArrayList<IMXMLMetadataNode>(); + + private int eventCounter; + private int idCounter; + private int bindingCounter; + + private boolean inMXMLContent; + private boolean inStatesOverride; + private boolean makingSimpleArray; + + private StringBuilder subDocuments = new StringBuilder(); + private ArrayList<String> subDocumentNames = new ArrayList<String>(); + private String interfaceList; + + /** + * This keeps track of the entries in our temporary array of + * DeferredInstanceFromFunction objects that we CG to help with + * State override CG. + * + * Keys are Instance nodes, + * values are the array index where the deferred instance is: + * + * deferred instance = local3[ nodeToIndexMap.get(an instance) ] + */ + protected Map<IMXMLNode, Integer> nodeToIndexMap; + + public MXMLFlexJSASDocEmitter(FilterWriter out) + { + super(out); + } + + @Override + public String postProcess(String output) + { + return output; + } + + @Override + protected String getIndent(int numIndent) + { + final StringBuilder sb = new StringBuilder(); + for (int i = 0; i < numIndent; i++) + sb.append(JSFlexJSEmitterTokens.INDENT.getToken()); + return sb.toString(); + } + + //-------------------------------------------------------------------------- + + @Override + public void emitDeclarations(IMXMLDeclarationsNode node) + { + super.emitDeclarations(node); + } + + @Override + public void emitDocument(IMXMLDocumentNode node) + { + // visit MXML + IClassDefinition cdef = node.getClassDefinition(); + classDefinition = cdef; + documentDefinition = cdef; + + // TODO (mschmalle) will remove this cast as more things get abstracted + JSFlexJSASDocEmitter fjs = (JSFlexJSASDocEmitter) ((IMXMLBlockWalker) getMXMLWalker()) + .getASEmitter(); + + fjs.getModel().setCurrentClass(cdef); + scripts = new ArrayList<MXMLScriptSpecifier>(); + + /* can there be asdoc for child tags? + // visit tags + final int len = node.getChildCount(); + for (int i = 0; i < len; i++) + { + getMXMLWalker().walk(node.getChild(i)); + } + */ + + String cname = node.getFileNode().getName(); + + //emitHeader(node); + + emitClassDeclStart(cname, node.getBaseClassName(), false); + + //emitPropertyDecls(); + emitScripts(); + + emitClassDeclEnd(cname, node.getBaseClassName()); + + // emitMetaData(cdef); + + // can there be asdoc for subdocs? + //write(subDocuments.toString()); + writeNewline(); + + /* these probably don't get asdoc either + emitEvents(cname); + + emitPropertyGetterSetters(cname); + */ + + } + + public void emitSubDocument(IMXMLComponentNode node) + { + // visit MXML + IClassDefinition oldClassDef = classDefinition; + IClassDefinition cdef = node.getContainedClassDefinition(); + classDefinition = cdef; + IASEmitter asEmitter = ((IMXMLBlockWalker) getMXMLWalker()) + .getASEmitter(); + ((JSFlexJSASDocEmitter) asEmitter).getModel().pushClass(cdef); + + IASNode classNode = node.getContainedClassDefinitionNode(); + String cname = cdef.getQualifiedName(); + String baseClassName = cdef.getBaseClassAsDisplayString(); + subDocumentNames.add(cname); + + // visit tags + final int len = classNode.getChildCount(); + for (int i = 0; i < len; i++) + { + getMXMLWalker().walk(classNode.getChild(i)); + } + + ((JSFlexJSASDocEmitter) asEmitter).mxmlEmitter = this; + + emitClassDeclStart(cname, baseClassName, false); + + emitComplexInitializers(classNode); + + //emitPropertyDecls(); + + emitClassDeclEnd(cname, baseClassName); + + + emitScripts(); + + emitEvents(cname); + + emitPropertyGetterSetters(cname); + + } + + //-------------------------------------------------------------------------- + + protected void emitClassDeclStart(String cname, String baseClassName, + boolean indent) + { + write("<"); + writeToken(formatQualifiedName(cname)); + write(">"); + if (indent) + indentPush(); + } + + //-------------------------------------------------------------------------- + + protected void emitClassDeclEnd(String cname, String baseClassName) + { + indentPop(); + writeNewline(); + writeNewline(); + write("</"); + writeToken(formatQualifiedName(cname)); + write(">"); + } + + //-------------------------------------------------------------------------- + + protected void emitScripts() + { + for (MXMLScriptSpecifier script : scripts) + { + String output = script.output(); + + if (!output.equals("")) + { + writeNewline(output); + } + } + } + + //-------------------------------------------------------------------------- + + protected void emitEvents(String cname) + { + for (MXMLEventSpecifier event : events) + { + writeNewline("/**"); + writeNewline(" * @export"); + writeNewline(" * @param {" + formatQualifiedName(event.type) + "} event"); + writeNewline(" */"); + writeNewline(formatQualifiedName(cname) + + ".prototype." + event.eventHandler + " = function(event)"); + writeNewline(ASEmitterTokens.BLOCK_OPEN, true); + + writeNewline(event.value + ASEmitterTokens.SEMICOLON.getToken(), + false); + + write(ASEmitterTokens.BLOCK_CLOSE); + writeNewline(";"); + writeNewline(); + writeNewline(); + } + } + + //-------------------------------------------------------------------------- + + protected void emitPropertyGetterSetters(String cname) + { + int n = 0; + for (MXMLDescriptorSpecifier instance : instances) + { + if (!instance.id.startsWith(MXMLFlexJSEmitterTokens.ID_PREFIX + .getToken())) + { + n++; + } + } + if (n == 0 && descriptorTree.size() == 0) + return; + + String formattedCName = formatQualifiedName(cname); + + write("Object.defineProperties("); + write(formattedCName); + writeNewline(".prototype, /** @lends {" + formattedCName + ".prototype} */ {"); + indentPush(); + int i = 0; + for (MXMLDescriptorSpecifier instance : instances) + { + if (!instance.id.startsWith(MXMLFlexJSEmitterTokens.ID_PREFIX + .getToken())) + { + indentPush(); + writeNewline("/** @export */"); + writeNewline(instance.id + ": {"); + writeNewline("/** @this {" + formattedCName + "} */"); + indentPush(); + writeNewline("get: function() {"); + indentPop(); + writeNewline("return this." + instance.id + "_;"); + writeNewline("},"); + writeNewline("/** @this {" + formattedCName + "} */"); + indentPush(); + writeNewline("set: function(value) {"); + indentPush(); + writeNewline("if (value != this." + instance.id + "_) {"); + writeNewline("this." + instance.id + "_ = value;"); + write("this.dispatchEvent(org.apache.flex.events.ValueChangeEvent.createUpdateEvent(this, '"); + indentPop(); + writeNewline(instance.id + "', null, value));"); + indentPop(); + writeNewline("}"); + indentPop(); + writeNewline("}"); + if (i < n - 1 || descriptorTree.size() > 0) + writeNewline("},"); + else + { + indentPop(); + writeNewline("}"); + } + i++; + } + } + if (descriptorTree.size() == 0) + writeNewline("});"); + } + + //-------------------------------------------------------------------------- + + private HashMap<IMXMLEventSpecifierNode, String> eventHandlerNameMap = new HashMap<IMXMLEventSpecifierNode, String>(); + + @Override + public void emitEventSpecifier(IMXMLEventSpecifierNode node) + { + if (isStateDependent(node) && !inStatesOverride) + return; + + IDefinition cdef = node.getDefinition(); + + MXMLDescriptorSpecifier currentDescriptor = getCurrentDescriptor("i"); + + MXMLEventSpecifier eventSpecifier = new MXMLEventSpecifier(); + eventSpecifier.eventHandler = MXMLFlexJSEmitterTokens.EVENT_PREFIX + .getToken() + eventCounter++; + eventSpecifier.name = cdef.getBaseName(); + eventSpecifier.type = node.getEventParameterDefinition() + .getTypeAsDisplayString(); + + eventHandlerNameMap.put(node, eventSpecifier.eventHandler); + + IASEmitter asEmitter = ((IMXMLBlockWalker) getMXMLWalker()) + .getASEmitter(); + + StringBuilder sb = null; + int len = node.getChildCount(); + if (len > 0) + { + sb = new StringBuilder(); + for (int i = 0; i < len; i++) + { + sb.append(getIndent((i > 0) ? 1 : 0) + + asEmitter.stringifyNode(node.getChild(i))); + if (i < len - 1) + { + sb.append(ASEmitterTokens.SEMICOLON.getToken()); + sb.append(ASEmitterTokens.NEW_LINE.getToken()); + } + } + } + eventSpecifier.value = sb.toString(); + + if (currentDescriptor != null) + currentDescriptor.eventSpecifiers.add(eventSpecifier); + else if (!inStatesOverride) // in theory, if no currentdescriptor must be top tag event + propertiesTree.eventSpecifiers.add(eventSpecifier); + events.add(eventSpecifier); + } + + @Override + public void emitInstance(IMXMLInstanceNode node) + { + if (isStateDependent(node) && !inStatesOverride) + return; + + IClassDefinition cdef = node + .getClassReference((ICompilerProject) getMXMLWalker() + .getProject()); + + MXMLDescriptorSpecifier currentPropertySpecifier = getCurrentDescriptor("ps"); + + String id = node.getID(); + if (id == null) + id = node.getEffectiveID(); + if (id == null) + id = MXMLFlexJSEmitterTokens.ID_PREFIX.getToken() + idCounter++; + + MXMLDescriptorSpecifier currentInstance = new MXMLDescriptorSpecifier(); + currentInstance.isProperty = false; + currentInstance.id = id; + currentInstance.name = formatQualifiedName(cdef.getQualifiedName()); + currentInstance.parent = currentPropertySpecifier; + + if (currentPropertySpecifier != null) + currentPropertySpecifier.propertySpecifiers.add(currentInstance); + else if (inMXMLContent) + descriptorTree.add(currentInstance); + else + { + currentInstance.parent = propertiesTree; + propertiesTree.propertySpecifiers.add(currentInstance); + } + + instances.add(currentInstance); + + IMXMLPropertySpecifierNode[] pnodes = node.getPropertySpecifierNodes(); + if (pnodes != null) + { + moveDown(false, currentInstance, null); + + for (IMXMLPropertySpecifierNode pnode : pnodes) + { + getMXMLWalker().walk(pnode); // Property Specifier + } + + moveUp(false, true); + } + else if (node instanceof IMXMLStateNode) + { + IMXMLStateNode stateNode = (IMXMLStateNode)node; + String name = stateNode.getStateName(); + if (name != null) + { + MXMLDescriptorSpecifier stateName = new MXMLDescriptorSpecifier(); + stateName.isProperty = true; + stateName.id = id; + stateName.name = "name"; + stateName.value = ASEmitterTokens.SINGLE_QUOTE.getToken() + name + ASEmitterTokens.SINGLE_QUOTE.getToken(); + stateName.parent = currentInstance; + currentInstance.propertySpecifiers.add(stateName); + } + MXMLDescriptorSpecifier overrides = new MXMLDescriptorSpecifier(); + overrides.isProperty = true; + overrides.hasArray = true; + overrides.id = id; + overrides.name = "overrides"; + overrides.parent = currentInstance; + currentInstance.propertySpecifiers.add(overrides); + moveDown(false, null, overrides); + + IMXMLClassDefinitionNode classDefinitionNode = stateNode.getClassDefinitionNode(); + List<IMXMLNode> snodes = classDefinitionNode.getNodesDependentOnState(stateNode.getStateName()); + if (snodes != null) + { + for (int i=snodes.size()-1; i>=0; --i) + { + IMXMLNode inode = snodes.get(i); + if (inode.getNodeID() == ASTNodeID.MXMLInstanceID) + { + emitInstanceOverride((IMXMLInstanceNode)inode); + } + } + // Next process the non-instance overrides dependent on this state. + // Each one will generate code to push an IOverride instance. + for (IMXMLNode anode : snodes) + { + switch (anode.getNodeID()) + { + case MXMLPropertySpecifierID: + { + emitPropertyOverride((IMXMLPropertySpecifierNode)anode); + break; + } + case MXMLStyleSpecifierID: + { + emitStyleOverride((IMXMLStyleSpecifierNode)anode); + break; + } + case MXMLEventSpecifierID: + { + emitEventOverride((IMXMLEventSpecifierNode)anode); + break; + } + default: + { + break; + } + } + } + } + + moveUp(false, false); + } + + IMXMLEventSpecifierNode[] enodes = node.getEventSpecifierNodes(); + if (enodes != null) + { + moveDown(false, currentInstance, null); + + for (IMXMLEventSpecifierNode enode : enodes) + { + getMXMLWalker().walk(enode); // Event Specifier + } + + moveUp(false, true); + } + } + + public void emitPropertyOverride(IMXMLPropertySpecifierNode propertyNode) + { + FlexProject project = (FlexProject) getMXMLWalker().getProject(); + Name propertyOverride = project.getPropertyOverrideClassName(); + emitPropertyOrStyleOverride(propertyOverride, propertyNode); + } + + /** + * Generates instructions in the current context + * to create an instance of mx.states.SetStyle + * with its <code>target</code>, <code>name</code>, + * and <code>value</code> properties set. + */ + void emitStyleOverride(IMXMLStyleSpecifierNode styleNode) + { + FlexProject project = (FlexProject) getMXMLWalker().getProject(); + Name styleOverride = project.getStyleOverrideClassName(); + emitPropertyOrStyleOverride(styleOverride, styleNode); + } + + void emitPropertyOrStyleOverride(Name overrideName, IMXMLPropertySpecifierNode propertyOrStyleNode) + { + MXMLDescriptorSpecifier currentInstance = getCurrentDescriptor("ps"); + IASNode parentNode = propertyOrStyleNode.getParent(); + String id = parentNode instanceof IMXMLInstanceNode ? + ((IMXMLInstanceNode)parentNode).getEffectiveID() : + null; + + String name = propertyOrStyleNode.getName(); + + boolean valueIsDataBound = isDataBindingNode(propertyOrStyleNode.getChild(0)); + IMXMLInstanceNode propertyOrStyleValueNode = propertyOrStyleNode.getInstanceNode(); + + MXMLDescriptorSpecifier setProp = new MXMLDescriptorSpecifier(); + setProp.isProperty = false; + setProp.name = formatQualifiedName(nameToString(overrideName)); + setProp.parent = currentInstance; + currentInstance.propertySpecifiers.add(setProp); + + if (id != null) + { + // Set its 'target' property to the id of the object + // whose property or style this override will set. + MXMLDescriptorSpecifier target = new MXMLDescriptorSpecifier(); + target.isProperty = true; + target.name = "target"; + target.parent = setProp; + target.value = ASEmitterTokens.SINGLE_QUOTE.getToken() + id + ASEmitterTokens.SINGLE_QUOTE.getToken(); + setProp.propertySpecifiers.add(target); + } + + // Set its 'name' property to the name of the property or style. + MXMLDescriptorSpecifier pname = new MXMLDescriptorSpecifier(); + pname.isProperty = true; + pname.name = "name"; + pname.parent = setProp; + pname.value = ASEmitterTokens.SINGLE_QUOTE.getToken() + name + ASEmitterTokens.SINGLE_QUOTE.getToken(); + setProp.propertySpecifiers.add(pname); + + if (!valueIsDataBound) + { + // Set its 'value' property to the value of the property or style. + MXMLDescriptorSpecifier value = new MXMLDescriptorSpecifier(); + value.isProperty = true; + value.name = "value"; + value.parent = setProp; + setProp.propertySpecifiers.add(value); + moveDown(false, null, value); + getMXMLWalker().walk(propertyOrStyleValueNode); // instance node + moveUp(false, false); + } + else + { + String overrideID = MXMLFlexJSEmitterTokens.BINDING_PREFIX.getToken() + bindingCounter++; + setProp.id = overrideID; + instances.add(setProp); + BindingDatabase bd = BindingDatabase.bindingMap.get(classDefinition); + Set<BindingInfo> bindingInfo = bd.getBindingInfo(); + IMXMLDataBindingNode bindingNode = (IMXMLDataBindingNode)propertyOrStyleNode.getChild(0); + for (BindingInfo bi : bindingInfo) + { + if (bi.node == bindingNode) + { + bi.setDestinationString(overrideID + ".value"); + break; + } + } + } + } + + /** + * Generates instructions in the current context + * to create an instance of mx.states.SetEventHandler + * with its <code>target</code>, <code>name</code>, + * and <code>handlerFunction</code> properties set. + */ + void emitEventOverride(IMXMLEventSpecifierNode eventNode) + { + inStatesOverride = true; + + MXMLDescriptorSpecifier currentInstance = getCurrentDescriptor("ps"); + FlexProject project = (FlexProject) getMXMLWalker().getProject(); + Name eventOverride = project.getEventOverrideClassName(); + + IASNode parentNode = eventNode.getParent(); + String id = parentNode instanceof IMXMLInstanceNode ? + ((IMXMLInstanceNode)parentNode).getEffectiveID() : + ""; + + String name = MXMLEventSpecifier.getJSEventName(eventNode.getName()); + + String eventHandler = eventHandlerNameMap.get(eventNode); + if (eventHandler == null) + { + emitEventSpecifier(eventNode); + eventHandler = eventHandlerNameMap.get(eventNode); + } + + MXMLDescriptorSpecifier setEvent = new MXMLDescriptorSpecifier(); + setEvent.isProperty = false; + setEvent.name = formatQualifiedName(nameToString(eventOverride)); + setEvent.parent = currentInstance; + currentInstance.propertySpecifiers.add(setEvent); + // Set its 'target' property to the id of the object + // whose event this override will set. + MXMLDescriptorSpecifier target = new MXMLDescriptorSpecifier(); + target.isProperty = true; + target.name = "target"; + target.parent = setEvent; + target.value = ASEmitterTokens.SINGLE_QUOTE.getToken() + id + ASEmitterTokens.SINGLE_QUOTE.getToken(); + setEvent.propertySpecifiers.add(target); + + // Set its 'name' property to the name of the event. + MXMLDescriptorSpecifier pname = new MXMLDescriptorSpecifier(); + pname.isProperty = true; + pname.name = "name"; + pname.parent = setEvent; + pname.value = ASEmitterTokens.SINGLE_QUOTE.getToken() + name + ASEmitterTokens.SINGLE_QUOTE.getToken(); + setEvent.propertySpecifiers.add(pname); + + // Set its 'handlerFunction' property to the autogenerated event handler. + MXMLDescriptorSpecifier handler = new MXMLDescriptorSpecifier(); + handler.isProperty = true; + handler.name = "handlerFunction"; + handler.parent = setEvent; + handler.value = JSFlexJSEmitterTokens.CLOSURE_FUNCTION_NAME.getToken() + ASEmitterTokens.PAREN_OPEN.getToken() + + ASEmitterTokens.THIS.getToken() + ASEmitterTokens.MEMBER_ACCESS.getToken() + eventHandler + + ASEmitterTokens.COMMA.getToken() + ASEmitterTokens.SPACE.getToken() + ASEmitterTokens.THIS.getToken() + + ASEmitterTokens.COMMA.getToken() + ASEmitterTokens.SPACE.getToken() + ASEmitterTokens.SINGLE_QUOTE.getToken() + + eventHandler + ASEmitterTokens.SINGLE_QUOTE.getToken() + + ASEmitterTokens.PAREN_CLOSE.getToken(); + setEvent.propertySpecifiers.add(handler); + + inStatesOverride = false; + } + + public void emitInstanceOverride(IMXMLInstanceNode instanceNode) + { + inStatesOverride = true; + + MXMLDescriptorSpecifier currentInstance = getCurrentDescriptor("ps"); + FlexProject project = (FlexProject) getMXMLWalker().getProject(); + Name instanceOverrideName = project.getInstanceOverrideClassName(); + + MXMLDescriptorSpecifier overrideInstances = getCurrentDescriptor("so"); + int index = overrideInstances.propertySpecifiers.size(); + if (nodeToIndexMap == null) + nodeToIndexMap = new HashMap<IMXMLNode, Integer>(); + if (nodeToIndexMap.containsKey(instanceNode)) + { + index = nodeToIndexMap.get(instanceNode); + } + else + { + nodeToIndexMap.put(instanceNode, index); + MXMLDescriptorSpecifier itemsDesc = new MXMLDescriptorSpecifier(); + itemsDesc.isProperty = true; + itemsDesc.hasArray = true; + itemsDesc.name = "itemsDescriptor"; + itemsDesc.parent = overrideInstances; + overrideInstances.propertySpecifiers.add(itemsDesc); + boolean oldInMXMLContent = inMXMLContent; + moveDown(false, null, itemsDesc); + inMXMLContent = true; + getMXMLWalker().walk(instanceNode); // instance node + inMXMLContent = oldInMXMLContent; + moveUp(false, false); + } + + MXMLDescriptorSpecifier addItems = new MXMLDescriptorSpecifier(); + addItems.isProperty = false; + addItems.name = formatQualifiedName(nameToString(instanceOverrideName)); + addItems.parent = currentInstance; + currentInstance.propertySpecifiers.add(addItems); + MXMLDescriptorSpecifier itemsDescIndex = new MXMLDescriptorSpecifier(); + itemsDescIndex.isProperty = true; + itemsDescIndex.hasArray = true; + itemsDescIndex.name = "itemsDescriptorIndex"; + itemsDescIndex.parent = addItems; + itemsDescIndex.value = Integer.toString(index); + addItems.propertySpecifiers.add(itemsDescIndex); + + //----------------------------------------------------------------------------- + // Second property set: maybe set destination and propertyName + + // get the property specifier node for the property the instanceNode represents + IMXMLPropertySpecifierNode propertySpecifier = (IMXMLPropertySpecifierNode) + instanceNode.getAncestorOfType( IMXMLPropertySpecifierNode.class); + + if (propertySpecifier == null) + { + assert false; // I think this indicates an invalid tree... + } + else + { + // Check the parent - if it's an instance then we want to use these + // nodes to get our property values from. If not, then it's the root + // and we don't need to specify destination + + IASNode parent = propertySpecifier.getParent(); + if (parent instanceof IMXMLInstanceNode) + { + IMXMLInstanceNode parentInstance = (IMXMLInstanceNode)parent; + String parentId = parentInstance.getEffectiveID(); + assert parentId != null; + String propName = propertySpecifier.getName(); + + MXMLDescriptorSpecifier dest = new MXMLDescriptorSpecifier(); + dest.isProperty = true; + dest.name = "destination"; + dest.parent = addItems; + dest.value = ASEmitterTokens.SINGLE_QUOTE.getToken() + parentId + ASEmitterTokens.SINGLE_QUOTE.getToken(); + addItems.propertySpecifiers.add(dest); + + MXMLDescriptorSpecifier prop = new MXMLDescriptorSpecifier(); + prop.isProperty = true; + prop.name = "propertyName"; + prop.parent = addItems; + prop.value = ASEmitterTokens.SINGLE_QUOTE.getToken() + propName + ASEmitterTokens.SINGLE_QUOTE.getToken(); + addItems.propertySpecifiers.add(prop); + } + } + + //--------------------------------------------------------------- + // Third property set: position and relativeTo + String positionPropertyValue = null; + String relativeToPropertyValue = null; + + // look to see if we have any sibling nodes that are not state dependent + // that come BEFORE us + IASNode instanceParent = instanceNode.getParent(); + IASNode prevStatelessSibling=null; + for (int i=0; i< instanceParent.getChildCount(); ++i) + { + IASNode sib = instanceParent.getChild(i); + assert sib instanceof IMXMLInstanceNode; // surely our siblings are also instances? + + // stop looking for previous nodes when we find ourself + if (sib == instanceNode) + break; + + if (sib instanceof IMXMLInstanceNode && !isStateDependent(sib)) + { + prevStatelessSibling = sib; + } + } + + if (prevStatelessSibling == null) { + positionPropertyValue = "first"; // TODO: these should be named constants + } + else { + positionPropertyValue = "after"; + relativeToPropertyValue = ((IMXMLInstanceNode)prevStatelessSibling).getEffectiveID(); + } + + MXMLDescriptorSpecifier pos = new MXMLDescriptorSpecifier(); + pos.isProperty = true; + pos.name = "position"; + pos.parent = addItems; + pos.value = ASEmitterTokens.SINGLE_QUOTE.getToken() + positionPropertyValue + ASEmitterTokens.SINGLE_QUOTE.getToken(); + addItems.propertySpecifiers.add(pos); + + if (relativeToPropertyValue != null) + { + MXMLDescriptorSpecifier rel = new MXMLDescriptorSpecifier(); + rel.isProperty = true; + rel.name = "relativeTo"; + rel.parent = addItems; + rel.value = ASEmitterTokens.SINGLE_QUOTE.getToken() + relativeToPropertyValue + ASEmitterTokens.SINGLE_QUOTE.getToken(); + addItems.propertySpecifiers.add(rel); + } + + inStatesOverride = false; + } + + private String nameToString(Name name) + { + String s; + Namespace ns = name.getSingleQualifier(); + s = ns.getName(); + if (s != "") s = s + ASEmitterTokens.MEMBER_ACCESS.getToken() + name.getBaseName(); + else s = name.getBaseName(); + return s; + } + /** + * Determines whether a node is state-dependent. + * TODO: we should move to IMXMLNode + */ + protected boolean isStateDependent(IASNode node) + { + if (node instanceof IMXMLSpecifierNode) + { + String suffix = ((IMXMLSpecifierNode)node).getSuffix(); + return suffix != null && suffix.length() > 0; + } + else if (isStateDependentInstance(node)) + return true; + return false; + } + + /** + * Determines whether the geven node is an instance node, as is state dependent + */ + protected boolean isStateDependentInstance(IASNode node) + { + if (node instanceof IMXMLInstanceNode) + { + String[] includeIn = ((IMXMLInstanceNode)node).getIncludeIn(); + String[] excludeFrom = ((IMXMLInstanceNode)node).getExcludeFrom(); + return includeIn != null || excludeFrom != null; + } + return false; + } + + /** + * Is a give node a "databinding node"? + */ + public static boolean isDataBindingNode(IASNode node) + { + return node instanceof IMXMLDataBindingNode; + } + + protected static boolean isDataboundProp(IMXMLPropertySpecifierNode propertyNode) + { + boolean ret = propertyNode.getChildCount() > 0 && isDataBindingNode(propertyNode.getInstanceNode()); + + // Sanity check that we based our conclusion about databinding on the correct node. + // (code assumes only one child if databinding) + int n = propertyNode.getChildCount(); + for (int i = 0; i < n; i++) + { + boolean db = isDataBindingNode(propertyNode.getChild(i)); + assert db == ret; + } + + return ret; + } + + @Override + public void emitPropertySpecifier(IMXMLPropertySpecifierNode node) + { + if (isDataboundProp(node)) + return; + + if (isStateDependent(node)) + return; + + IDefinition cdef = node.getDefinition(); + + IASNode cnode = node.getChild(0); + + MXMLDescriptorSpecifier currentInstance = getCurrentDescriptor("i"); + + MXMLDescriptorSpecifier currentPropertySpecifier = new MXMLDescriptorSpecifier(); + currentPropertySpecifier.isProperty = true; + currentPropertySpecifier.name = cdef.getQualifiedName(); + currentPropertySpecifier.parent = currentInstance; + + boolean oldInMXMLContent = inMXMLContent; + boolean reusingDescriptor = false; + if (currentPropertySpecifier.name.equals("mxmlContent")) + { + inMXMLContent = true; + ArrayList<MXMLDescriptorSpecifier> specList = + (currentInstance == null) ? descriptorTree : currentInstance.propertySpecifiers; + for (MXMLDescriptorSpecifier ds : specList) + { + if (ds.name.equals("mxmlContent")) + { + currentPropertySpecifier = ds; + reusingDescriptor = true; + break; + } + } + } + + if (currentInstance != null) + { + // we end up here for children of tags + if (!reusingDescriptor) + currentInstance.propertySpecifiers.add(currentPropertySpecifier); + } + else if (inMXMLContent) + { + // we end up here for top tags? + if (!reusingDescriptor) + descriptorTree.add(currentPropertySpecifier); + } + else + { + currentPropertySpecifier.parent = propertiesTree; + propertiesTree.propertySpecifiers.add(currentPropertySpecifier); + } + + boolean valueIsArray = cnode != null && cnode instanceof IMXMLArrayNode; + boolean valueIsObject = cnode != null && cnode instanceof IMXMLObjectNode; + + currentPropertySpecifier.hasArray = valueIsArray; + currentPropertySpecifier.hasObject = valueIsObject; + + moveDown(valueIsArray || valueIsObject, null, currentPropertySpecifier); + + getMXMLWalker().walk(cnode); // Array or Instance + + moveUp(valueIsArray || valueIsObject, false); + + inMXMLContent = oldInMXMLContent; + } + + @Override + public void emitScript(IMXMLScriptNode node) + { + IASEmitter asEmitter = ((IMXMLBlockWalker) getMXMLWalker()) + .getASEmitter(); + + String nl = ASEmitterTokens.NEW_LINE.getToken(); + + StringBuilder sb = null; + MXMLScriptSpecifier scriptSpecifier = null; + + int len = node.getChildCount(); + if (len > 0) + { + for (int i = 0; i < len; i++) + { + IASNode cnode = node.getChild(i); + getMXMLWalker().walk(cnode); + } + } + } + + @Override + public void emitStyleSpecifier(IMXMLStyleSpecifierNode node) + { + } + + //-------------------------------------------------------------------------- + + @Override + public void emitObject(IMXMLObjectNode node) + { + final int len = node.getChildCount(); + if (!makingSimpleArray) + { + for (int i = 0; i < len; i++) + { + getMXMLWalker().walk(node.getChild(i)); // props in object + } + } + else + { + MXMLDescriptorSpecifier ps = getCurrentDescriptor("ps"); + if (ps.value == null) + ps.value = ""; + ps.value += "{"; + for (int i = 0; i < len; i++) + { + IMXMLPropertySpecifierNode propName = (IMXMLPropertySpecifierNode)node.getChild(i); + ps.value += propName.getName() + ": "; + getMXMLWalker().walk(propName.getChild(0)); + if (i < len - 1) + ps.value += ", "; + } + ps.value += "}"; + } + } + + @Override + public void emitArray(IMXMLArrayNode node) + { + moveDown(false, null, null); + + boolean isSimple = true; + final int len = node.getChildCount(); + for (int i = 0; i < len; i++) + { + final IASNode child = node.getChild(i); + ASTNodeID nodeID = child.getNodeID(); + if (nodeID == ASTNodeID.MXMLArrayID || nodeID == ASTNodeID.MXMLInstanceID || nodeID == ASTNodeID.MXMLStateID) + { + isSimple = false; + break; + } + } + boolean oldMakingSimpleArray = makingSimpleArray; + MXMLDescriptorSpecifier ps = getCurrentDescriptor("ps"); + if (isSimple) + { + makingSimpleArray = true; + ps.value = ASEmitterTokens.SQUARE_OPEN.getToken(); + } + for (int i = 0; i < len; i++) + { + getMXMLWalker().walk(node.getChild(i)); // Instance + if (isSimple && i < len - 1) + ps.value += ASEmitterTokens.COMMA.getToken(); + } + if (isSimple) + { + ps.value += ASEmitterTokens.SQUARE_CLOSE.getToken(); + } + makingSimpleArray = oldMakingSimpleArray; + + moveUp(false, false); + } + + @Override + public void emitString(IMXMLStringNode node) + { + getCurrentDescriptor("ps").valueNeedsQuotes = true; + + emitAttributeValue(node); + } + + //-------------------------------------------------------------------------- + + @Override + public void emitLiteral(IMXMLLiteralNode node) + { + MXMLDescriptorSpecifier ps = getCurrentDescriptor("ps"); + if (ps.value == null) // might be non-null if makingSimpleArray + ps.value = ""; + + if (ps.valueNeedsQuotes) + ps.value += ASEmitterTokens.SINGLE_QUOTE.getToken(); + + String s = node.getValue().toString(); + if (ps.valueNeedsQuotes) + { + // escape all single quotes found within the string + s = s.replace(ASEmitterTokens.SINGLE_QUOTE.getToken(), + "\\" + ASEmitterTokens.SINGLE_QUOTE.getToken()); + } + ps.value += s; + + if (ps.valueNeedsQuotes) + ps.value += ASEmitterTokens.SINGLE_QUOTE.getToken(); + } + + //-------------------------------------------------------------------------- + + @Override + public void emitFactory(IMXMLFactoryNode node) + { + MXMLDescriptorSpecifier ps = getCurrentDescriptor("ps"); + ps.value = "new " + formatQualifiedName("org.apache.flex.core.ClassFactory") + "("; + + IASNode cnode = node.getChild(0); + if (cnode instanceof IMXMLClassNode) + { + ps.value += formatQualifiedName(((IMXMLClassNode)cnode).getValue(getMXMLWalker().getProject()).getQualifiedName()); + } + ps.value += ")"; + } + + //-------------------------------------------------------------------------- + + @Override + public void emitComponent(IMXMLComponentNode node) + { + MXMLDescriptorSpecifier ps = getCurrentDescriptor("ps"); + ps.value = "new " + formatQualifiedName("org.apache.flex.core.ClassFactory") + "("; + + ps.value += formatQualifiedName(documentDefinition.getQualifiedName()) + "."; + ps.value += formatQualifiedName(node.getName()); + ps.value += ")"; + + setBufferWrite(true); + emitSubDocument(node); + subDocuments.append(getBuilder().toString()); + getBuilder().setLength(0); + setBufferWrite(false); + } + + @Override + protected void setBufferWrite(boolean value) + { + super.setBufferWrite(value); + IASEmitter asEmitter = ((IMXMLBlockWalker) getMXMLWalker()).getASEmitter(); + ((JSFlexJSASDocEmitter)asEmitter).setBufferWrite(value); + } + + //-------------------------------------------------------------------------- + // JS output + //-------------------------------------------------------------------------- + + private void emitHeader(IMXMLDocumentNode node) + { + String cname = node.getFileNode().getName(); + String bcname = node.getBaseClassName(); + + FlexJSProject project = (FlexJSProject) getMXMLWalker().getProject(); + List<File> sourcePaths = project.getSourcePath(); + String sourceName = node.getSourcePath(); + for (File sourcePath : sourcePaths) + { + if (sourceName.startsWith(sourcePath.getAbsolutePath())) + { + sourceName = sourceName.substring(sourcePath.getAbsolutePath().length() + 1); + } + } + writeNewline("/**"); + writeNewline(" * Generated by Apache Flex Cross-Compiler from " + sourceName); + writeNewline(" * " + cname); + writeNewline(" *"); + writeNewline(" * @fileoverview"); + writeNewline(" *"); + writeNewline(" * @suppress {checkTypes|accessControls}"); + writeNewline(" */"); + writeNewline(); + + ArrayList<String> writtenInstances = new ArrayList<String>(); + emitHeaderLine(cname, true); // provide + for (String subDocumentName : subDocumentNames) + { + emitHeaderLine(subDocumentName, true); + writtenInstances.add(formatQualifiedName(subDocumentName)); + } + writeNewline(); + emitHeaderLine(bcname); + writtenInstances.add(formatQualifiedName(cname)); // make sure we don't add ourselves + writtenInstances.add(formatQualifiedName(bcname)); // make sure we don't add the baseclass twice + allInstances.addAll(0, instances); + for (MXMLDescriptorSpecifier instance : allInstances) + { + String name = instance.name; + if (writtenInstances.indexOf(name) == -1) + { + emitHeaderLine(name); + writtenInstances.add(name); + } + } + ASProjectScope projectScope = (ASProjectScope) project.getScope(); + IDefinition cdef = node.getDefinition(); + ICompilationUnit cu = projectScope + .getCompilationUnitForDefinition(cdef); + ArrayList<String> deps = project.getRequires(cu); + + // TODO (mschmalle) will remove this cast as more things get abstracted + JSFlexJSASDocEmitter fjs = (JSFlexJSASDocEmitter) ((IMXMLBlockWalker) getMXMLWalker()) + .getASEmitter(); + if (fjs.getModel().hasStaticBindableVars()) { + //we need to add EventDispatcher + if (deps.indexOf(BindableEmitter.DISPATCHER_CLASS_QNAME) == -1) + deps.add(BindableEmitter.DISPATCHER_CLASS_QNAME); + if (usedNames.indexOf(BindableEmitter.DISPATCHER_CLASS_QNAME) == -1) + usedNames.add(BindableEmitter.DISPATCHER_CLASS_QNAME); + } + + if (interfaceList != null) + { + String[] interfaces = interfaceList.split(", "); + for (String iface : interfaces) + { + deps.add(iface); + usedNames.add(iface); + } + } + if (deps != null) + { + Collections.sort(deps); + for (String imp : deps) + { + if (imp.indexOf(JSGoogEmitterTokens.AS3.getToken()) != -1) + continue; + + if (imp.equals(cname)) + continue; + + if (imp.equals("mx.binding.Binding")) + continue; + if (imp.equals("mx.binding.BindingManager")) + continue; + if (imp.equals("mx.binding.FunctionReturnWatcher")) + continue; + if (imp.equals("mx.binding.PropertyWatcher")) + continue; + if (imp.equals("mx.binding.StaticPropertyWatcher")) + continue; + if (imp.equals("mx.binding.XMLWatcher")) + continue; + if (imp.equals("mx.events.PropertyChangeEvent")) + continue; + if (imp.equals("mx.events.PropertyChangeEventKind")) + continue; + if (imp.equals("mx.core.DeferredInstanceFromFunction")) + continue; + + if (NativeUtils.isNative(imp)) + continue; + + String formatted = formatQualifiedName(imp, false); + if (writtenInstances.indexOf(formatted) == -1) + { + emitHeaderLine(imp); + writtenInstances.add(formatted); + } + } + } + + // erikdebruin: Add missing language feature support, like the 'is' and + // 'as' operators. We don't need to worry about requiring + // this in every project: ADVANCED_OPTIMISATIONS will NOT + // include any of the code if it is not used in the project. + if (project.mainCU != null && + cu.getName().equals(project.mainCU.getName())) + { + if (project instanceof FlexJSProject) + { + if (((FlexJSProject)project).needLanguage) + emitHeaderLine(JSFlexJSEmitterTokens.LANGUAGE_QNAME.getToken()); + } + } + + writeNewline(); + writeNewline(); + } + + private void emitHeaderLine(String qname) + { + emitHeaderLine(qname, false); + } + + private void emitHeaderLine(String qname, boolean isProvide) + { + write((isProvide) ? JSGoogEmitterTokens.GOOG_PROVIDE + : JSGoogEmitterTokens.GOOG_REQUIRE); + write(ASEmitterTokens.PAREN_OPEN); + write(ASEmitterTokens.SINGLE_QUOTE); + write(formatQualifiedName(qname, false)); + write(ASEmitterTokens.SINGLE_QUOTE); + write(ASEmitterTokens.PAREN_CLOSE); + writeNewline(ASEmitterTokens.SEMICOLON); + } + + private String createRequireLine(String qname, boolean isProvide) { + StringBuilder createHeader = new StringBuilder(); + createHeader.append(isProvide ? JSGoogEmitterTokens.GOOG_PROVIDE.getToken() : JSGoogEmitterTokens.GOOG_REQUIRE.getToken()); + createHeader.append(ASEmitterTokens.PAREN_OPEN.getToken()); + createHeader.append(ASEmitterTokens.SINGLE_QUOTE.getToken()); + createHeader.append(qname); + createHeader.append(ASEmitterTokens.SINGLE_QUOTE.getToken()); + createHeader.append(ASEmitterTokens.PAREN_CLOSE.getToken()); + createHeader.append(ASEmitterTokens.SEMICOLON.getToken()); + return createHeader.toString(); + } + + //-------------------------------------------------------------------------- + // Utils + //-------------------------------------------------------------------------- + + @Override + protected void emitAttributeValue(IASNode node) + { + IMXMLLiteralNode cnode = (IMXMLLiteralNode) node.getChild(0); + + if (cnode.getValue() != null) + getMXMLWalker().walk((IASNode) cnode); // Literal + } + + private MXMLDescriptorSpecifier getCurrentDescriptor(String type) + { + MXMLDescriptorSpecifier currentDescriptor = null; + + int index; + + if (type.equals("i")) + { + index = currentInstances.size() - 1; + if (index > -1) + currentDescriptor = currentInstances.get(index); + } + else if (type.equals("so")) + { + return currentStateOverrides; + } + else + { + index = currentPropertySpecifiers.size() - 1; + if (index > -1) + currentDescriptor = currentPropertySpecifiers.get(index); + } + + return currentDescriptor; + } + + protected void moveDown(boolean byPass, + MXMLDescriptorSpecifier currentInstance, + MXMLDescriptorSpecifier currentPropertySpecifier) + { + if (!byPass) + { + if (currentInstance != null) + currentInstances.add(currentInstance); + } + + if (currentPropertySpecifier != null) + currentPropertySpecifiers.add(currentPropertySpecifier); + } + + protected void moveUp(boolean byPass, boolean isInstance) + { + if (!byPass) + { + int index; + + if (isInstance) + { + index = currentInstances.size() - 1; + if (index > -1) + currentInstances.remove(index); + } + else + { + index = currentPropertySpecifiers.size() - 1; + if (index > -1) + currentPropertySpecifiers.remove(index); + } + } + } + + public String formatQualifiedName(String name) + { + return formatQualifiedName(name, true); + } + + protected String formatQualifiedName(String name, boolean useName) + { + /* + if (name.contains("goog.") || name.startsWith("Vector.")) + return name; + name = name.replaceAll("\\.", "_"); + */ + if (subDocumentNames.contains(name)) + return documentDefinition.getQualifiedName() + "." + name; + if (NativeUtils.isJSNative(name)) return name; + if (useName && !usedNames.contains(name)) + usedNames.add(name); + return name; + } + + private void emitComplexInitializers(IASNode node) + { + int n = node.getChildCount(); + for (int i = 0; i < n; i++) + { + IASNode child = node.getChild(i); + if (child.getNodeID() == ASTNodeID.MXMLScriptID) + { + int m = child.getChildCount(); + for (int j = 0; j < m; j++) + { + IASNode schild = child.getChild(j); + ASTNodeID schildID = schild.getNodeID(); + if (schildID == ASTNodeID.VariableID || + schildID == ASTNodeID.BindableVariableID) + { + IVariableNode varnode = (IVariableNode)schild; + IExpressionNode vnode = varnode.getAssignedValueNode(); + if (vnode != null && (!(varnode.isConst() || EmitterUtils.isScalar(vnode)))) + { + writeNewline(); + write(ASEmitterTokens.THIS); + write(ASEmitterTokens.MEMBER_ACCESS); + write(varnode.getName()); + if (schildID == ASTNodeID.BindableVariableID) + write("_"); // use backing variable + write(ASEmitterTokens.SPACE); + writeToken(ASEmitterTokens.EQUAL); + JSFlexJSASDocEmitter fjs = (JSFlexJSASDocEmitter) ((IMXMLBlockWalker) getMXMLWalker()) + .getASEmitter(); + fjs.getWalker().walk(vnode); + write(ASEmitterTokens.SEMICOLON); + + } + } + } + } + } + } + + @Override + public void emitImplements(IMXMLImplementsNode node) + { + StringBuilder list = new StringBuilder(); + boolean needsComma = false; + IIdentifierNode[] interfaces = node.getInterfaceNodes(); + for (IIdentifierNode iface : interfaces) + { + if (needsComma) + list.append(", "); + list.append(iface.getName()); + needsComma = true; + } + //System.out.println("mxml implements "+list); + interfaceList = list.toString(); + } + +}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/f938cb72/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/js/goog/ASDocConfiguration.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/js/goog/ASDocConfiguration.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/js/goog/ASDocConfiguration.java new file mode 100644 index 0000000..8291c08 --- /dev/null +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/js/goog/ASDocConfiguration.java @@ -0,0 +1,566 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.flex.compiler.internal.driver.js.goog; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.apache.flex.compiler.config.Configuration; +import org.apache.flex.compiler.config.ConfigurationInfo; +import org.apache.flex.compiler.config.ConfigurationValue; +import org.apache.flex.compiler.exceptions.ConfigurationException; +import org.apache.flex.compiler.internal.config.COMPCConfiguration; + +/** + * A Configuration to override some behaviors of the default configuration. + */ +public class ASDocConfiguration extends JSGoogConfiguration +{ + public ASDocConfiguration() + { + super(); + + // Override MXMLC defaults + setDebug(true); + } + + public static Map<String, String> getAliases() + { + Map<String, String> map = new HashMap<String, String>(); + map.put( "o", "output" ); + map.put( "dc", "doc-classes" ); + map.put( "dn", "doc-namespaces" ); + map.put( "ds", "doc-sources" ); + map.putAll(Configuration.getAliases()); + return map; + } + + // + // 'doc-classes' option + // + + private List<String> classes = new ArrayList<String>(); + + public List<String> getClasses() + { + return classes; + } + + public void cfgDocClasses(ConfigurationValue cv, List<String> args) throws ConfigurationException + { + classes.addAll( args ); + } + + public static ConfigurationInfo getDocClassesInfo() + { + return new ConfigurationInfo( -1, new String[] { "class" } ) + { + public boolean allowMultiple() + { + return true; + } + }; + } + + /** + * @return Normalized file paths of the included source files. + */ + @Override + public List<String> getIncludeClasses() + { + return classes; + } + + + // + // 'doc-namespaces' option + // + + private List<String> namespaces = new ArrayList<String>(); + + public List<String> getNamespaces() + { + return namespaces; + } + + public void cfgDocNamespaces(ConfigurationValue val, List<String> DocNamespaces) + { + namespaces.addAll(DocNamespaces); + } + + public static ConfigurationInfo getDocNamespacesInfo() + { + return new ConfigurationInfo( -1, new String[] { "uri" } ) + { + public boolean allowMultiple() + { + return true; + } + }; + } + + /** + * @return Normalized file paths of the included source files. + */ + @Override + public List<String> getIncludeNamespaces() + { + return namespaces; + } + + // + // 'doc-sources' option + // + + private List<String> sources = new ArrayList<String>(); + + public List<String> getDocSources() + { + return sources; + } + + public void cfgDocSources(ConfigurationValue cv, List<String> args) throws ConfigurationException + { + sources.addAll( args ); + } + + public static ConfigurationInfo getDocSourcesInfo() + { + return new ConfigurationInfo( -1, new String[] { "path-element" } ) + { + public boolean allowMultiple() + { + return true; + } + + public boolean isPath() + { + return true; + } + }; + } + + /** + * @return Normalized file paths of the included source files. + */ + @Override + public List<String> getIncludeSources() + { + return sources; + } + + + // + // 'examples-path' option + // + + private String examplesPath; + + public String getExamplesPath() + { + return examplesPath; + } + + public void cfgExamplesPath(ConfigurationValue cv, String str) throws ConfigurationException + { + File file = new File(str); + if (! file.isDirectory()) + { + throw new ConfigurationException.NotDirectory( str, cv.getVar(), cv.getSource(), cv.getLine() ); + } + examplesPath = file.getAbsolutePath().replace('\\', '/'); + } + + // + // 'exclude-classes' option + // + + private List<String> excludeClasses = new ArrayList<String>(); + + public List<String> getExcludeClasses() + { + return excludeClasses; + } + + public void cfgExcludeClasses(ConfigurationValue cv, List<String> args) throws ConfigurationException + { + excludeClasses.addAll( args ); + } + + public static ConfigurationInfo getExcludeClassesInfo() + { + return new ConfigurationInfo( -1, new String[] { "class" } ) + { + public boolean allowMultiple() + { + return true; + } + }; + } + + // + // 'exclude-dependencies' option + // + + private boolean excludeDependencies; + + public boolean excludeDependencies() + { + return excludeDependencies; + } + + public void cfgExcludeDependencies(ConfigurationValue val, boolean bool) + { + this.excludeDependencies = bool; + } + + // + // 'footer' option + // + + private String footer; + + public String getFooter() + { + return footer; + } + + public void cfgFooter(ConfigurationValue cv, String str) throws ConfigurationException + { + footer = str; + } + + // + // 'help' option + // + + // dummy, just a trigger for help text + public void cfgHelp(ConfigurationValue cv, String[] keywords) + { + // intercepted upstream in order to allow help text to be printed even when args are otherwise bad + } + + public static ConfigurationInfo getHelpInfo() + { + return new ConfigurationInfo( -1, "keyword" ) + { + public boolean isGreedy() + { + return true; + } + + public boolean isDisplayed() + { + return false; + } + }; + } + // + // 'keep-xml' option + // + + private boolean keepXML; + + public boolean keepXml() + { + return keepXML; + } + + public void cfgKeepXml(ConfigurationValue cv, boolean b) throws ConfigurationException + { + keepXML = b; + } + + public static ConfigurationInfo getKeepXmlInfo() + { + return new ConfigurationInfo() + { + public boolean isHidden() + { + return true; + } + }; + } + + // + // 'left-frameset-width' option + // + + private int leftFramesetWidth; + + public int getLeftFramesetWidth() + { + return leftFramesetWidth; + } + + public void cfgLeftFramesetWidth(ConfigurationValue val, int left) + { + this.leftFramesetWidth = left; + } + + // + // 'load-config' p[topm + // + + // dummy, ignored - pulled out of the buffer + public void cfgLoadConfig(ConfigurationValue cv, String filename) throws ConfigurationException + { + } + + public static ConfigurationInfo getLoadConfigInfo() + { + return new ConfigurationInfo( 1, "filename" ) + { + public boolean allowMultiple() + { + return true; + } + }; + } + + // + // 'main-title' option + // + + private String mainTitle; + + public String getMainTitle() + { + return mainTitle; + } + + public void cfgMainTitle(ConfigurationValue cv, String str) throws ConfigurationException + { + mainTitle = str; + } + + // + // 'package-description-file' option + // + private String packageDescriptionFile; + + public String getPackageDescriptionFile() + { + return packageDescriptionFile; + } + + public void cfgPackageDescriptionFile(ConfigurationValue cv, String str) throws ConfigurationException + { + File file = new File(str); + if (!file.exists() || file.isDirectory()) + { + throw new ConfigurationException.NotAFile( str, cv.getVar(), cv.getSource(), cv.getLine() ); + } + packageDescriptionFile = file.getAbsolutePath().replace('\\', '/'); + } + + // + // 'skip-xsl' option + // + + private boolean skipXSL; + + public boolean skipXsl() + { + return skipXSL; + } + + public void cfgSkipXsl(ConfigurationValue cv, boolean b) throws ConfigurationException + { + skipXSL = b; + } + + public static ConfigurationInfo getSkipXslInfo() + { + return new ConfigurationInfo() + { + public boolean isHidden() + { + return true; + } + }; + } + + // + // 'templates-path' option + // + + private String templatesPath; + + public String getTemplatesPath() + { + return templatesPath; + } + + public void cfgTemplatesPath(ConfigurationValue val, String basedir) throws ConfigurationException + { + this.templatesPath = basedir; + } + + // + // 'version' option + // + + // dummy, just a trigger for version info + public void cfgVersion(ConfigurationValue cv, boolean dummy) + { + // intercepted upstream in order to allow version into to be printed even when required args are missing + } + + // + // 'window-title' option + // + + private String windowTitle; + + public String getWindowTitle() + { + return windowTitle; + } + + public void cfgWindowTitle(ConfigurationValue cv, String str) throws ConfigurationException + { + windowTitle = str; + } + + // + // 'restore-builtin-classes' option + // + + private boolean restoreBuiltinClasses; + + public boolean restoreBuiltinClasses() + { + return restoreBuiltinClasses; + } + + public void cfgRestoreBuiltinClasses(ConfigurationValue cv, boolean b) throws ConfigurationException + { + restoreBuiltinClasses = b; + } + + // restore-builtin-classes is only for internal use + public static ConfigurationInfo getRestoreBuiltinClassesInfo() + { + return new ConfigurationInfo() + { + public boolean isHidden() + { + return true; + } + }; + } + + + // + // 'lenient' option + // + + private boolean lenient; + + public boolean isLenient() + { + return lenient; + } + + public void cfgLenient(ConfigurationValue cv, boolean b) throws ConfigurationException + { + lenient = b; + } + + // + // 'exclude-sources' option + // + + private List<String> excludeSources = new ArrayList<String>(); + + public List<String> getExcludeSources() + { + return excludeSources; + } + + public void cfgExcludeSources(ConfigurationValue cv, List<String> args) throws ConfigurationException + { + excludeSources.addAll( args ); + } + + public static ConfigurationInfo getExcludeSourcesInfo() + { + return new ConfigurationInfo( -1, new String[] { "path-element" } ) + { + public boolean allowMultiple() + { + return true; + } + + public boolean isPath() + { + return true; + } + }; + } + + // + // 'date-in-footer' option + // + + private boolean dateInFooter = true; + + public boolean getDateInFooter() + { + return dateInFooter; + } + + public void cfgDateInFooter(ConfigurationValue cv, boolean b) throws ConfigurationException + { + dateInFooter = b; + } + + // + // 'include-all-for-asdoc' option + // + private boolean includeAllForAsdoc; + + public boolean isIncludeAllForAsdoc() + { + return includeAllForAsdoc; + } + + public void cfgIncludeAllForAsdoc(ConfigurationValue cv, boolean b) throws ConfigurationException + { + includeAllForAsdoc = b; + } + + // include-all-only is only for internal use + public static ConfigurationInfo getIncludeAllForAsdoc() + { + return new ConfigurationInfo() + { + public boolean isHidden() + { + return true; + } + }; + } +} http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/f938cb72/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/mxml/ASDocASSourceFileHandler.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/mxml/ASDocASSourceFileHandler.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/mxml/ASDocASSourceFileHandler.java new file mode 100644 index 0000000..f49d4b5 --- /dev/null +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/mxml/ASDocASSourceFileHandler.java @@ -0,0 +1,89 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.flex.compiler.internal.driver.mxml; + +import org.apache.flex.compiler.internal.driver.js.goog.ASDocConfiguration; +import org.apache.flex.compiler.internal.projects.CompilerProject; +import org.apache.flex.compiler.internal.projects.DefinitionPriority; +import org.apache.flex.compiler.internal.projects.FlexJSProject; +import org.apache.flex.compiler.internal.projects.ISourceFileHandler; +import org.apache.flex.compiler.internal.units.ASCompilationUnit; +import org.apache.flex.compiler.internal.units.MXMLCompilationUnit; +import org.apache.flex.compiler.units.ICompilationUnit; + +/** + * Implementation of ISourceFileHandler that constructs + * {@link ASCompilationUnit}'s. MXMLSourceFileHandler is the SourceFileHandler + * that provides JSCompilationUnit for *.mxml files. JSDriver registers + * MXMLSourceFileHandler at FlexApplicationProject. This implementation is part + * of FalconJS. For more details on FalconJS see + * org.apache.flex.compiler.JSDriver + */ +public final class ASDocASSourceFileHandler implements ISourceFileHandler +{ + + public static final String EXTENSION = "as"; //$NON-NLS-1$ + public static final ASDocASSourceFileHandler INSTANCE = new ASDocASSourceFileHandler(); + + private ASDocASSourceFileHandler() + { + } + + /** + * {@inheritDoc} + */ + @Override + public String[] getExtensions() + { + return new String[] { EXTENSION }; + } + + /** + * {@inheritDoc} + */ + @Override + public ICompilationUnit createCompilationUnit(CompilerProject proj, + String path, DefinitionPriority.BasePriority basePriority, + int order, String qname, String locale) + { + return new ASCompilationUnit(proj, path, basePriority, order, qname); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean needCompilationUnit(CompilerProject project, String path, + String qname, String locale) + { + FlexJSProject fproject = (FlexJSProject)project; + ASDocConfiguration config = (ASDocConfiguration)(fproject.configurator.getConfiguration()); + return !(config.getExcludeSources().contains(path)); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean canCreateInvisibleCompilationUnit() + { + return false; + } +} http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/f938cb72/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/mxml/ASDocMXMLSourceFileHandler.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/mxml/ASDocMXMLSourceFileHandler.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/mxml/ASDocMXMLSourceFileHandler.java new file mode 100644 index 0000000..17f45e9 --- /dev/null +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/mxml/ASDocMXMLSourceFileHandler.java @@ -0,0 +1,89 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.flex.compiler.internal.driver.mxml; + +import org.apache.flex.compiler.internal.driver.js.goog.ASDocConfiguration; +import org.apache.flex.compiler.internal.projects.CompilerProject; +import org.apache.flex.compiler.internal.projects.DefinitionPriority; +import org.apache.flex.compiler.internal.projects.FlexJSProject; +import org.apache.flex.compiler.internal.projects.ISourceFileHandler; +import org.apache.flex.compiler.internal.units.ASCompilationUnit; +import org.apache.flex.compiler.internal.units.MXMLCompilationUnit; +import org.apache.flex.compiler.units.ICompilationUnit; + +/** + * Implementation of ISourceFileHandler that constructs + * {@link ASCompilationUnit}'s. MXMLSourceFileHandler is the SourceFileHandler + * that provides JSCompilationUnit for *.mxml files. JSDriver registers + * MXMLSourceFileHandler at FlexApplicationProject. This implementation is part + * of FalconJS. For more details on FalconJS see + * org.apache.flex.compiler.JSDriver + */ +public final class ASDocMXMLSourceFileHandler implements ISourceFileHandler +{ + + public static final String EXTENSION = "mxml"; //$NON-NLS-1$ + public static final ASDocMXMLSourceFileHandler INSTANCE = new ASDocMXMLSourceFileHandler(); + + private ASDocMXMLSourceFileHandler() + { + } + + /** + * {@inheritDoc} + */ + @Override + public String[] getExtensions() + { + return new String[] { EXTENSION }; + } + + /** + * {@inheritDoc} + */ + @Override + public ICompilationUnit createCompilationUnit(CompilerProject proj, + String path, DefinitionPriority.BasePriority basePriority, + int order, String qname, String locale) + { + return new MXMLCompilationUnit(proj, path, basePriority, order, qname); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean needCompilationUnit(CompilerProject project, String path, + String qname, String locale) + { + FlexJSProject fproject = (FlexJSProject)project; + ASDocConfiguration config = (ASDocConfiguration)(fproject.config); + return !(config.getExcludeSources().contains(path)); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean canCreateInvisibleCompilationUnit() + { + return false; + } +} http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/f938cb72/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/mxml/flexjs/MXMLFlexJSASDocBackend.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/mxml/flexjs/MXMLFlexJSASDocBackend.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/mxml/flexjs/MXMLFlexJSASDocBackend.java new file mode 100644 index 0000000..4816fd2 --- /dev/null +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/mxml/flexjs/MXMLFlexJSASDocBackend.java @@ -0,0 +1,140 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.flex.compiler.internal.driver.mxml.flexjs; + +import java.io.FilterWriter; +import java.util.List; + +import org.apache.flex.compiler.codegen.IDocEmitter; +import org.apache.flex.compiler.codegen.as.IASEmitter; +import org.apache.flex.compiler.codegen.js.IJSEmitter; +import org.apache.flex.compiler.codegen.js.IJSWriter; +import org.apache.flex.compiler.codegen.mxml.IMXMLEmitter; +import org.apache.flex.compiler.config.Configurator; +import org.apache.flex.compiler.driver.IBackend; +import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSASDocEmitter; +import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSEmitter; +import org.apache.flex.compiler.internal.codegen.js.goog.JSGoogDocEmitter; +import org.apache.flex.compiler.internal.codegen.mxml.MXMLBlockWalker; +import org.apache.flex.compiler.internal.codegen.mxml.MXMLWriter; +import org.apache.flex.compiler.internal.codegen.mxml.flexjs.MXMLFlexJSASDocEmitter; +import org.apache.flex.compiler.internal.codegen.mxml.flexjs.MXMLFlexJSBlockWalker; +import org.apache.flex.compiler.internal.codegen.mxml.flexjs.MXMLFlexJSEmitter; +import org.apache.flex.compiler.internal.driver.js.goog.ASDocConfiguration; +import org.apache.flex.compiler.internal.driver.js.goog.JSGoogConfiguration; +import org.apache.flex.compiler.internal.driver.mxml.ASDocASSourceFileHandler; +import org.apache.flex.compiler.internal.driver.mxml.MXMLBackend; +import org.apache.flex.compiler.internal.driver.mxml.MXMLSourceFileHandler; +import org.apache.flex.compiler.internal.projects.ISourceFileHandler; +import org.apache.flex.compiler.internal.targets.FlexJSSWCTarget; +import org.apache.flex.compiler.internal.targets.JSTarget; +import org.apache.flex.compiler.internal.visitor.as.ASNodeSwitch; +import org.apache.flex.compiler.internal.visitor.mxml.MXMLNodeSwitch; +import org.apache.flex.compiler.problems.ICompilerProblem; +import org.apache.flex.compiler.projects.IASProject; +import org.apache.flex.compiler.targets.ITargetProgressMonitor; +import org.apache.flex.compiler.targets.ITargetSettings; +import org.apache.flex.compiler.tree.mxml.IMXMLFileNode; +import org.apache.flex.compiler.units.ICompilationUnit; +import org.apache.flex.compiler.visitor.IBlockVisitor; +import org.apache.flex.compiler.visitor.IBlockWalker; +import org.apache.flex.compiler.visitor.mxml.IMXMLBlockWalker; + +/** + * A concrete implementation of the {@link IBackend} API where the + * {@link MXMLBlockWalker} is used to traverse the {@link IMXMLFileNode} AST. + * + * @author Erik de Bruin + */ +public class MXMLFlexJSASDocBackend extends MXMLFlexJSSWCBackend +{ + + @Override + public Configurator createConfigurator() + { + return new Configurator(ASDocConfiguration.class); + } + + @Override + public IMXMLEmitter createMXMLEmitter(FilterWriter out) + { + return new MXMLFlexJSASDocEmitter(out); + } + + @Override + public IMXMLBlockWalker createMXMLWalker(IASProject project, + List<ICompilerProblem> errors, IMXMLEmitter mxmlEmitter, + IASEmitter asEmitter, IBlockWalker asBlockWalker) + { + MXMLBlockWalker walker = new MXMLFlexJSBlockWalker(errors, project, + mxmlEmitter, asEmitter, asBlockWalker); + + ASNodeSwitch asStrategy = new ASNodeSwitch( + (IBlockVisitor) asBlockWalker); + walker.setASStrategy(asStrategy); + + MXMLNodeSwitch mxmlStrategy = new MXMLNodeSwitch(walker); + walker.setMXMLStrategy(mxmlStrategy); + + return walker; + } + + @Override + public IDocEmitter createDocEmitter(IASEmitter emitter) + { + return new JSGoogDocEmitter((IJSEmitter) emitter); + } + + @Override + public IJSEmitter createEmitter(FilterWriter out) + { + IJSEmitter emitter = new JSFlexJSASDocEmitter(out); + emitter.setDocEmitter(createDocEmitter(emitter)); + return emitter; + } + + @Override + public IJSWriter createMXMLWriter(IASProject project, + List<ICompilerProblem> problems, ICompilationUnit compilationUnit, + boolean enableDebug) + { + return new MXMLWriter(project, problems, compilationUnit, enableDebug); + } + + @Override + public JSTarget createTarget(IASProject project, ITargetSettings settings, + ITargetProgressMonitor monitor) + { + return new FlexJSSWCTarget(project, settings, monitor); + } + + @Override + public ISourceFileHandler getSourceFileHandlerInstance() + { + return ASDocASSourceFileHandler.INSTANCE; + } + + @Override + public String getOutputExtension() + { + return "txt"; + } + +} http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/f938cb72/compiler-jx/src/main/java/org/apache/flex/compiler/internal/projects/FlexJSProject.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/projects/FlexJSProject.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/projects/FlexJSProject.java index b63ceb0..3f51e28 100644 --- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/projects/FlexJSProject.java +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/projects/FlexJSProject.java @@ -27,6 +27,7 @@ import java.util.Set; import java.util.TreeSet; import org.apache.flex.compiler.common.DependencyType; +import org.apache.flex.compiler.config.Configurator; import org.apache.flex.compiler.definitions.IDefinition; import org.apache.flex.compiler.definitions.metadata.IMetaTag; import org.apache.flex.compiler.definitions.metadata.IMetaTagAttribute; @@ -71,6 +72,7 @@ public class FlexJSProject extends FlexProject public TreeSet<String> mixinClassNames; public JSGoogConfiguration config; + public Configurator configurator; public ICompilationUnit mainCU;