You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by cd...@apache.org on 2016/04/13 20:56:33 UTC
[41/51] [partial] git commit: [flex-falcon]
[refs/heads/feature/maven-migration-test] - - Check-In of the migrated
project to make error analysis easier
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogEmitter.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogEmitter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogEmitter.java
new file mode 100644
index 0000000..e08fb84
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogEmitter.java
@@ -0,0 +1,1120 @@
+/*
+ *
+ * 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.js.goog;
+
+import java.io.FilterWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.flex.compiler.codegen.IASGlobalFunctionConstants.BuiltinType;
+import org.apache.flex.compiler.codegen.js.goog.IJSGoogDocEmitter;
+import org.apache.flex.compiler.codegen.js.goog.IJSGoogEmitter;
+import org.apache.flex.compiler.common.ASModifier;
+import org.apache.flex.compiler.common.ModifiersSet;
+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.definitions.IPackageDefinition;
+import org.apache.flex.compiler.definitions.ITypeDefinition;
+import org.apache.flex.compiler.definitions.IVariableDefinition;
+import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
+import org.apache.flex.compiler.internal.codegen.js.JSEmitter;
+import org.apache.flex.compiler.internal.codegen.js.JSEmitterTokens;
+import org.apache.flex.compiler.internal.codegen.js.JSSessionModel;
+import org.apache.flex.compiler.internal.codegen.js.utils.EmitterUtils;
+import org.apache.flex.compiler.internal.definitions.AccessorDefinition;
+import org.apache.flex.compiler.internal.definitions.FunctionDefinition;
+import org.apache.flex.compiler.internal.scopes.PackageScope;
+import org.apache.flex.compiler.internal.tree.as.ChainedVariableNode;
+import org.apache.flex.compiler.internal.tree.as.FunctionCallNode;
+import org.apache.flex.compiler.internal.tree.as.FunctionNode;
+import org.apache.flex.compiler.internal.tree.as.MemberAccessExpressionNode;
+import org.apache.flex.compiler.problems.ICompilerProblem;
+import org.apache.flex.compiler.projects.ICompilerProject;
+import org.apache.flex.compiler.scopes.IASScope;
+import org.apache.flex.compiler.tree.ASTNodeID;
+import org.apache.flex.compiler.tree.as.IASNode;
+import org.apache.flex.compiler.tree.as.IAccessorNode;
+import org.apache.flex.compiler.tree.as.IBinaryOperatorNode;
+import org.apache.flex.compiler.tree.as.IClassNode;
+import org.apache.flex.compiler.tree.as.IContainerNode;
+import org.apache.flex.compiler.tree.as.IDefinitionNode;
+import org.apache.flex.compiler.tree.as.IEmbedNode;
+import org.apache.flex.compiler.tree.as.IExpressionNode;
+import org.apache.flex.compiler.tree.as.IForLoopNode;
+import org.apache.flex.compiler.tree.as.IFunctionCallNode;
+import org.apache.flex.compiler.tree.as.IFunctionNode;
+import org.apache.flex.compiler.tree.as.IGetterNode;
+import org.apache.flex.compiler.tree.as.IIdentifierNode;
+import org.apache.flex.compiler.tree.as.IInterfaceNode;
+import org.apache.flex.compiler.tree.as.INamespaceAccessExpressionNode;
+import org.apache.flex.compiler.tree.as.IParameterNode;
+import org.apache.flex.compiler.tree.as.ISetterNode;
+import org.apache.flex.compiler.tree.as.ITypeNode;
+import org.apache.flex.compiler.tree.as.IVariableExpressionNode;
+import org.apache.flex.compiler.tree.as.IVariableNode;
+import org.apache.flex.compiler.utils.ASNodeUtils;
+
+/**
+ * Concrete implementation of the 'goog' JavaScript production.
+ *
+ * @author Michael Schmalle
+ * @author Erik de Bruin
+ */
+public class JSGoogEmitter extends JSEmitter implements IJSGoogEmitter
+{
+ protected List<String> propertyNames = new ArrayList<String>();
+
+ // TODO (mschmalle) Remove this (not used in JSFlexJSEmitter and JSGoogEmitter anymore)
+ public ICompilerProject project;
+
+ private JSGoogDocEmitter docEmitter;
+
+ // TODO (mschmalle) Fix; this is not using the backend doc strategy for replacement
+ @Override
+ public IJSGoogDocEmitter getDocEmitter()
+ {
+ if (docEmitter == null)
+ docEmitter = new JSGoogDocEmitter(this);
+ return docEmitter;
+ }
+
+ @Override
+ public String formatQualifiedName(String name)
+ {
+ return name;
+ }
+
+ //--------------------------------------------------------------------------
+ // Package Level
+ //--------------------------------------------------------------------------
+
+ // XXX DEAD
+ @Override
+ public void emitPackageHeader(IPackageDefinition definition)
+ {
+ IASScope containedScope = definition.getContainedScope();
+ ITypeDefinition type = findType(containedScope.getAllLocalDefinitions());
+ if (type == null)
+ return;
+
+ /* goog.provide('x');\n\n */
+ write(JSGoogEmitterTokens.GOOG_PROVIDE);
+ write(ASEmitterTokens.PAREN_OPEN);
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ write(type.getQualifiedName());
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ write(ASEmitterTokens.PAREN_CLOSE);
+ writeNewline(ASEmitterTokens.SEMICOLON);
+ writeNewline();
+ }
+
+ // XXX DEAD
+ @Override
+ public void emitPackageHeaderContents(IPackageDefinition definition)
+ {
+ PackageScope containedScope = (PackageScope) definition
+ .getContainedScope();
+
+ ITypeDefinition type = findType(containedScope.getAllLocalDefinitions());
+ if (type == null)
+ return;
+
+ List<String> list = EmitterUtils.resolveImports(type);
+ for (String imp : list)
+ {
+ if (imp.indexOf(JSGoogEmitterTokens.AS3.getToken()) != -1)
+ continue;
+
+ /* goog.require('x');\n */
+ write(JSGoogEmitterTokens.GOOG_REQUIRE);
+ write(ASEmitterTokens.PAREN_OPEN);
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ write(imp);
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ write(ASEmitterTokens.PAREN_CLOSE);
+ writeNewline(ASEmitterTokens.SEMICOLON);
+ }
+
+ // (erikdebruin) only write 'closing' line break when there are
+ // actually imports...
+ if (list.size() > 1
+ || (list.size() == 1 && list.get(0).indexOf(
+ JSGoogEmitterTokens.AS3.getToken()) == -1))
+ {
+ writeNewline();
+ }
+ }
+
+ // XXX DEAD
+ @Override
+ public void emitPackageContents(IPackageDefinition definition)
+ {
+ IASScope containedScope = definition.getContainedScope();
+
+ ITypeDefinition type = EmitterUtils.findType(containedScope.getAllLocalDefinitions());
+ if (type != null)
+ {
+ ITypeNode tnode = EmitterUtils.findTypeNode(definition.getNode());
+ if (tnode != null)
+ {
+ getWalker().walk(tnode); // IClassNode | IInterfaceNode
+ }
+ return;
+ }
+
+ IFunctionDefinition func = EmitterUtils.findFunction(containedScope.getAllLocalDefinitions());
+ if (func != null)
+ {
+ IFunctionNode fnode = EmitterUtils.findFunctionNode(definition.getNode());
+ if (fnode != null)
+ {
+ getWalker().walk(fnode);
+ }
+ return;
+ }
+
+ IVariableDefinition variable = EmitterUtils.findVariable(containedScope.getAllLocalDefinitions());
+ if (variable != null)
+ {
+ IVariableNode vnode = EmitterUtils.findVariableNode(definition.getNode());
+ if (vnode != null)
+ {
+ getWalker().walk(vnode);
+ }
+ }
+ }
+
+ // XXX DEAD
+ @Override
+ public void emitPackageFooter(IPackageDefinition definition)
+ {
+ }
+
+ //--------------------------------------------------------------------------
+ // Class
+ //--------------------------------------------------------------------------
+
+ // XXX DEAD
+ @Override
+ public void emitClass(IClassNode node)
+ {
+ IClassDefinition definition = node.getDefinition();
+ getModel().setCurrentClass(definition);
+
+ IFunctionDefinition ctorDefinition = definition.getConstructor();
+
+ // Static-only (Singleton) classes may not have a constructor
+ if (ctorDefinition != null)
+ {
+ IFunctionNode ctorNode = (IFunctionNode) ctorDefinition.getNode();
+ if (ctorNode != null)
+ {
+ // constructor
+ emitMethod(ctorNode);
+ write(ASEmitterTokens.SEMICOLON);
+ }
+ else
+ {
+ String qname = definition.getQualifiedName();
+ if (qname != null && !qname.equals(""))
+ {
+ write(qname);
+ write(ASEmitterTokens.SPACE);
+ writeToken(ASEmitterTokens.EQUAL);
+ write(ASEmitterTokens.FUNCTION);
+ write(ASEmitterTokens.PAREN_OPEN);
+ write(ASEmitterTokens.PAREN_CLOSE);
+ write(ASEmitterTokens.SPACE);
+ write(ASEmitterTokens.BLOCK_OPEN);
+ writeNewline();
+ write(ASEmitterTokens.BLOCK_CLOSE);
+ write(ASEmitterTokens.SEMICOLON);
+ }
+ }
+ }
+
+ IDefinitionNode[] dnodes = node.getAllMemberNodes();
+ for (IDefinitionNode dnode : dnodes)
+ {
+ if (dnode.getNodeID() == ASTNodeID.VariableID)
+ {
+ writeNewline();
+ writeNewline();
+ emitField((IVariableNode) dnode);
+ write(ASEmitterTokens.SEMICOLON);
+ }
+ else if (dnode.getNodeID() == ASTNodeID.FunctionID)
+ {
+ if (!((IFunctionNode) dnode).isConstructor())
+ {
+ writeNewline();
+ writeNewline();
+ emitMethod((IFunctionNode) dnode);
+ write(ASEmitterTokens.SEMICOLON);
+ }
+ }
+ else if (dnode.getNodeID() == ASTNodeID.GetterID
+ || dnode.getNodeID() == ASTNodeID.SetterID)
+ {
+ writeNewline();
+ writeNewline();
+ emitAccessors((IAccessorNode) dnode);
+ write(ASEmitterTokens.SEMICOLON);
+ }
+ }
+ }
+
+ // XXX Dead [InterfaceEmitter]
+ @Override
+ public void emitInterface(IInterfaceNode node)
+ {
+ ICompilerProject project = getWalker().getProject();
+
+ getDocEmitter().emitInterfaceDoc(node, project);
+
+ String qname = node.getQualifiedName();
+ if (qname != null && !qname.equals(""))
+ {
+ write(formatQualifiedName(qname));
+ write(ASEmitterTokens.SPACE);
+ writeToken(ASEmitterTokens.EQUAL);
+ write(ASEmitterTokens.FUNCTION);
+ write(ASEmitterTokens.PAREN_OPEN);
+ write(ASEmitterTokens.PAREN_CLOSE);
+ write(ASEmitterTokens.SPACE);
+ write(ASEmitterTokens.BLOCK_OPEN);
+ writeNewline();
+ write(ASEmitterTokens.BLOCK_CLOSE);
+ write(ASEmitterTokens.SEMICOLON);
+ }
+
+ final IDefinitionNode[] members = node.getAllMemberDefinitionNodes();
+ for (IDefinitionNode mnode : members)
+ {
+ boolean isAccessor = mnode.getNodeID() == ASTNodeID.GetterID
+ || mnode.getNodeID() == ASTNodeID.SetterID;
+
+ if (!isAccessor || !propertyNames.contains(qname))
+ {
+ writeNewline();
+
+ write(formatQualifiedName(qname));
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ write(JSEmitterTokens.PROTOTYPE);
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ write(mnode.getQualifiedName());
+
+ if (isAccessor && !propertyNames.contains(qname))
+ {
+ propertyNames.add(qname);
+ }
+ else
+ {
+ write(ASEmitterTokens.SPACE);
+ writeToken(ASEmitterTokens.EQUAL);
+ write(ASEmitterTokens.FUNCTION);
+
+ emitParameters(((IFunctionNode) mnode).getParametersContainerNode());
+
+ write(ASEmitterTokens.SPACE);
+ write(ASEmitterTokens.BLOCK_OPEN);
+ writeNewline();
+ write(ASEmitterTokens.BLOCK_CLOSE);
+ }
+
+ write(ASEmitterTokens.SEMICOLON);
+ }
+ }
+ }
+
+ // XXX Dead
+ @Override
+ public void emitField(IVariableNode node)
+ {
+ IClassDefinition definition = EmitterUtils.getClassDefinition(node);
+
+ IDefinition def = null;
+ IExpressionNode enode = node.getVariableTypeNode();//getAssignedValueNode();
+ if (enode != null)
+ def = enode.resolveType(getWalker().getProject());
+
+ getDocEmitter().emitFieldDoc(node, def, getWalker().getProject());
+
+ /* x.prototype.y = z */
+
+ ModifiersSet modifierSet = node.getDefinition().getModifiers();
+ String root = "";
+ if (modifierSet != null && !modifierSet.hasModifier(ASModifier.STATIC))
+ {
+ root = JSEmitterTokens.PROTOTYPE.getToken();
+ root += ASEmitterTokens.MEMBER_ACCESS.getToken();
+ }
+ write(definition.getQualifiedName()
+ + ASEmitterTokens.MEMBER_ACCESS.getToken() + root
+ + node.getName());
+
+ IExpressionNode vnode = node.getAssignedValueNode();
+ if (vnode != null)
+ {
+ write(ASEmitterTokens.SPACE);
+ writeToken(ASEmitterTokens.EQUAL);
+ getWalker().walk(vnode);
+ }
+
+ if (!(node instanceof ChainedVariableNode))
+ {
+ int len = node.getChildCount();
+ for (int i = 0; i < len; i++)
+ {
+ IASNode child = node.getChild(i);
+ if (child instanceof ChainedVariableNode)
+ {
+ writeNewline(ASEmitterTokens.SEMICOLON);
+ writeNewline();
+ emitField((IVariableNode) child);
+ }
+ }
+ }
+ }
+
+ // XXX Dead [VarDeclarationEmitter]
+ @Override
+ public void emitVarDeclaration(IVariableNode node)
+ {
+ if (!(node instanceof ChainedVariableNode) && !node.isConst())
+ {
+ emitMemberKeyword(node);
+ }
+
+ IExpressionNode avnode = node.getAssignedValueNode();
+ if (avnode != null)
+ {
+ IDefinition def = avnode.resolveType(getWalker().getProject());
+
+ String opcode = avnode.getNodeID().getParaphrase();
+ if (opcode != "AnonymousFunction")
+ getDocEmitter().emitVarDoc(node, def, getWalker().getProject());
+ }
+ else
+ {
+ getDocEmitter().emitVarDoc(node, null, getWalker().getProject());
+ }
+
+ emitDeclarationName(node);
+ if (avnode != null && !(avnode instanceof IEmbedNode))
+ {
+ write(ASEmitterTokens.SPACE);
+ writeToken(ASEmitterTokens.EQUAL);
+ emitAssignedValue(avnode);
+ }
+
+ if (!(node instanceof ChainedVariableNode))
+ {
+ // check for chained variables
+ int len = node.getChildCount();
+ for (int i = 0; i < len; i++)
+ {
+ IASNode child = node.getChild(i);
+ if (child instanceof ChainedVariableNode)
+ {
+ writeToken(ASEmitterTokens.COMMA);
+ emitVarDeclaration((IVariableNode) child);
+ }
+ }
+ }
+ }
+
+ // XXX Dead
+ public void emitAccessors(IAccessorNode node)
+ {
+ String qname = node.getQualifiedName();
+ if (!propertyNames.contains(qname))
+ {
+ emitField(node);
+ write(ASEmitterTokens.SEMICOLON);
+ writeNewline();
+ writeNewline();
+
+ propertyNames.add(qname);
+ }
+
+ if (node.getNodeID() == ASTNodeID.GetterID)
+ {
+ emitGetAccessor((IGetterNode) node);
+ }
+ else if (node.getNodeID() == ASTNodeID.SetterID)
+ {
+ emitSetAccessor((ISetterNode) node);
+ }
+ }
+
+ // XXX Dead
+ @Override
+ public void emitGetAccessor(IGetterNode node)
+ {
+ emitObjectDefineProperty(node);
+ }
+
+ // XXX Dead
+ @Override
+ public void emitSetAccessor(ISetterNode node)
+ {
+ emitObjectDefineProperty(node);
+ }
+
+ // XXX Dead [MethodEmitter]
+ @Override
+ public void emitMethod(IFunctionNode node)
+ {
+ FunctionNode fn = (FunctionNode) node;
+ fn.parseFunctionBody(new ArrayList<ICompilerProblem>());
+
+ ICompilerProject project = getWalker().getProject();
+
+ getDocEmitter().emitMethodDoc(node, project);
+
+ boolean isConstructor = node.isConstructor();
+
+ String qname = EmitterUtils.getTypeDefinition(node).getQualifiedName();
+ if (qname != null && !qname.equals(""))
+ {
+ write(formatQualifiedName(qname));
+ if (!isConstructor)
+ {
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ if (!fn.hasModifier(ASModifier.STATIC))
+ {
+ write(JSEmitterTokens.PROTOTYPE);
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ }
+ }
+ }
+
+ if (!isConstructor)
+ emitMemberName(node);
+
+ write(ASEmitterTokens.SPACE);
+ writeToken(ASEmitterTokens.EQUAL);
+ write(ASEmitterTokens.FUNCTION);
+
+ emitParameters(node.getParametersContainerNode());
+
+ boolean hasSuperClass = EmitterUtils.hasSuperClass(project, node);
+
+ if (isConstructor && node.getScopedNode().getChildCount() == 0)
+ {
+ write(ASEmitterTokens.SPACE);
+ write(ASEmitterTokens.BLOCK_OPEN);
+ if (hasSuperClass)
+ emitSuperCall(node, JSSessionModel.CONSTRUCTOR_EMPTY);
+ writeNewline();
+ write(ASEmitterTokens.BLOCK_CLOSE);
+ }
+
+ if (!isConstructor || node.getScopedNode().getChildCount() > 0)
+ emitMethodScope(node.getScopedNode());
+
+ if (isConstructor && hasSuperClass)
+ {
+ writeNewline(ASEmitterTokens.SEMICOLON);
+ write(JSGoogEmitterTokens.GOOG_INHERITS);
+ write(ASEmitterTokens.PAREN_OPEN);
+ write(formatQualifiedName(qname));
+ writeToken(ASEmitterTokens.COMMA);
+ String sname = EmitterUtils.getSuperClassDefinition(node, project)
+ .getQualifiedName();
+ write(formatQualifiedName(sname));
+ write(ASEmitterTokens.PAREN_CLOSE);
+ }
+ }
+
+ // XXX Dead
+ @Override
+ public void emitFunctionCall(IFunctionCallNode node)
+ {
+ IASNode cnode = node.getChild(0);
+
+ if (cnode.getNodeID() == ASTNodeID.MemberAccessExpressionID)
+ cnode = cnode.getChild(0);
+
+ ASTNodeID id = cnode.getNodeID();
+ if (id != ASTNodeID.SuperID)
+ {
+ if (node.isNewExpression())
+ {
+ writeToken(ASEmitterTokens.NEW);
+ }
+
+ getWalker().walk(node.getNameNode());
+
+ emitArguments(node.getArgumentsNode());
+ }
+ else
+ {
+ emitSuperCall(node, JSSessionModel.SUPER_FUNCTION_CALL);
+ }
+ }
+
+ // XXX Dead
+ @Override
+ public void emitIdentifier(IIdentifierNode node)
+ {
+ ICompilerProject project = getWalker().getProject();
+
+ IClassNode cnode = (IClassNode) node
+ .getAncestorOfType(IClassNode.class);
+
+ IDefinition def = node.resolve(project);
+
+ ITypeDefinition type = node.resolveType(project);
+
+ IASNode pnode = node.getParent();
+ ASTNodeID inode = pnode.getNodeID();
+
+ boolean writeSelf = false;
+ if (cnode != null)
+ {
+ IDefinitionNode[] members = cnode.getAllMemberNodes();
+ for (IDefinitionNode mnode : members)
+ {
+ if ((type != null && type.getQualifiedName().equalsIgnoreCase(
+ IASLanguageConstants.Function))
+ || (def != null && def.getQualifiedName()
+ .equalsIgnoreCase(mnode.getQualifiedName())))
+ {
+ if (!(pnode instanceof FunctionNode)
+ && inode != ASTNodeID.MemberAccessExpressionID)
+ {
+ writeSelf = true;
+ break;
+ }
+ else if (inode == ASTNodeID.MemberAccessExpressionID
+ && !def.isStatic())
+ {
+ String tname = type.getQualifiedName();
+ writeSelf = !tname.equalsIgnoreCase(cnode
+ .getQualifiedName())
+ && !tname.equals(IASLanguageConstants.Function);
+ break;
+ }
+ }
+ }
+ }
+
+ boolean isRunningInTestMode = cnode != null
+ && cnode.getQualifiedName().equalsIgnoreCase("FalconTest_A");
+ if (writeSelf && !isRunningInTestMode)
+ {
+ write(JSGoogEmitterTokens.SELF);
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ }
+ else
+ {
+ String pname = (type != null) ? type.getPackageName() : "";
+ if (cnode != null && pname != ""
+ && !pname.equalsIgnoreCase(cnode.getPackageName())
+ && inode != ASTNodeID.ArgumentID
+ && inode != ASTNodeID.VariableID
+ && inode != ASTNodeID.TypedExpressionID)
+ {
+ write(pname);
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ }
+ }
+
+ super.emitIdentifier(node);
+ }
+
+ @Override
+ public void emitFunctionBlockHeader(IFunctionNode node)
+ {
+ IDefinition def = node.getDefinition();
+ boolean isStatic = false;
+ if (def != null && def.isStatic())
+ isStatic = true;
+ boolean isLocal = false;
+ if (node.getFunctionClassification() == IFunctionDefinition.FunctionClassification.LOCAL)
+ isLocal = true;
+ if (EmitterUtils.hasBody(node) && !isStatic && !isLocal)
+ emitSelfReference(node);
+
+ if (node.isConstructor()
+ && EmitterUtils.hasSuperClass(getWalker().getProject(), node)
+ && !EmitterUtils.hasSuperCall(node.getScopedNode()))
+ emitSuperCall(node, JSSessionModel.CONSTRUCTOR_FULL);
+
+ emitRestParameterCodeBlock(node);
+
+ emitDefaultParameterCodeBlock(node);
+ }
+
+ // XXX Dead
+ protected void emitSelfReference(IFunctionNode node)
+ {
+ writeToken(ASEmitterTokens.VAR);
+ writeToken(JSGoogEmitterTokens.SELF);
+ writeToken(ASEmitterTokens.EQUAL);
+ write(ASEmitterTokens.THIS);
+ writeNewline(ASEmitterTokens.SEMICOLON);
+ }
+
+ // XXX Dead
+ protected void emitSuperCall(IASNode node, String type)
+ {
+ IFunctionNode fnode = (node instanceof IFunctionNode) ? (IFunctionNode) node
+ : null;
+ IFunctionCallNode fcnode = (node instanceof IFunctionCallNode) ? (FunctionCallNode) node
+ : null;
+
+ if (type == JSSessionModel.CONSTRUCTOR_EMPTY)
+ {
+ indentPush();
+ writeNewline();
+ indentPop();
+ }
+ else if (type == JSSessionModel.SUPER_FUNCTION_CALL)
+ {
+ if (fnode == null)
+ fnode = (IFunctionNode) fcnode
+ .getAncestorOfType(IFunctionNode.class);
+ }
+
+ if (fnode.isConstructor()
+ && !EmitterUtils.hasSuperClass(getWalker().getProject(), fnode))
+ return;
+
+ IClassNode cnode = (IClassNode) node
+ .getAncestorOfType(IClassNode.class);
+
+ if (cnode == null)
+ {
+ IDefinition cdef = getModel().getCurrentClass();
+ write(formatQualifiedName(cdef.getQualifiedName()));
+ }
+ else
+ write(formatQualifiedName(cnode.getQualifiedName()));
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ write(JSGoogEmitterTokens.GOOG_BASE);
+ write(ASEmitterTokens.PAREN_OPEN);
+ write(ASEmitterTokens.THIS);
+
+ if (fnode.isConstructor())
+ {
+ writeToken(ASEmitterTokens.COMMA);
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ write(JSGoogEmitterTokens.GOOG_CONSTRUCTOR);
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ }
+
+ if (fnode != null && !fnode.isConstructor())
+ {
+ writeToken(ASEmitterTokens.COMMA);
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ write(fnode.getName());
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ }
+
+ IASNode[] anodes = null;
+ boolean writeArguments = false;
+ if (fcnode != null)
+ {
+ anodes = fcnode.getArgumentNodes();
+
+ writeArguments = anodes.length > 0;
+ }
+ else if (fnode.isConstructor())
+ {
+ anodes = fnode.getParameterNodes();
+
+ writeArguments = (anodes != null && anodes.length > 0);
+ }
+
+ if (writeArguments)
+ {
+ int len = anodes.length;
+ for (int i = 0; i < len; i++)
+ {
+ writeToken(ASEmitterTokens.COMMA);
+
+ getWalker().walk(anodes[i]);
+ }
+ }
+
+ write(ASEmitterTokens.PAREN_CLOSE);
+
+ if (type == JSSessionModel.CONSTRUCTOR_FULL)
+ {
+ write(ASEmitterTokens.SEMICOLON);
+ writeNewline();
+ }
+ else if (type == JSSessionModel.CONSTRUCTOR_EMPTY)
+ {
+ write(ASEmitterTokens.SEMICOLON);
+ }
+ }
+
+ protected void emitDefaultParameterCodeBlock(IFunctionNode node)
+ {
+ IParameterNode[] pnodes = node.getParameterNodes();
+ if (pnodes.length == 0)
+ return;
+
+ Map<Integer, IParameterNode> defaults = EmitterUtils
+ .getDefaults(pnodes);
+
+ if (defaults != null)
+ {
+ final StringBuilder code = new StringBuilder();
+
+ if (!EmitterUtils.hasBody(node))
+ {
+ indentPush();
+ writeIndent();
+ }
+
+ List<IParameterNode> parameters = new ArrayList<IParameterNode>(
+ defaults.values());
+
+ for (int i = 0, n = parameters.size(); i < n; i++)
+ {
+ IParameterNode pnode = parameters.get(i);
+
+ if (pnode != null)
+ {
+ code.setLength(0);
+
+ /* x = typeof y !== 'undefined' ? y : z;\n */
+ code.append(pnode.getName());
+ code.append(ASEmitterTokens.SPACE.getToken());
+ code.append(ASEmitterTokens.EQUAL.getToken());
+ code.append(ASEmitterTokens.SPACE.getToken());
+ code.append(ASEmitterTokens.TYPEOF.getToken());
+ code.append(ASEmitterTokens.SPACE.getToken());
+ code.append(pnode.getName());
+ code.append(ASEmitterTokens.SPACE.getToken());
+ code.append(ASEmitterTokens.STRICT_NOT_EQUAL.getToken());
+ code.append(ASEmitterTokens.SPACE.getToken());
+ code.append(ASEmitterTokens.SINGLE_QUOTE.getToken());
+ code.append(ASEmitterTokens.UNDEFINED.getToken());
+ code.append(ASEmitterTokens.SINGLE_QUOTE.getToken());
+ code.append(ASEmitterTokens.SPACE.getToken());
+ code.append(ASEmitterTokens.TERNARY.getToken());
+ code.append(ASEmitterTokens.SPACE.getToken());
+ code.append(pnode.getName());
+ code.append(ASEmitterTokens.SPACE.getToken());
+ code.append(ASEmitterTokens.COLON.getToken());
+ code.append(ASEmitterTokens.SPACE.getToken());
+ code.append(pnode.getDefaultValue());
+ code.append(ASEmitterTokens.SEMICOLON.getToken());
+
+ write(code.toString());
+
+ if (i == n - 1 && !EmitterUtils.hasBody(node))
+ indentPop();
+
+ writeNewline();
+ }
+ }
+ }
+ }
+
+ protected void emitRestParameterCodeBlock(IFunctionNode node)
+ {
+ IParameterNode[] pnodes = node.getParameterNodes();
+
+ IParameterNode rest = EmitterUtils.getRest(pnodes);
+ if (rest != null)
+ {
+ final StringBuilder code = new StringBuilder();
+
+ /* x = Array.prototype.slice.call(arguments, y);\n */
+ code.append(rest.getName());
+ code.append(ASEmitterTokens.SPACE.getToken());
+ code.append(ASEmitterTokens.EQUAL.getToken());
+ code.append(ASEmitterTokens.SPACE.getToken());
+ code.append(BuiltinType.ARRAY.getName());
+ code.append(ASEmitterTokens.MEMBER_ACCESS.getToken());
+ code.append(JSEmitterTokens.PROTOTYPE.getToken());
+ code.append(ASEmitterTokens.MEMBER_ACCESS.getToken());
+ code.append(JSEmitterTokens.SLICE.getToken());
+ code.append(ASEmitterTokens.MEMBER_ACCESS.getToken());
+ code.append(JSEmitterTokens.CALL.getToken());
+ code.append(ASEmitterTokens.PAREN_OPEN.getToken());
+ code.append(JSEmitterTokens.ARGUMENTS.getToken());
+ code.append(ASEmitterTokens.COMMA.getToken());
+ code.append(ASEmitterTokens.SPACE.getToken());
+ code.append(String.valueOf(pnodes.length - 1));
+ code.append(ASEmitterTokens.PAREN_CLOSE.getToken());
+ code.append(ASEmitterTokens.SEMICOLON.getToken());
+
+ write(code.toString());
+
+ writeNewline();
+ }
+ }
+
+ @Override
+ public void emitParameter(IParameterNode node)
+ {
+ getWalker().walk(node.getNameExpressionNode());
+ }
+
+ @Override
+ public void emitAssignedValue(IExpressionNode node)
+ {
+ if (node == null)
+ {
+ return;
+ }
+ IDefinition definition = node.resolve(getWalker().getProject());
+ if (node.getNodeID() == ASTNodeID.ClassReferenceID)
+ {
+ write(definition.getQualifiedName());
+ }
+ else
+ {
+ // AJH need Language.bind here and maybe not require
+ // that the node is a MemberAccessExpression
+ if (definition instanceof FunctionDefinition &&
+ !((FunctionDefinition)definition).isStatic() &&
+ (!(definition instanceof AccessorDefinition)) &&
+ node instanceof MemberAccessExpressionNode)
+ {
+ emitClosureStart();
+ getWalker().walk(node);
+ writeToken(ASEmitterTokens.COMMA);
+ getWalker().walk(((MemberAccessExpressionNode)node).getLeftOperandNode());
+ emitClosureEnd(((MemberAccessExpressionNode)node).getLeftOperandNode());
+ }
+ else
+ getWalker().walk(node);
+ }
+ }
+
+ // XXX Dead
+ @Override
+ public void emitForEachLoop(IForLoopNode node)
+ {
+ IContainerNode xnode = (IContainerNode) node.getChild(1);
+ IBinaryOperatorNode bnode = (IBinaryOperatorNode) node
+ .getConditionalsContainerNode().getChild(0);
+ IASNode childNode = bnode.getChild(0);
+
+ write(JSGoogEmitterTokens.GOOG_ARRAY_FOREACH);
+ write(ASEmitterTokens.PAREN_OPEN);
+ getWalker().walk(bnode.getChild(1));
+ writeToken(ASEmitterTokens.COMMA);
+ writeToken(ASEmitterTokens.FUNCTION);
+ write(ASEmitterTokens.PAREN_OPEN);
+ if (childNode instanceof IVariableExpressionNode)
+ write(((IVariableNode) childNode.getChild(0)).getName());
+ else
+ write(((IIdentifierNode) childNode).getName());
+ writeToken(ASEmitterTokens.PAREN_CLOSE);
+ if (isImplicit(xnode))
+ write(ASEmitterTokens.BLOCK_OPEN);
+ getWalker().walk(node.getStatementContentsNode());
+ if (isImplicit(xnode))
+ {
+ writeNewline();
+ write(ASEmitterTokens.BLOCK_CLOSE);
+ }
+ write(ASEmitterTokens.PAREN_CLOSE);
+ }
+
+ public JSGoogEmitter(FilterWriter out)
+ {
+ super(out);
+ }
+
+ // XXX Dead
+ protected void emitObjectDefineProperty(IAccessorNode node)
+ {
+ /*
+ Object.defineProperty(
+ A.prototype,
+ 'foo',
+ {get: function() {return -1;},
+ configurable: true}
+ );
+ */
+
+ FunctionNode fn = (FunctionNode) node;
+ fn.parseFunctionBody(getProblems());
+
+ // head
+ write(JSGoogEmitterTokens.OBJECT);
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ write(JSEmitterTokens.DEFINE_PROPERTY);
+ writeNewline(ASEmitterTokens.PAREN_OPEN, true);
+
+ // Type
+ IFunctionDefinition definition = node.getDefinition();
+ ITypeDefinition type = (ITypeDefinition) definition.getParent();
+ write(type.getQualifiedName());
+ if (!node.hasModifier(ASModifier.STATIC))
+ {
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ write(JSEmitterTokens.PROTOTYPE);
+ }
+ writeToken(ASEmitterTokens.COMMA);
+ writeNewline();
+
+ // name
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ write(definition.getBaseName());
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ writeToken(ASEmitterTokens.COMMA);
+ writeNewline();
+
+ // info object
+ // declaration
+ write(ASEmitterTokens.BLOCK_OPEN);
+ write(node.getNodeID() == ASTNodeID.GetterID ? ASEmitterTokens.GET
+ : ASEmitterTokens.SET);
+ write(ASEmitterTokens.COLON);
+ write(ASEmitterTokens.FUNCTION);
+ emitParameters(node.getParametersContainerNode());
+
+ emitDefinePropertyFunction(node);
+
+ writeToken(ASEmitterTokens.COMMA);
+ write(JSEmitterTokens.CONFIGURABLE);
+ write(ASEmitterTokens.COLON);
+ write(ASEmitterTokens.TRUE);
+ writeNewline(ASEmitterTokens.BLOCK_CLOSE, false);
+
+ // tail, no colon; parent container will add it
+ write(ASEmitterTokens.PAREN_CLOSE);
+ }
+
+ // XXX Dead
+ protected void emitDefinePropertyFunction(IAccessorNode node)
+ {
+ emitMethodScope(node.getScopedNode());
+ }
+
+ //--------------------------------------------------------------------------
+ // Operators
+ //--------------------------------------------------------------------------
+
+ @Override
+ public void emitNamespaceAccessExpression(
+ INamespaceAccessExpressionNode node)
+ {
+ getWalker().walk(node.getLeftOperandNode());
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ getWalker().walk(node.getRightOperandNode());
+ }
+
+ @Override
+ public void emitAsOperator(IBinaryOperatorNode node)
+ {
+ emitBinaryOperator(node);
+ }
+
+ @Override
+ public void emitIsOperator(IBinaryOperatorNode node)
+ {
+ emitBinaryOperator(node);
+ }
+
+ // XXX Dead
+ @Override
+ public void emitBinaryOperator(IBinaryOperatorNode node)
+ {
+ if (ASNodeUtils.hasParenOpen(node))
+ write(ASEmitterTokens.PAREN_OPEN);
+
+ ASTNodeID id = node.getNodeID();
+
+ if (id == ASTNodeID.Op_IsID)
+ {
+ write(ASEmitterTokens.IS);
+ write(ASEmitterTokens.PAREN_OPEN);
+ getWalker().walk(node.getLeftOperandNode());
+ writeToken(ASEmitterTokens.COMMA);
+ getWalker().walk(node.getRightOperandNode());
+ write(ASEmitterTokens.PAREN_CLOSE);
+ }
+ else if (id == ASTNodeID.Op_AsID)
+ {
+ // (is(a, b) ? a : null)
+ write(ASEmitterTokens.PAREN_OPEN);
+ write(ASEmitterTokens.IS);
+ write(ASEmitterTokens.PAREN_OPEN);
+ getWalker().walk(node.getLeftOperandNode());
+ writeToken(ASEmitterTokens.COMMA);
+ getWalker().walk(node.getRightOperandNode());
+ writeToken(ASEmitterTokens.PAREN_CLOSE);
+ writeToken(ASEmitterTokens.TERNARY);
+ getWalker().walk(node.getLeftOperandNode());
+ write(ASEmitterTokens.SPACE);
+ writeToken(ASEmitterTokens.COLON);
+ write(ASEmitterTokens.NULL);
+ write(ASEmitterTokens.PAREN_CLOSE);
+ }
+ else
+ {
+ getWalker().walk(node.getLeftOperandNode());
+
+ if (id != ASTNodeID.Op_CommaID)
+ write(ASEmitterTokens.SPACE);
+
+ // (erikdebruin) rewrite 'a &&= b' to 'a = a && b'
+ if (id == ASTNodeID.Op_LogicalAndAssignID
+ || id == ASTNodeID.Op_LogicalOrAssignID)
+ {
+ IIdentifierNode lnode = (IIdentifierNode) node
+ .getLeftOperandNode();
+
+ writeToken(ASEmitterTokens.EQUAL);
+ writeToken(lnode.getName());
+ write((id == ASTNodeID.Op_LogicalAndAssignID) ? ASEmitterTokens.LOGICAL_AND
+ : ASEmitterTokens.LOGICAL_OR);
+ }
+ else
+ {
+ write(node.getOperator().getOperatorText());
+ }
+
+ write(ASEmitterTokens.SPACE);
+
+ getWalker().walk(node.getRightOperandNode());
+ }
+
+ if (ASNodeUtils.hasParenOpen(node))
+ write(ASEmitterTokens.PAREN_CLOSE);
+ }
+
+ protected void emitClosureStart(FunctionNode node)
+ {
+ write(JSGoogEmitterTokens.GOOG_BIND);
+ write(ASEmitterTokens.PAREN_OPEN);
+ }
+
+ protected void emitClosureEnd(FunctionNode node)
+ {
+ write(ASEmitterTokens.PAREN_CLOSE);
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogEmitterTokens.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogEmitterTokens.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogEmitterTokens.java
new file mode 100644
index 0000000..fd41804
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogEmitterTokens.java
@@ -0,0 +1,52 @@
+/*
+ *
+ * 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.js.goog;
+
+import org.apache.flex.compiler.codegen.IEmitterTokens;
+
+public enum JSGoogEmitterTokens implements IEmitterTokens
+{
+ AS3("__AS3__"),
+ GOOG_ARRAY_FOREACH("goog.array.forEach"),
+ GOOG_BASE("base"),
+ GOOG_CALL("call"),
+ GOOG_BIND("goog.bind"),
+ GOOG_CONSTRUCTOR("constructor"),
+ GOOG_GOOG("goog"),
+ GOOG_INHERITS("goog.inherits"),
+ GOOG_PROVIDE("goog.provide"),
+ GOOG_REQUIRE("goog.require"),
+ OBJECT("Object"),
+ ARRAY("Array"),
+ ERROR("Error"),
+ SELF("self"),
+ SUPERCLASS("superClass_");
+
+ private String token;
+
+ private JSGoogEmitterTokens(String value)
+ {
+ token = value;
+ }
+
+ public String getToken()
+ {
+ return token;
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogPublisher.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogPublisher.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogPublisher.java
new file mode 100644
index 0000000..a031737
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogPublisher.java
@@ -0,0 +1,360 @@
+/*
+ *
+ * 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.js.goog;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.io.filefilter.DirectoryFileFilter;
+import org.apache.commons.io.filefilter.RegexFileFilter;
+import org.apache.flex.compiler.clients.JSConfiguration;
+import org.apache.flex.compiler.clients.MXMLJSC.JSOutputType;
+import org.apache.flex.compiler.clients.problems.ProblemQuery;
+import org.apache.flex.compiler.codegen.js.IJSPublisher;
+import org.apache.flex.compiler.config.Configuration;
+import org.apache.flex.compiler.internal.codegen.js.JSPublisher;
+import org.apache.flex.compiler.internal.codegen.js.JSSharedData;
+import org.apache.flex.compiler.internal.driver.js.goog.JSGoogConfiguration;
+import org.apache.flex.compiler.utils.JSClosureCompilerUtil;
+
+import com.google.javascript.jscomp.CheckLevel;
+import com.google.javascript.jscomp.ErrorManager;
+import com.google.javascript.jscomp.JSError;
+import com.google.javascript.jscomp.SourceFile;
+import com.google.javascript.jscomp.SourceMap;
+import com.google.javascript.jscomp.deps.DepsGenerator;
+import com.google.javascript.jscomp.deps.DepsGenerator.InclusionStrategy;
+
+public class JSGoogPublisher extends JSPublisher implements IJSPublisher
+{
+
+ public static final String GOOG_INTERMEDIATE_DIR_NAME = "js-intermediate";
+ public static final String GOOG_RELEASE_DIR_NAME = "js-release";
+
+ public JSGoogPublisher(Configuration config)
+ {
+ super(config);
+ }
+
+ @Override
+ public File getOutputFolder()
+ {
+ outputParentFolder = new File(configuration.getTargetFileDirectory()).getParentFile();
+ outputFolder = new File(outputParentFolder,
+ JSGoogPublisher.GOOG_INTERMEDIATE_DIR_NAME);
+
+ setupOutputFolder();
+
+ return outputFolder;
+ }
+
+ @Override
+ public boolean publish(ProblemQuery problems) throws IOException
+ {
+ final String intermediateDirPath = getOutputFolder().getPath();
+
+ final String projectName = FilenameUtils.getBaseName(configuration.getTargetFile());
+ final String outputFileName = projectName + "."
+ + JSSharedData.OUTPUT_EXTENSION;
+
+ File releaseDir = new File(
+ new File(intermediateDirPath).getParentFile(),
+ GOOG_RELEASE_DIR_NAME);
+ final String releaseDirPath = releaseDir.getPath();
+ if (releaseDir.exists())
+ org.apache.commons.io.FileUtils.deleteQuietly(releaseDir);
+ releaseDir.mkdir();
+
+ final String closureLibDirPath = ((JSGoogConfiguration) configuration).getClosureLib();
+ final String closureGoogSrcLibDirPath = closureLibDirPath
+ + "/closure/goog/";
+ final String closureGoogTgtLibDirPath = intermediateDirPath
+ + "/library/closure/goog";
+ final String closureTPSrcLibDirPath = closureLibDirPath
+ + "/third_party/closure/goog/";
+ final String closureTPTgtLibDirPath = intermediateDirPath
+ + "/library/third_party/closure/goog";
+ final List<String> vanillaSDKSrcLibDirPath = ((JSGoogConfiguration) configuration).getSDKJSLib();
+ final String vanillaSDKTgtLibDirPath = intermediateDirPath
+ + "/VanillaSDK";
+
+ final String depsSrcFilePath = intermediateDirPath
+ + "/library/closure/goog/deps.js";
+ final String depsTgtFilePath = intermediateDirPath + "/deps.js";
+ final String projectIntermediateJSFilePath = intermediateDirPath
+ + File.separator + outputFileName;
+ final String projectReleaseJSFilePath = releaseDirPath + File.separator
+ + outputFileName;
+
+ appendExportSymbol(projectIntermediateJSFilePath, projectName);
+
+ copyFile(vanillaSDKSrcLibDirPath.get(0), vanillaSDKTgtLibDirPath);
+
+ List<SourceFile> inputs = new ArrayList<SourceFile>();
+ Collection<File> files = org.apache.commons.io.FileUtils.listFiles(
+ new File(intermediateDirPath),
+ new RegexFileFilter("^.*(\\.js)"),
+ DirectoryFileFilter.DIRECTORY);
+ for (File file : files)
+ {
+ inputs.add(SourceFile.fromFile(file));
+ }
+
+ copyFile(closureGoogSrcLibDirPath, closureGoogTgtLibDirPath);
+ copyFile(closureTPSrcLibDirPath, closureTPTgtLibDirPath);
+
+ File srcDeps = new File(depsSrcFilePath);
+
+ final List<SourceFile> deps = new ArrayList<SourceFile>();
+ deps.add(SourceFile.fromFile(srcDeps));
+
+ ErrorManager errorManager = new JSGoogErrorManager();
+ DepsGenerator depsGenerator = new DepsGenerator(deps, inputs,
+ InclusionStrategy.ALWAYS, closureGoogTgtLibDirPath,
+ errorManager);
+ writeFile(depsTgtFilePath, depsGenerator.computeDependencyCalls(),
+ false);
+
+ org.apache.commons.io.FileUtils.deleteQuietly(srcDeps);
+ org.apache.commons.io.FileUtils.moveFile(new File(depsTgtFilePath),
+ srcDeps);
+
+ // XXX (mschmalle) until we figure out what is going on with this configuration, just skip
+ // HTML generation for JSC output type
+ String outputType = ((JSConfiguration) configuration).getJSOutputType();
+ if (!outputType.equals(JSOutputType.JSC.getText()))
+ {
+ writeHTML("intermediate", projectName, intermediateDirPath);
+ writeHTML("release", projectName, releaseDirPath);
+ }
+
+ ArrayList<String> optionList = new ArrayList<String>();
+
+ files = org.apache.commons.io.FileUtils.listFiles(new File(
+ intermediateDirPath), new RegexFileFilter("^.*(\\.js)"),
+ DirectoryFileFilter.DIRECTORY);
+ for (File file : files)
+ {
+ optionList.add("--js=" + file.getCanonicalPath());
+ }
+
+ optionList.add("--closure_entry_point=" + projectName);
+ optionList.add("--only_closure_dependencies");
+ optionList.add("--compilation_level=ADVANCED_OPTIMIZATIONS");
+ optionList.add("--js_output_file=" + projectReleaseJSFilePath);
+ optionList.add("--output_manifest=" + releaseDirPath + File.separator
+ + "manifest.txt");
+ optionList.add("--create_source_map=" + projectReleaseJSFilePath
+ + ".map");
+ optionList.add("--source_map_format=" + SourceMap.Format.V3);
+
+ String[] options = optionList.toArray(new String[0]);
+
+ JSClosureCompilerUtil.run(options);
+
+ appendSourceMapLocation(projectReleaseJSFilePath, projectName);
+
+ System.out.println("The project '" + projectName
+ + "' has been successfully compiled and optimized.");
+
+ return true;
+ }
+
+ private void appendExportSymbol(String path, String projectName)
+ throws IOException
+ {
+ StringBuilder appendString = new StringBuilder();
+ appendString.append("\n\n// Ensures the symbol will be visible after compiler renaming.\n");
+ appendString.append("goog.exportSymbol('");
+ appendString.append(projectName);
+ appendString.append("', ");
+ appendString.append(projectName);
+ appendString.append(");\n");
+ writeFile(path, appendString.toString(), true);
+ }
+
+ protected void appendSourceMapLocation(String path, String projectName)
+ throws IOException
+ {
+ StringBuilder appendString = new StringBuilder();
+ appendString.append("\n//# sourceMappingURL=./" + projectName
+ + ".js.map");
+ writeFile(path, appendString.toString(), true);
+ }
+
+ protected void copyFile(String srcPath, String tgtPath) throws IOException
+ {
+ File srcFile = new File(srcPath);
+ if (srcFile.isDirectory())
+ org.apache.commons.io.FileUtils.copyDirectory(srcFile, new File(
+ tgtPath));
+ else
+ org.apache.commons.io.FileUtils.copyFile(srcFile, new File(tgtPath));
+ }
+
+ protected void writeHTML(String type, String projectName, String dirPath)
+ throws IOException
+ {
+ StringBuilder htmlFile = new StringBuilder();
+ htmlFile.append("<!DOCTYPE html>\n");
+ htmlFile.append("<html>\n");
+ htmlFile.append("<head>\n");
+ htmlFile.append("\t<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n");
+ htmlFile.append("\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n");
+
+ if (type == "intermediate")
+ {
+ htmlFile.append("\t<script type=\"text/javascript\" src=\"./library/closure/goog/base.js\"></script>\n");
+ htmlFile.append("\t<script type=\"text/javascript\">\n");
+ htmlFile.append("\t\tgoog.require(\"");
+ htmlFile.append(projectName);
+ htmlFile.append("\");\n");
+ htmlFile.append("\t</script>\n");
+ }
+ else
+ {
+ htmlFile.append("\t<script type=\"text/javascript\" src=\"./");
+ htmlFile.append(projectName);
+ htmlFile.append(".js\"></script>\n");
+ }
+
+ htmlFile.append("</head>\n");
+ htmlFile.append("<body>\n");
+ htmlFile.append("\t<script type=\"text/javascript\">\n");
+ htmlFile.append("\t\tnew ");
+ htmlFile.append(projectName);
+ htmlFile.append("();\n");
+ htmlFile.append("\t</script>\n");
+ htmlFile.append("</body>\n");
+ htmlFile.append("</html>");
+
+ writeFile(dirPath + File.separator + "index.html", htmlFile.toString(),
+ false);
+ }
+
+ protected void writeFile(String path, String content, boolean append)
+ throws IOException
+ {
+ File tgtFile = new File(path);
+
+ if (!tgtFile.exists())
+ tgtFile.createNewFile();
+
+ FileWriter fw = new FileWriter(tgtFile, append);
+ fw.write(content);
+ fw.close();
+ }
+
+ protected void dumpJar(File jarFile, File outputDir) throws IOException
+ {
+ // TODO (mschmalle) for some reason ide thinks this has not been closed
+ @SuppressWarnings("resource")
+ JarFile jar = new JarFile(jarFile);
+
+ for (Enumeration<JarEntry> jarEntries = jar.entries(); jarEntries.hasMoreElements();)
+ {
+ JarEntry jarEntry = jarEntries.nextElement();
+ if (!jarEntry.getName().endsWith("/"))
+ {
+ File file = new File(outputDir, jarEntry.getName());
+
+ // Check if the parent directory exists. If not -> create it.
+ File dir = file.getParentFile();
+ if (!dir.exists())
+ {
+ if (!dir.mkdirs())
+ {
+ throw new IOException("Unable to create directory "
+ + dir.getAbsolutePath());
+ }
+ }
+
+ // Dump the file.
+ InputStream is = jar.getInputStream(jarEntry);
+ FileOutputStream fos = new FileOutputStream(file);
+ while (is.available() > 0)
+ {
+ fos.write(is.read());
+ }
+ fos.close();
+ is.close();
+ }
+ }
+
+ jar.close();
+ }
+
+ public class JSGoogErrorManager implements ErrorManager
+ {
+ @Override
+ public void setTypedPercent(double arg0)
+ {
+ }
+
+ @Override
+ public void report(CheckLevel arg0, JSError arg1)
+ {
+ }
+
+ @Override
+ public JSError[] getWarnings()
+ {
+ return null;
+ }
+
+ @Override
+ public int getWarningCount()
+ {
+ return 0;
+ }
+
+ @Override
+ public double getTypedPercent()
+ {
+ return 0;
+ }
+
+ @Override
+ public JSError[] getErrors()
+ {
+ return null;
+ }
+
+ @Override
+ public int getErrorCount()
+ {
+ return 0;
+ }
+
+ @Override
+ public void generateReport()
+ {
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jsc/JSCJSEmitter.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jsc/JSCJSEmitter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jsc/JSCJSEmitter.java
new file mode 100644
index 0000000..1a10804
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jsc/JSCJSEmitter.java
@@ -0,0 +1,39 @@
+/*
+ *
+ * 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.js.jsc;
+
+import java.io.FilterWriter;
+
+import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSEmitter;
+
+/**
+ * Concrete implementation of the 'FlexJS' JavaScript production.
+ *
+ * @author Michael Schmalle
+ * @author Erik de Bruin
+ */
+public class JSCJSEmitter extends JSFlexJSEmitter
+{
+
+ public JSCJSEmitter(FilterWriter out)
+ {
+ super(out);
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jsc/JSCPublisher.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jsc/JSCPublisher.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jsc/JSCPublisher.java
new file mode 100644
index 0000000..1f39d50
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jsc/JSCPublisher.java
@@ -0,0 +1,53 @@
+/*
+ *
+ * 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.js.jsc;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.flex.compiler.config.Configuration;
+import org.apache.flex.compiler.internal.codegen.mxml.flexjs.MXMLFlexJSPublisher;
+import org.apache.flex.compiler.internal.projects.FlexJSProject;
+
+public class JSCPublisher extends MXMLFlexJSPublisher
+{
+
+ public JSCPublisher(Configuration config, FlexJSProject project)
+ {
+ super(config, project);
+ }
+
+ @Override
+ protected void writeHTML(String type, String projectName, String dirPath,
+ String deps, List<String> additionalHTML) throws IOException
+ {
+ if ("intermediate".equals(type))
+ {
+ StringBuilder depsFile = new StringBuilder();
+ depsFile.append(deps);
+ depsFile.append("goog.require(\"");
+ depsFile.append(projectName);
+ depsFile.append("\");\n");
+ writeFile(dirPath + File.separator + projectName + "-dependencies.js", depsFile.toString(), false);
+ }
+ // super.writeHTML(type, projectName, dirPath, deps, additionalHTML);
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/AccessorEmitter.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/AccessorEmitter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/AccessorEmitter.java
new file mode 100644
index 0000000..f2910d7
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/AccessorEmitter.java
@@ -0,0 +1,420 @@
+/*
+ *
+ * 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.js.jx;
+
+import java.util.HashMap;
+import java.util.Set;
+
+import org.apache.flex.compiler.codegen.ISubEmitter;
+import org.apache.flex.compiler.codegen.js.IJSEmitter;
+import org.apache.flex.compiler.common.ASModifier;
+import org.apache.flex.compiler.common.IMetaInfo;
+import org.apache.flex.compiler.common.ModifiersSet;
+import org.apache.flex.compiler.definitions.IAccessorDefinition;
+import org.apache.flex.compiler.definitions.IClassDefinition;
+import org.apache.flex.compiler.definitions.IFunctionDefinition;
+import org.apache.flex.compiler.definitions.ITypeDefinition;
+import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
+import org.apache.flex.compiler.internal.codegen.js.JSDocEmitterTokens;
+import org.apache.flex.compiler.internal.codegen.js.JSEmitterTokens;
+import org.apache.flex.compiler.internal.codegen.js.JSSessionModel.PropertyNodes;
+import org.apache.flex.compiler.internal.codegen.js.JSSubEmitter;
+import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSDocEmitter;
+import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSEmitter;
+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.projects.FlexJSProject;
+import org.apache.flex.compiler.internal.semantics.SemanticUtils;
+import org.apache.flex.compiler.internal.tree.as.FunctionNode;
+import org.apache.flex.compiler.internal.tree.as.SetterNode;
+import org.apache.flex.compiler.projects.ICompilerProject;
+import org.apache.flex.compiler.tree.ASTNodeID;
+import org.apache.flex.compiler.tree.as.IAccessorNode;
+import org.apache.flex.compiler.tree.as.IGetterNode;
+import org.apache.flex.compiler.tree.as.ISetterNode;
+
+public class AccessorEmitter extends JSSubEmitter implements
+ ISubEmitter<IAccessorNode>
+{
+
+ public AccessorEmitter(IJSEmitter emitter)
+ {
+ super(emitter);
+ }
+
+ @Override
+ public void emit(IAccessorNode node)
+ {
+ if (node.getNodeID() == ASTNodeID.GetterID)
+ {
+ emitGet((IGetterNode) node);
+ }
+ else if (node.getNodeID() == ASTNodeID.SetterID)
+ {
+ emitSet((ISetterNode) node);
+ }
+ }
+
+ public void emit(IClassDefinition definition)
+ {
+ // TODO (mschmalle) will remove this cast as more things get abstracted
+ JSFlexJSEmitter fjs = (JSFlexJSEmitter) getEmitter();
+
+ if (!getModel().getPropertyMap().isEmpty())
+ {
+ writeNewline();
+ writeNewline();
+ writeNewline();
+ write(JSGoogEmitterTokens.OBJECT);
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ write(JSEmitterTokens.DEFINE_PROPERTIES);
+ write(ASEmitterTokens.PAREN_OPEN);
+ String qname = definition.getQualifiedName();
+ write(getEmitter().formatQualifiedName(qname));
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ write(JSEmitterTokens.PROTOTYPE);
+ write(ASEmitterTokens.COMMA);
+ write(ASEmitterTokens.SPACE);
+ write("/** @lends {" + getEmitter().formatQualifiedName(qname)
+ + ".prototype} */ ");
+ writeNewline(ASEmitterTokens.BLOCK_OPEN);
+
+ Set<String> propertyNames = getModel().getPropertyMap().keySet();
+ boolean firstTime = true;
+ for (String propName : propertyNames)
+ {
+ if (firstTime)
+ firstTime = false;
+ else
+ writeNewline(ASEmitterTokens.COMMA);
+
+ boolean wroteGetter = false;
+ PropertyNodes p = getModel().getPropertyMap().get(propName);
+ writeNewline("/** @export */");
+ write(propName);
+ write(ASEmitterTokens.COLON);
+ write(ASEmitterTokens.SPACE);
+ writeNewline(ASEmitterTokens.BLOCK_OPEN);
+ if (p.getter != null)
+ {
+ write(ASEmitterTokens.GET);
+ write(ASEmitterTokens.COLON);
+ write(ASEmitterTokens.SPACE);
+ write(JSDocEmitterTokens.JSDOC_OPEN);
+ write(ASEmitterTokens.SPACE);
+ write(ASEmitterTokens.ATSIGN);
+ write(ASEmitterTokens.THIS);
+ write(ASEmitterTokens.SPACE);
+ write(ASEmitterTokens.BLOCK_OPEN);
+ write(getEmitter().formatQualifiedName(qname));
+ write(ASEmitterTokens.BLOCK_CLOSE);
+ write(ASEmitterTokens.SPACE);
+ write(JSDocEmitterTokens.JSDOC_CLOSE);
+ write(ASEmitterTokens.SPACE);
+ write(ASEmitterTokens.FUNCTION);
+ fjs.emitParameters(p.getter.getParametersContainerNode());
+
+ fjs.emitDefinePropertyFunction(p.getter);
+ wroteGetter = true;
+ }
+ else if (p.setter != null && p.setter.getDefinition().isOverride())
+ {
+ // see if there is a getter on a base class. If so, we have to
+ // generate a call to the super from this class because
+ // Object.defineProperty doesn't allow overriding just the setter.
+ // If there is no getter defineProp'd the property will seen as
+ // write-only.
+ IAccessorDefinition other = (IAccessorDefinition)SemanticUtils.resolveCorrespondingAccessor(p.setter.getDefinition(), getProject());
+ if (other != null)
+ {
+ write(ASEmitterTokens.GET);
+ write(ASEmitterTokens.COLON);
+ write(ASEmitterTokens.SPACE);
+ write(JSDocEmitterTokens.JSDOC_OPEN);
+ write(ASEmitterTokens.SPACE);
+ write(ASEmitterTokens.ATSIGN);
+ write(ASEmitterTokens.THIS);
+ write(ASEmitterTokens.SPACE);
+ write(ASEmitterTokens.BLOCK_OPEN);
+ write(getEmitter().formatQualifiedName(qname));
+ write(ASEmitterTokens.BLOCK_CLOSE);
+ write(ASEmitterTokens.SPACE);
+ write(JSDocEmitterTokens.JSDOC_CLOSE);
+ write(ASEmitterTokens.SPACE);
+ write(ASEmitterTokens.FUNCTION);
+ write(ASEmitterTokens.PAREN_OPEN);
+ write(ASEmitterTokens.PAREN_CLOSE);
+ write(ASEmitterTokens.SPACE);
+ writeNewline(ASEmitterTokens.BLOCK_OPEN);
+
+ ICompilerProject project = this.getProject();
+ if (project instanceof FlexJSProject)
+ ((FlexJSProject)project).needLanguage = true;
+ // setter is handled in binaryOperator
+ write(ASEmitterTokens.RETURN);
+ write(ASEmitterTokens.SPACE);
+ write(JSFlexJSEmitterTokens.LANGUAGE_QNAME);
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ write(JSFlexJSEmitterTokens.SUPERGETTER);
+ write(ASEmitterTokens.PAREN_OPEN);
+ write(getEmitter().formatQualifiedName(qname));
+ writeToken(ASEmitterTokens.COMMA);
+ write(ASEmitterTokens.THIS);
+ writeToken(ASEmitterTokens.COMMA);
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ write(propName);
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ write(ASEmitterTokens.PAREN_CLOSE);
+ writeNewline(ASEmitterTokens.SEMICOLON);
+ write(ASEmitterTokens.BLOCK_CLOSE);
+ wroteGetter = true;
+ }
+ }
+ if (p.setter != null)
+ {
+ if (wroteGetter)
+ writeNewline(ASEmitterTokens.COMMA);
+
+ write(ASEmitterTokens.SET);
+ write(ASEmitterTokens.COLON);
+ write(ASEmitterTokens.SPACE);
+ write(JSDocEmitterTokens.JSDOC_OPEN);
+ write(ASEmitterTokens.SPACE);
+ write(ASEmitterTokens.ATSIGN);
+ write(ASEmitterTokens.THIS);
+ write(ASEmitterTokens.SPACE);
+ write(ASEmitterTokens.BLOCK_OPEN);
+ write(getEmitter().formatQualifiedName(qname));
+ write(ASEmitterTokens.BLOCK_CLOSE);
+ write(ASEmitterTokens.SPACE);
+ write(JSDocEmitterTokens.JSDOC_CLOSE);
+ write(ASEmitterTokens.SPACE);
+ write(ASEmitterTokens.FUNCTION);
+ fjs.emitParameters(p.setter.getParametersContainerNode());
+
+ fjs.emitDefinePropertyFunction(p.setter);
+ }
+ else if (p.getter != null && p.getter.getDefinition().isOverride())
+ {
+ // see if there is a getter on a base class. If so, we have to
+ // generate a call to the super from this class because
+ // Object.defineProperty doesn't allow overriding just the getter.
+ // If there is no setter defineProp'd the property will seen as
+ // read-only.
+ IAccessorDefinition other = (IAccessorDefinition)SemanticUtils.resolveCorrespondingAccessor(p.getter.getDefinition(), getProject());
+ if (other != null)
+ {
+ if (wroteGetter)
+ writeNewline(ASEmitterTokens.COMMA);
+
+ write(ASEmitterTokens.SET);
+ write(ASEmitterTokens.COLON);
+ write(ASEmitterTokens.SPACE);
+ write(JSDocEmitterTokens.JSDOC_OPEN);
+ write(ASEmitterTokens.SPACE);
+ write(ASEmitterTokens.ATSIGN);
+ write(ASEmitterTokens.THIS);
+ write(ASEmitterTokens.SPACE);
+ write(ASEmitterTokens.BLOCK_OPEN);
+ write(getEmitter().formatQualifiedName(qname));
+ write(ASEmitterTokens.BLOCK_CLOSE);
+ write(ASEmitterTokens.SPACE);
+ write(JSDocEmitterTokens.JSDOC_CLOSE);
+ write(ASEmitterTokens.SPACE);
+ write(ASEmitterTokens.FUNCTION);
+ write(ASEmitterTokens.PAREN_OPEN);
+ write("value");
+ write(ASEmitterTokens.PAREN_CLOSE);
+ write(ASEmitterTokens.SPACE);
+ writeNewline(ASEmitterTokens.BLOCK_OPEN);
+
+ ICompilerProject project = this.getProject();
+ if (project instanceof FlexJSProject)
+ ((FlexJSProject)project).needLanguage = true;
+
+ write(JSFlexJSEmitterTokens.LANGUAGE_QNAME);
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ write(JSFlexJSEmitterTokens.SUPERSETTER);
+ write(ASEmitterTokens.PAREN_OPEN);
+ write(getEmitter().formatQualifiedName(qname));
+ writeToken(ASEmitterTokens.COMMA);
+ write(ASEmitterTokens.THIS);
+ writeToken(ASEmitterTokens.COMMA);
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ write(propName);
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ writeToken(ASEmitterTokens.COMMA);
+ write("value");
+ write(ASEmitterTokens.PAREN_CLOSE);
+ writeNewline(ASEmitterTokens.SEMICOLON);
+ write(ASEmitterTokens.BLOCK_CLOSE);
+ }
+ }
+ write(ASEmitterTokens.BLOCK_CLOSE);
+ }
+ writeNewline(ASEmitterTokens.BLOCK_CLOSE);
+ write(ASEmitterTokens.PAREN_CLOSE);
+ write(ASEmitterTokens.SEMICOLON);
+ }
+ if (!getModel().getStaticPropertyMap().isEmpty())
+ {
+ write(JSGoogEmitterTokens.OBJECT);
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ write(JSEmitterTokens.DEFINE_PROPERTIES);
+ write(ASEmitterTokens.PAREN_OPEN);
+ String qname = definition.getQualifiedName();
+ write(getEmitter().formatQualifiedName(qname));
+ write(ASEmitterTokens.COMMA);
+ write(ASEmitterTokens.SPACE);
+ write("/** @lends {" + getEmitter().formatQualifiedName(qname)
+ + "} */ ");
+ writeNewline(ASEmitterTokens.BLOCK_OPEN);
+
+ Set<String> propertyNames = getModel().getStaticPropertyMap()
+ .keySet();
+ boolean firstTime = true;
+ for (String propName : propertyNames)
+ {
+ if (firstTime)
+ firstTime = false;
+ else
+ writeNewline(ASEmitterTokens.COMMA);
+
+ PropertyNodes p = getModel().getStaticPropertyMap().get(
+ propName);
+ writeNewline("/** @export */");
+ write(propName);
+ write(ASEmitterTokens.COLON);
+ write(ASEmitterTokens.SPACE);
+ writeNewline(ASEmitterTokens.BLOCK_OPEN);
+ if (p.getter != null)
+ {
+ write(ASEmitterTokens.GET);
+ write(ASEmitterTokens.COLON);
+ write(ASEmitterTokens.SPACE);
+ write(ASEmitterTokens.FUNCTION);
+ fjs.emitParameters(p.getter.getParametersContainerNode());
+
+ fjs.emitDefinePropertyFunction(p.getter);
+ }
+ if (p.setter != null)
+ {
+ if (p.getter != null)
+ writeNewline(ASEmitterTokens.COMMA);
+
+ write(ASEmitterTokens.SET);
+ write(ASEmitterTokens.COLON);
+ write(ASEmitterTokens.SPACE);
+ write(ASEmitterTokens.FUNCTION);
+ fjs.emitParameters(p.setter.getParametersContainerNode());
+
+ fjs.emitDefinePropertyFunction(p.setter);
+ }
+ write(ASEmitterTokens.BLOCK_CLOSE);
+ }
+ writeNewline(ASEmitterTokens.BLOCK_CLOSE);
+ write(ASEmitterTokens.PAREN_CLOSE);
+ write(ASEmitterTokens.SEMICOLON);
+ }
+ }
+
+ public void emitGet(IGetterNode node)
+ {
+ // TODO (mschmalle) will remove this cast as more things get abstracted
+ JSFlexJSEmitter fjs = (JSFlexJSEmitter) getEmitter();
+
+ ModifiersSet modifierSet = node.getDefinition().getModifiers();
+ boolean isStatic = (modifierSet != null && modifierSet
+ .hasModifier(ASModifier.STATIC));
+ HashMap<String, PropertyNodes> map = isStatic ? getModel()
+ .getStaticPropertyMap() : getModel().getPropertyMap();
+ String name = node.getName();
+ PropertyNodes p = map.get(name);
+ if (p == null)
+ {
+ p = new PropertyNodes();
+ map.put(name, p);
+ }
+ p.getter = node;
+ FunctionNode fn = (FunctionNode) node;
+ fn.parseFunctionBody(fjs.getProblems());
+ }
+
+ public void emitSet(ISetterNode node)
+ {
+ // TODO (mschmalle) will remove this cast as more things get abstracted
+ JSFlexJSEmitter fjs = (JSFlexJSEmitter) getEmitter();
+ JSFlexJSDocEmitter doc = (JSFlexJSDocEmitter) fjs.getDocEmitter();
+
+ ModifiersSet modifierSet = node.getDefinition().getModifiers();
+ boolean isStatic = (modifierSet != null && modifierSet
+ .hasModifier(ASModifier.STATIC));
+ HashMap<String, PropertyNodes> map = isStatic ? getModel()
+ .getStaticPropertyMap() : getModel().getPropertyMap();
+ String name = node.getName();
+ PropertyNodes p = map.get(name);
+ if (p == null)
+ {
+ p = new PropertyNodes();
+ map.put(name, p);
+ }
+ p.setter = node;
+ FunctionNode fn = (FunctionNode) node;
+ fn.parseFunctionBody(fjs.getProblems());
+
+ boolean isBindableSetter = false;
+ if (node instanceof SetterNode)
+ {
+ IMetaInfo[] metaInfos = null;
+ metaInfos = node.getMetaInfos();
+ for (IMetaInfo metaInfo : metaInfos)
+ {
+ name = metaInfo.getTagName();
+ if (name.equals("Bindable")
+ && metaInfo.getAllAttributes().length == 0)
+ {
+ isBindableSetter = true;
+ break;
+ }
+ }
+ }
+ if (isBindableSetter)
+ {
+ IFunctionDefinition definition = node.getDefinition();
+ ITypeDefinition type = (ITypeDefinition) definition.getParent();
+ doc.emitMethodDoc(fn, getProject());
+ write(fjs.formatQualifiedName(type.getQualifiedName()));
+ if (!node.hasModifier(ASModifier.STATIC))
+ {
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ write(JSEmitterTokens.PROTOTYPE);
+ }
+
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ write("__bindingWrappedSetter__");
+ writeToken(node.getName());
+ writeToken(ASEmitterTokens.EQUAL);
+ write(ASEmitterTokens.FUNCTION);
+ fjs.emitParameters(node.getParametersContainerNode());
+ //writeNewline();
+ fjs.emitMethodScope(node.getScopedNode());
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/AsIsEmitter.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/AsIsEmitter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/AsIsEmitter.java
new file mode 100644
index 0000000..ee8a5e6
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/AsIsEmitter.java
@@ -0,0 +1,197 @@
+/*
+ *
+ * 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.js.jx;
+
+import org.apache.flex.compiler.asdoc.flexjs.ASDocComment;
+import org.apache.flex.compiler.codegen.js.IJSEmitter;
+import org.apache.flex.compiler.definitions.IClassDefinition;
+import org.apache.flex.compiler.definitions.IDefinition;
+import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
+import org.apache.flex.compiler.internal.codegen.js.JSSubEmitter;
+import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSEmitterTokens;
+import org.apache.flex.compiler.internal.projects.FlexJSProject;
+import org.apache.flex.compiler.projects.ICompilerProject;
+import org.apache.flex.compiler.tree.ASTNodeID;
+import org.apache.flex.compiler.tree.as.IASNode;
+import org.apache.flex.compiler.tree.as.IBinaryOperatorNode;
+import org.apache.flex.compiler.tree.as.IExpressionNode;
+import org.apache.flex.compiler.tree.as.IFunctionNode;
+
+public class AsIsEmitter extends JSSubEmitter
+{
+
+ public AsIsEmitter(IJSEmitter emitter)
+ {
+ super(emitter);
+ }
+
+ public void emitIsAs(IExpressionNode node, IExpressionNode left, IExpressionNode right,
+ ASTNodeID id, boolean coercion)
+ {
+ // project is null in unit tests
+ //IDefinition dnode = project != null ? (right).resolve(project) : null;
+ IDefinition dnode = getProject() != null ? (right)
+ .resolve(getProject()) : null;
+ if (id != ASTNodeID.Op_IsID && dnode != null)
+ {
+ boolean emit = coercion ?
+ !((FlexJSProject)getProject()).config.getJSOutputOptimizations().contains(JSFlexJSEmitterTokens.SKIP_FUNCTION_COERCIONS.getToken()) :
+ !((FlexJSProject)getProject()).config.getJSOutputOptimizations().contains(JSFlexJSEmitterTokens.SKIP_AS_COERCIONS.getToken());
+
+ // find the function node
+ IFunctionNode functionNode = (IFunctionNode) left
+ .getAncestorOfType(IFunctionNode.class);
+ if (functionNode != null) // can be null in synthesized binding code
+ {
+ if (coercion)
+ {
+ // see if the cast is inside a try/catch in this function. If so,
+ // assume that we want an exception.
+ IASNode child = left.getParent();
+ while (child != functionNode)
+ {
+ if (child.getNodeID() == ASTNodeID.TryID)
+ {
+ emit = true;
+ break;
+ }
+ child = child.getParent();
+ }
+ }
+ ASDocComment asDoc = (ASDocComment) functionNode
+ .getASDocComment();
+ if (asDoc != null)
+ {
+ String asDocString = asDoc.commentNoEnd();
+ String coercionToken = JSFlexJSEmitterTokens.EMIT_COERCION
+ .getToken();
+ int emitIndex = asDocString.indexOf(coercionToken);
+ while (emitIndex != -1)
+ {
+ String emitable = asDocString.substring(emitIndex
+ + coercionToken.length());
+ int endIndex = emitable.indexOf("\n");
+ emitable = emitable.substring(0, endIndex);
+ emitable = emitable.trim();
+ String rightSide = dnode.getQualifiedName();
+ if (emitable.equals(rightSide))
+ {
+ emit = true;
+ break;
+ }
+ emitIndex = asDocString.indexOf(coercionToken,
+ emitIndex + coercionToken.length());
+ }
+ String ignoreToken = JSFlexJSEmitterTokens.IGNORE_COERCION
+ .getToken();
+ int ignoreIndex = asDocString.indexOf(ignoreToken);
+ while (ignoreIndex != -1)
+ {
+ String ignorable = asDocString.substring(ignoreIndex
+ + ignoreToken.length());
+ int endIndex = ignorable.indexOf("\n");
+ ignorable = ignorable.substring(0, endIndex);
+ ignorable = ignorable.trim();
+ String rightSide = dnode.getQualifiedName();
+ if (ignorable.equals(rightSide))
+ {
+ emit = false;
+ break;
+ }
+ ignoreIndex = asDocString.indexOf(ignoreToken,
+ ignoreIndex + ignoreToken.length());
+ }
+ }
+ }
+ if (!emit)
+ {
+ getWalker().walk(left);
+ return;
+ }
+ }
+
+ ICompilerProject project = this.getProject();
+ if (project instanceof FlexJSProject)
+ ((FlexJSProject)project).needLanguage = true;
+
+ if (node instanceof IBinaryOperatorNode)
+ {
+ IBinaryOperatorNode binaryOperatorNode = (IBinaryOperatorNode) node;
+ startMapping(node, binaryOperatorNode.getLeftOperandNode());
+ }
+ else
+ {
+ startMapping(node);
+ }
+ write(JSFlexJSEmitterTokens.LANGUAGE_QNAME);
+ write(ASEmitterTokens.MEMBER_ACCESS);
+
+ if (id == ASTNodeID.Op_IsID)
+ write(ASEmitterTokens.IS);
+ else
+ write(ASEmitterTokens.AS);
+
+ write(ASEmitterTokens.PAREN_OPEN);
+ endMapping(node);
+
+ getWalker().walk(left);
+ if (node instanceof IBinaryOperatorNode)
+ {
+ IBinaryOperatorNode binaryOperatorNode = (IBinaryOperatorNode) node;
+ startMapping(node, binaryOperatorNode.getLeftOperandNode());
+ }
+ else
+ {
+ startMapping(node);
+ }
+ writeToken(ASEmitterTokens.COMMA);
+ endMapping(node);
+
+ if (dnode instanceof IClassDefinition)
+ {
+ startMapping(right);
+ write(getEmitter().formatQualifiedName(dnode.getQualifiedName()));
+ endMapping(right);
+ }
+ else
+ {
+ getWalker().walk(right);
+ }
+
+ if (node instanceof IBinaryOperatorNode)
+ {
+ IBinaryOperatorNode binaryOperatorNode = (IBinaryOperatorNode) node;
+ startMapping(node, binaryOperatorNode.getLeftOperandNode());
+ }
+ else
+ {
+ startMapping(node);
+ }
+ if (coercion)
+ {
+ writeToken(ASEmitterTokens.COMMA);
+ write(ASEmitterTokens.TRUE);
+ }
+
+ write(ASEmitterTokens.PAREN_CLOSE);
+ endMapping(node);
+ }
+
+}