You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by ms...@apache.org on 2013/03/05 20:22:09 UTC
svn commit: r1452955 [7/9] - in /flex/falcon/trunk:
compiler.jx.tests/src/org/apache/flex/compiler/internal/as/
compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/
compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/as/
compile...
Added: flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/amd/TempTools.java
URL: http://svn.apache.org/viewvc/flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/amd/TempTools.java?rev=1452955&view=auto
==============================================================================
--- flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/amd/TempTools.java (added)
+++ flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/amd/TempTools.java Tue Mar 5 19:22:05 2013
@@ -0,0 +1,451 @@
+/*
+ *
+ * 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.amd;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.flex.compiler.common.ASModifier;
+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.IParameterDefinition;
+import org.apache.flex.compiler.definitions.ITypeDefinition;
+import org.apache.flex.compiler.definitions.IVariableDefinition;
+import org.apache.flex.compiler.definitions.references.IReference;
+import org.apache.flex.compiler.internal.definitions.ClassTraitsDefinition;
+import org.apache.flex.compiler.internal.tree.as.ExpressionNodeBase;
+import org.apache.flex.compiler.internal.tree.as.FunctionCallNode;
+import org.apache.flex.compiler.internal.tree.as.MemberAccessExpressionNode;
+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.IClassNode;
+import org.apache.flex.compiler.tree.as.IDefinitionNode;
+import org.apache.flex.compiler.tree.as.IDynamicAccessNode;
+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.IIdentifierNode;
+import org.apache.flex.compiler.tree.as.ILanguageIdentifierNode;
+import org.apache.flex.compiler.tree.as.ILanguageIdentifierNode.LanguageIdentifierKind;
+import org.apache.flex.compiler.tree.as.IMemberAccessExpressionNode;
+import org.apache.flex.compiler.tree.as.IParameterNode;
+import org.apache.flex.compiler.tree.as.IUnaryOperatorNode;
+import org.apache.flex.compiler.tree.as.IVariableNode;
+
+/**
+ * These tools need to be refactored into utility classes.
+ *
+ * @author Michael Schmalle
+ */
+public class TempTools
+{
+
+ public static void fillStaticStatements(IClassNode node,
+ List<IASNode> list, boolean excludeFields)
+ {
+ int len = node.getScopedNode().getChildCount();
+ for (int i = 0; i < len; i++)
+ {
+ IASNode child = node.getScopedNode().getChild(i);
+ if (child instanceof IExpressionNode)
+ list.add(child);
+ else if (child instanceof IDefinitionNode)
+ {
+ if (!excludeFields
+ && ((IDefinitionNode) child)
+ .hasModifier(ASModifier.STATIC)
+ && child instanceof IVariableNode)
+ list.add(child);
+ }
+ }
+ }
+
+ public static void fillInstanceMembers(IDefinitionNode[] members,
+ List<IDefinitionNode> list)
+ {
+ for (IDefinitionNode node : members)
+ {
+ if (node instanceof IFunctionNode
+ && ((IFunctionNode) node).isConstructor())
+ continue;
+
+ if (!node.hasModifier(ASModifier.STATIC))
+ {
+ list.add(node);
+ }
+ }
+ }
+
+ public static void fillStaticMembers(IDefinitionNode[] members,
+ List<IDefinitionNode> list, boolean excludeFields,
+ boolean excludeFunctions)
+ {
+ for (IDefinitionNode node : members)
+ {
+ if (node.hasModifier(ASModifier.STATIC))
+ {
+ if (!excludeFields && node instanceof IVariableNode)
+ list.add(node);
+ else if (!excludeFunctions && node instanceof IFunctionNode)
+ list.add(node);
+ }
+ }
+ }
+
+ public static List<IVariableDefinition> getFields(
+ IClassDefinition definition, boolean excludePrivate)
+ {
+ ArrayList<IVariableDefinition> result = new ArrayList<IVariableDefinition>();
+ Collection<IDefinition> definitions = definition.getContainedScope()
+ .getAllLocalDefinitions();
+ for (IDefinition member : definitions)
+ {
+ if (!member.isImplicit() && member instanceof IVariableDefinition)
+ {
+ IVariableDefinition vnode = (IVariableDefinition) member;
+ if (!member.isStatic()
+ && (member.isPublic() || member.isProtected()))
+ result.add(vnode);
+ // TODO FIX the logic here, this won't add twice though
+ if (!excludePrivate && member.isPrivate())
+ result.add(vnode);
+ }
+ }
+ return result;
+ }
+
+ public static boolean isVariableAParameter(IVariableDefinition node,
+ IParameterDefinition[] parameters)
+ {
+ for (IParameterDefinition parameter : parameters)
+ {
+ if (node.getBaseName().equals(parameter.getBaseName()))
+ return true;
+ }
+ return false;
+ }
+
+ public static Map<Integer, IParameterNode> getDefaults(
+ IParameterNode[] nodes)
+ {
+ Map<Integer, IParameterNode> result = new HashMap<Integer, IParameterNode>();
+ int i = 0;
+ boolean hasDefaults = false;
+ for (IParameterNode node : nodes)
+ {
+ if (node.hasDefaultValue())
+ {
+ hasDefaults = true;
+ result.put(i, node);
+ }
+ else
+ {
+ result.put(i, null);
+ }
+ i++;
+ }
+
+ if (!hasDefaults)
+ return null;
+
+ return result;
+ }
+
+ public static boolean injectThisArgument(FunctionCallNode node,
+ boolean allowMembers)
+ {
+ // if super isSuper checks the nameNode
+ if (node.isSuperExpression() && !node.isNewExpression())
+ return true;
+
+ ExpressionNodeBase base = node.getNameNode();
+ if (base.getNodeID() == ASTNodeID.IdentifierID)
+ return false;
+
+ if (allowMembers && base instanceof IMemberAccessExpressionNode)
+ {
+ // foo.super()
+ IMemberAccessExpressionNode mnode = (IMemberAccessExpressionNode) base;
+ if (mnode.getLeftOperandNode().getNodeID() == ASTNodeID.SuperID)
+ return true;
+ }
+
+ return false;
+ }
+
+ public static String toInitialValue(IVariableDefinition field,
+ ICompilerProject project)
+ {
+ Object value = field.resolveInitialValue(project);
+ if (value != null)
+ return value.toString();
+ IReference reference = field.getTypeReference();
+ if (reference == null)
+ return "undefined";
+ if (reference.getName().equals("int")
+ || reference.getName().equals("uint")
+ || reference.getName().equals("Number"))
+ return "0";
+ return "null";
+ }
+
+ public static boolean isBinding(IIdentifierNode node,
+ ICompilerProject project)
+ {
+ IDefinition resolve = node.resolve(project);
+
+ if (resolve != null && resolve.isPrivate() && !isField(resolve))
+ {
+ //if (resolve instanceof IFunctionDefinition)
+ IExpressionNode rightSide = getNode(node, true, project);
+ IBinaryOperatorNode parent = (IBinaryOperatorNode) node
+ .getAncestorOfType(IBinaryOperatorNode.class);
+ if (isThisLeftOf(node))
+ parent = (IBinaryOperatorNode) parent
+ .getAncestorOfType(IBinaryOperatorNode.class);
+
+ IVariableNode vparent = (IVariableNode) node
+ .getAncestorOfType(IVariableNode.class);
+ if (vparent != null)
+ {
+ IExpressionNode indentFromThis = getIndentFromThis(node);
+ if (vparent.getAssignedValueNode() == node
+ || ((IBinaryOperatorNode) vparent
+ .getAssignedValueNode()).getRightOperandNode() == indentFromThis)
+ return true;
+ }
+
+ if (rightSide == node && parent != null/*|| isThisLeftOf(node)*/)
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private static boolean isField(IDefinition node)
+ {
+ return !(node instanceof IFunctionDefinition);
+ }
+
+ public static boolean isValidThis(IIdentifierNode node,
+ ICompilerProject project)
+ {
+ // added super.foo(), wanted to 'this' behind foo
+ if (node.getParent() instanceof IMemberAccessExpressionNode)
+ {
+ IMemberAccessExpressionNode mnode = (IMemberAccessExpressionNode) node
+ .getParent();
+ if (mnode.getLeftOperandNode().getNodeID() == ASTNodeID.SuperID)
+ return false;
+
+ IExpressionNode indentFromThis = getIndentFromThis(node);
+ if (node == indentFromThis)
+ return true;
+
+ // test that this is the base expression
+ ExpressionNodeBase enode = (ExpressionNodeBase) node;
+ ExpressionNodeBase baseExpression = enode.getBaseExpression();
+ if (indentFromThis == null && baseExpression != null
+ && baseExpression != node)
+ return false;
+
+ // check to see if the left is a type
+ ITypeDefinition type = mnode.getLeftOperandNode().resolveType(
+ project);
+
+ // A.{foo} : Left is a Type
+ // XXX going to have to test packgeName to com.acme.A
+ if (type instanceof ClassTraitsDefinition
+ && mnode.getLeftOperandNode() == node)
+ {
+ return false;
+ }
+ // this.{foo} : explicit 'this', in js we are ignoring explicit this identifiers
+ // because we are inserting all of them with the emitter
+ else if (indentFromThis == null)
+ {
+ //return false;
+ }
+
+ }
+
+ IDefinition definition = node.resolve(project);
+ if (definition == null)
+ return false; // Is this correct?
+ if (definition instanceof IParameterDefinition)
+ return false;
+ if (definition.getParent() instanceof IMemberAccessExpressionNode)
+ return false;
+ if (!(definition.getParent() instanceof IClassDefinition))
+ return false;
+
+ if (definition instanceof IVariableDefinition)
+ {
+ IVariableDefinition variable = (IVariableDefinition) definition;
+ if (variable.isStatic())
+ return false;
+ }
+ if (definition instanceof IFunctionDefinition)
+ {
+ IFunctionDefinition function = (IFunctionDefinition) definition;
+ if (function.isStatic())
+ return false;
+ }
+
+ return true;
+ }
+
+ private static boolean isThisLeftOf(IIdentifierNode node)
+ {
+ if (node.getParent() instanceof IMemberAccessExpressionNode)
+ {
+ IMemberAccessExpressionNode parent = (IMemberAccessExpressionNode) node
+ .getParent();
+ if (parent.getLeftOperandNode() instanceof ILanguageIdentifierNode
+ && ((ILanguageIdentifierNode) parent.getLeftOperandNode())
+ .getKind() == LanguageIdentifierKind.THIS)
+ return true;
+ }
+ return false;
+ }
+
+ public static IExpressionNode getNode(IASNode iNode, Boolean toRight,
+ ICompilerProject project)
+ {
+ try
+ {
+ IASNode node = iNode;
+ while (node != null)
+ {
+ if (node instanceof IBinaryOperatorNode
+ && !(node instanceof MemberAccessExpressionNode))
+ {
+ if (toRight)
+ node = ((IBinaryOperatorNode) node)
+ .getRightOperandNode();
+ else
+ node = ((IBinaryOperatorNode) node)
+ .getLeftOperandNode();
+ }
+ else if (node instanceof IFunctionCallNode)
+ node = ((IFunctionCallNode) node).getNameNode();
+ else if (node instanceof IDynamicAccessNode)
+ node = ((IDynamicAccessNode) node).getLeftOperandNode();
+ else if (node instanceof IUnaryOperatorNode)
+ node = ((IUnaryOperatorNode) node).getOperandNode();
+ else if (node instanceof IForLoopNode)
+ node = ((IForLoopNode) node).getChild(0).getChild(0);
+ else if (node instanceof IVariableNode)
+ {
+ if (toRight)
+ node = ((IVariableNode) node).getAssignedValueNode();
+ else
+ node = ((IVariableNode) node).getVariableTypeNode();
+ }
+ else if (node instanceof IExpressionNode)
+ {
+ // IDefinition def = ((IExpressionNode) node).resolve(project);
+ // if (def instanceof VariableDefinition)
+ // {
+ // final VariableDefinition variable = (VariableDefinition) def;
+ // def = variable.resolveType(project);
+ // }
+ // else if (def instanceof FunctionDefinition)
+ // {
+ // final FunctionDefinition functionDef = (FunctionDefinition) def;
+ // final IReference typeRef = functionDef
+ // .getReturnTypeReference();
+ // if (typeRef != null)
+ // def = typeRef.resolve(project,
+ // (ASScope) getScopeFromNode(iNode),
+ // DependencyType.INHERITANCE, false);
+ // }
+ // else if (def instanceof IGetterDefinition)
+ // {
+ // final ITypeDefinition returnType = ((IGetterDefinition) def)
+ // .resolveReturnType(project);
+ // // def = m_sharedData.getDefinition(returnType
+ // // .getQualifiedName());
+ // def = returnType; // XXX figure out
+ // }
+ //
+ // if (def != null && def instanceof ClassDefinition)
+ // {
+ // return def;
+ // }
+ return (IExpressionNode) node;
+ }
+ else
+ {
+ node = null;
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ // getDefinitionForNode(iNode,toRight);
+
+ // getDefinition() sometimes crashes, e.g. when looking at a cast to an interface in some cases,
+ // FunctionDefinition.getParameters() returns null and ExpressionNodeBase.determineIfFunction() chokes on it
+ // printWarning(iNode, "getDefinitionForNode() failed for" + iNode);
+ }
+ return null;
+ }
+
+ private static IExpressionNode getIndentFromThis(IIdentifierNode node)
+ {
+ if (node.getParent() instanceof IMemberAccessExpressionNode)
+ {
+ IMemberAccessExpressionNode parent = (IMemberAccessExpressionNode) node
+ .getParent();
+ if (parent.getLeftOperandNode() instanceof ILanguageIdentifierNode
+ && ((ILanguageIdentifierNode) parent.getLeftOperandNode())
+ .getKind() == LanguageIdentifierKind.THIS)
+ return parent.getRightOperandNode();
+ }
+ return null;
+ }
+
+ public static String toPackageName(String name)
+ {
+ if (!name.contains("."))
+ return name;
+ final String stem = name.substring(0, name.lastIndexOf("."));
+ return stem;
+ }
+
+ public static String toBaseName(String name)
+ {
+ if (!name.contains("."))
+ return name;
+ final String basename = name.substring(name.lastIndexOf(".") + 1);
+ return basename;
+ }
+
+}
Propchange: flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/amd/TempTools.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogDocEmitter.java
URL: http://svn.apache.org/viewvc/flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogDocEmitter.java?rev=1452955&view=auto
==============================================================================
--- flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogDocEmitter.java (added)
+++ flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogDocEmitter.java Tue Mar 5 19:22:05 2013
@@ -0,0 +1,438 @@
+/*
+ *
+ * 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.IASGlobalFunctionConstants;
+import org.apache.flex.compiler.codegen.IEmitterTokens;
+import org.apache.flex.compiler.codegen.js.IJSEmitter;
+import org.apache.flex.compiler.codegen.js.goog.IJSGoogDocEmitter;
+import org.apache.flex.compiler.common.ASModifier;
+import org.apache.flex.compiler.common.DependencyType;
+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.ITypeDefinition;
+import org.apache.flex.compiler.definitions.references.IReference;
+import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
+import org.apache.flex.compiler.internal.codegen.js.JSDocEmitter;
+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.JSSharedData;
+import org.apache.flex.compiler.internal.scopes.ASScope;
+import org.apache.flex.compiler.internal.semantics.SemanticUtils;
+import org.apache.flex.compiler.projects.ICompilerProject;
+import org.apache.flex.compiler.tree.as.IASNode;
+import org.apache.flex.compiler.tree.as.IClassNode;
+import org.apache.flex.compiler.tree.as.IExpressionNode;
+import org.apache.flex.compiler.tree.as.IFunctionNode;
+import org.apache.flex.compiler.tree.as.IInterfaceNode;
+import org.apache.flex.compiler.tree.as.IPackageNode;
+import org.apache.flex.compiler.tree.as.IParameterNode;
+import org.apache.flex.compiler.tree.as.IScopedNode;
+import org.apache.flex.compiler.tree.as.IVariableNode;
+import org.apache.flex.compiler.tree.mxml.IMXMLDocumentNode;
+
+public class JSGoogDocEmitter extends JSDocEmitter implements IJSGoogDocEmitter
+{
+
+ public JSGoogDocEmitter(IJSEmitter emitter)
+ {
+ super(emitter);
+ }
+
+ @Override
+ public void emitInterfaceDoc(IInterfaceNode node)
+ {
+ begin();
+
+ emitJSDocLine(JSEmitterTokens.INTERFACE.getToken());
+
+ String[] inodes = node.getExtendedInterfaces();
+ for (String inode : inodes)
+ {
+ emitJSDocLine(ASEmitterTokens.EXTENDS, inode);
+ }
+
+ end();
+ }
+
+ @Override
+ public void emitFieldDoc(IVariableNode node, IDefinition def)
+ {
+ begin();
+
+ String ns = node.getNamespace();
+ if (ns == IASKeywordConstants.PRIVATE)
+ {
+ emitPrivate(node);
+ }
+ else if (ns == IASKeywordConstants.PROTECTED)
+ {
+ emitProtected(node);
+ }
+
+ if (node.isConst())
+ emitConst(node);
+
+ String packageName = "";
+ if (def != null)
+ packageName = def.getPackageName();
+
+ emitType(node, packageName);
+
+ end();
+ }
+
+ @Override
+ public void emitMethodDoc(IFunctionNode node, ICompilerProject project)
+ {
+ IClassDefinition classDefinition = resolveClassDefinition(node);
+
+ if (node instanceof IFunctionNode)
+ {
+ boolean hasDoc = false;
+
+ if (node.isConstructor())
+ {
+ begin();
+ hasDoc = true;
+
+ emitJSDocLine(JSEmitterTokens.CONSTRUCTOR);
+
+ IClassDefinition parent = (IClassDefinition) node
+ .getDefinition().getParent();
+ IClassDefinition superClass = parent.resolveBaseClass(project);
+ String qname = superClass.getQualifiedName();
+
+ if (superClass != null
+ && !qname.equals(IASLanguageConstants.Object))
+ emitExtends(superClass, superClass.getPackageName());
+
+ IReference[] references = classDefinition
+ .getImplementedInterfaceReferences();
+ for (IReference iReference : references)
+ {
+ ITypeDefinition type = (ITypeDefinition) iReference
+ .resolve(project, (ASScope) classDefinition
+ .getContainingScope(),
+ DependencyType.INHERITANCE, true);
+ emitImplements(type, type.getPackageName());
+ }
+ }
+ else
+ {
+ // @this
+ if (containsThisReference(node))
+ {
+ begin();
+ hasDoc = true;
+
+ emitThis(classDefinition, classDefinition.getPackageName());
+ }
+ }
+
+ // @param
+ IParameterNode[] parameters = node.getParameterNodes();
+ for (IParameterNode pnode : parameters)
+ {
+ if (!hasDoc)
+ {
+ begin();
+ hasDoc = true;
+ }
+
+ IExpressionNode enode = pnode.getNameExpressionNode();
+ emitParam(pnode, enode.resolveType(project).getPackageName());
+ }
+
+ if (!node.isConstructor())
+ {
+ // @return
+ String returnType = node.getReturnType();
+ if (returnType != ""
+ && returnType != ASEmitterTokens.VOID.getToken())
+ {
+ if (!hasDoc)
+ {
+ begin();
+ hasDoc = true;
+ }
+
+ emitReturn(node, node.getPackageName());
+ }
+
+ // @override
+ Boolean override = node.hasModifier(ASModifier.OVERRIDE);
+ if (override)
+ {
+ if (!hasDoc)
+ {
+ begin();
+ hasDoc = true;
+ }
+
+ emitOverride(node);
+ }
+ }
+
+ if (hasDoc)
+ end();
+ }
+ }
+
+ @Override
+ public void emitVarDoc(IVariableNode node, IDefinition def)
+ {
+ String packageName = "";
+ if (def != null)
+ packageName = def.getPackageName();
+
+ if (!node.isConst())
+ {
+ emitTypeShort(node, packageName);
+ }
+ else
+ {
+ writeNewline();
+ begin();
+ emitConst(node);
+ emitType(node, packageName);
+ end();
+ }
+ }
+
+ @Override
+ public void emitConst(IVariableNode node)
+ {
+ emitJSDocLine(ASEmitterTokens.CONST);
+ }
+
+ @Override
+ public void emitExtends(IClassDefinition superDefinition, String packageName)
+ {
+ emitJSDocLine(ASEmitterTokens.EXTENDS,
+ superDefinition.getQualifiedName());
+ }
+
+ @Override
+ public void emitImplements(ITypeDefinition definition, String packageName)
+ {
+ emitJSDocLine(ASEmitterTokens.IMPLEMENTS, definition.getQualifiedName());
+ }
+
+ @Override
+ public void emitOverride(IFunctionNode node)
+ {
+ emitJSDocLine(ASEmitterTokens.OVERRIDE);
+ }
+
+ @Override
+ public void emitParam(IParameterNode node, String packageName)
+ {
+ String postfix = (node.getDefaultValue() == null) ? ""
+ : ASEmitterTokens.EQUAL.getToken();
+
+ String paramType = "";
+ if (node.isRest())
+ paramType = ASEmitterTokens.ELLIPSIS.getToken();
+ else
+ paramType = convertASTypeToJS(node.getVariableType(), packageName);
+
+ emitJSDocLine(JSGoogDocEmitterTokens.PARAM, paramType + postfix,
+ node.getName());
+ }
+
+ @Override
+ public void emitPrivate(IASNode node)
+ {
+ emitJSDocLine(ASEmitterTokens.PRIVATE);
+ }
+
+ @Override
+ public void emitProtected(IASNode node)
+ {
+ emitJSDocLine(ASEmitterTokens.PROTECTED);
+ }
+
+ @Override
+ public void emitReturn(IFunctionNode node, String packageName)
+ {
+ String rtype = node.getReturnType();
+ if (rtype != null)
+ {
+ emitJSDocLine(ASEmitterTokens.RETURN,
+ convertASTypeToJS(rtype, packageName));
+ }
+ }
+
+ @Override
+ public void emitThis(ITypeDefinition type, String packageName)
+ {
+ emitJSDocLine(ASEmitterTokens.THIS.getToken(), type.getQualifiedName());
+ }
+
+ @Override
+ public void emitType(IASNode node, String packageName)
+ {
+ String type = ((IVariableNode) node).getVariableType();
+ emitJSDocLine(JSGoogDocEmitterTokens.TYPE.getToken(),
+ convertASTypeToJS(type, packageName));
+ }
+
+ public void emitTypeShort(IASNode node, String packageName)
+ {
+ String type = ((IVariableNode) node).getVariableType();
+ writeToken(JSDocEmitterTokens.JSDOC_OPEN);
+ write(ASEmitterTokens.ATSIGN);
+ writeToken(JSGoogDocEmitterTokens.TYPE);
+ writeBlockOpen();
+ write(convertASTypeToJS(type, packageName));
+ writeBlockClose();
+ write(ASEmitterTokens.SPACE);
+ writeToken(JSDocEmitterTokens.JSDOC_CLOSE);
+ }
+
+ //--------------------------------------------------------------------------
+
+ public void emmitPackageHeader(IPackageNode node)
+ {
+ begin();
+ write(ASEmitterTokens.SPACE);
+ writeToken(JSGoogDocEmitterTokens.STAR);
+ write(JSSharedData.getTimeStampString());
+ end();
+ }
+
+ //--------------------------------------------------------------------------
+
+ private void emitJSDocLine(IEmitterTokens name)
+ {
+ emitJSDocLine(name.getToken(), "");
+ }
+
+ private void emitJSDocLine(String name)
+ {
+ emitJSDocLine(name, "");
+ }
+
+ private void emitJSDocLine(IEmitterTokens name, String type)
+ {
+ emitJSDocLine(name.getToken(), type, "");
+ }
+
+ private void emitJSDocLine(String name, String type)
+ {
+ emitJSDocLine(name, type, "");
+ }
+
+ private void emitJSDocLine(IEmitterTokens name, String type, String param)
+ {
+ emitJSDocLine(name.getToken(), type, param);
+ }
+
+ private void emitJSDocLine(String name, String type, String param)
+ {
+ write(ASEmitterTokens.SPACE);
+ writeToken(JSGoogDocEmitterTokens.STAR);
+ write(ASEmitterTokens.ATSIGN);
+ write(name);
+ if (type != "")
+ {
+ write(ASEmitterTokens.SPACE);
+ writeBlockOpen();
+ write(type);
+ writeBlockClose();
+ }
+ if (param != "")
+ {
+ write(ASEmitterTokens.SPACE);
+ write(param);
+ }
+ writeNewline();
+ }
+
+ private boolean containsThisReference(IASNode node)
+ {
+ final int len = node.getChildCount();
+ for (int i = 0; i < len; i++)
+ {
+ final IASNode child = node.getChild(i);
+ if (child.getChildCount() > 0)
+ {
+ return containsThisReference(child);
+ }
+ else
+ {
+ if (SemanticUtils.isThisKeyword(child))
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private String convertASTypeToJS(String name, String pname)
+ {
+ String result = "";
+
+ if (name.equals(""))
+ result = ASEmitterTokens.ANY_TYPE.getToken();
+ else if (name.equals(IASLanguageConstants.Boolean)
+ || name.equals(IASLanguageConstants.String)
+ || name.equals(IASLanguageConstants.Number))
+ result = name.toLowerCase();
+ else if (name.equals(IASLanguageConstants._int)
+ || name.equals(IASLanguageConstants.uint))
+ result = IASLanguageConstants.Number.toLowerCase();
+
+ boolean isBuiltinFunction = name.matches("Vector\\.<.*>");
+ IASGlobalFunctionConstants.BuiltinType[] builtinTypes = IASGlobalFunctionConstants.BuiltinType
+ .values();
+ for (IASGlobalFunctionConstants.BuiltinType builtinType : builtinTypes)
+ {
+ if (name.equalsIgnoreCase(builtinType.getName()))
+ {
+ isBuiltinFunction = true;
+ break;
+ }
+ }
+
+ if (result == "")
+ result = (pname != "" && !isBuiltinFunction) ? pname
+ + ASEmitterTokens.MEMBER_ACCESS.getToken() + name : name;
+
+ result = result.replace(IASLanguageConstants.String,
+ IASLanguageConstants.String.toLowerCase());
+
+ return result;
+ }
+
+ private IClassDefinition resolveClassDefinition(IFunctionNode node)
+ {
+ IScopedNode scope = node.getContainingScope();
+ if (scope instanceof IMXMLDocumentNode)
+ return ((IMXMLDocumentNode) scope).getClassDefinition();
+
+ IClassNode cnode = (IClassNode) node
+ .getAncestorOfType(IClassNode.class);
+ return cnode.getDefinition();
+ }
+}
Propchange: flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogDocEmitter.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogDocEmitterTokens.java
URL: http://svn.apache.org/viewvc/flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogDocEmitterTokens.java?rev=1452955&view=auto
==============================================================================
--- flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogDocEmitterTokens.java (added)
+++ flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogDocEmitterTokens.java Tue Mar 5 19:22:05 2013
@@ -0,0 +1,20 @@
+package org.apache.flex.compiler.internal.codegen.js.goog;
+
+import org.apache.flex.compiler.codegen.IEmitterTokens;
+
+public enum JSGoogDocEmitterTokens implements IEmitterTokens
+{
+ PARAM("param"), STAR("*"), TYPE("type");
+
+ private String token;
+
+ private JSGoogDocEmitterTokens(String value)
+ {
+ token = value;
+ }
+
+ public String getToken()
+ {
+ return token;
+ }
+}
Propchange: flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogDocEmitterTokens.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogEmitter.java
URL: http://svn.apache.org/viewvc/flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogEmitter.java?rev=1452955&view=auto
==============================================================================
--- flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogEmitter.java (added)
+++ flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogEmitter.java Tue Mar 5 19:22:05 2013
@@ -0,0 +1,1065 @@
+/*
+ *
+ * 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.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.flex.compiler.codegen.IDocEmitter;
+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.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.definitions.ClassDefinition;
+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.NamespaceAccessExpressionNode;
+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.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.IParameterNode;
+import org.apache.flex.compiler.tree.as.IScopedNode;
+import org.apache.flex.compiler.tree.as.ISetterNode;
+import org.apache.flex.compiler.tree.as.ITypeNode;
+import org.apache.flex.compiler.tree.as.ITypedExpressionNode;
+import org.apache.flex.compiler.tree.as.IVariableNode;
+
+/**
+ * Concrete implementation of the 'goog' JavaScript production.
+ *
+ * @author Michael Schmalle
+ * @author Erik de Bruin
+ */
+public class JSGoogEmitter extends JSEmitter implements IJSGoogEmitter
+{
+
+ private static final String CONSTRUCTOR_EMPTY = "emptyConstructor";
+ private static final String CONSTRUCTOR_FULL = "fullConstructor";
+ private static final String SUPER_FUNCTION_CALL = "replaceSuperFunction";
+
+ private List<String> propertyNames = new ArrayList<String>();
+
+ IJSGoogDocEmitter getDoc()
+ {
+ return (IJSGoogDocEmitter) getDocEmitter();
+ }
+
+ @Override
+ public IDocEmitter getDocEmitter()
+ {
+ return new JSGoogDocEmitter(this);
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ //--------------------------------------------------------------------------
+
+ @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();
+ }
+
+ @Override
+ public void emitPackageHeaderContents(IPackageDefinition definition)
+ {
+ PackageScope containedScope = (PackageScope) definition
+ .getContainedScope();
+
+ ITypeDefinition type = findType(containedScope.getAllLocalDefinitions());
+ if (type == null)
+ return;
+
+ List<String> list = 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();
+ }
+ }
+
+ @Override
+ public void emitPackageContents(IPackageDefinition definition)
+ {
+ IASScope containedScope = definition.getContainedScope();
+ ITypeDefinition type = findType(containedScope.getAllLocalDefinitions());
+ if (type == null)
+ return;
+
+ IClassNode cnode = (IClassNode) type.getNode();
+ if (cnode == null)
+ return;
+
+ emitClass(cnode);
+ }
+
+ @Override
+ public void emitPackageFooter(IPackageDefinition definition)
+ {
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ //--------------------------------------------------------------------------
+
+ @Override
+ public void emitClass(IClassNode node)
+ {
+ IClassDefinition definition = node.getDefinition();
+
+ // constructor
+ emitMethod((IFunctionNode) definition.getConstructor().getNode());
+ 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);
+ }
+ }
+ }
+
+ @Override
+ public void emitInterface(IInterfaceNode node)
+ {
+ getDoc().emitInterfaceDoc(node);
+
+ writeToken(node.getNamespace());
+
+ writeToken(ASEmitterTokens.INTERFACE);
+ getWalker().walk(node.getNameExpressionNode());
+ write(ASEmitterTokens.SPACE);
+
+ writeNewline(ASEmitterTokens.BLOCK_OPEN);
+ write(ASEmitterTokens.BLOCK_CLOSE);
+
+ final IDefinitionNode[] members = node.getAllMemberDefinitionNodes();
+ for (IDefinitionNode mnode : members)
+ {
+ boolean isAccessor = mnode.getNodeID() == ASTNodeID.GetterID
+ || mnode.getNodeID() == ASTNodeID.SetterID;
+
+ String qname = node.getQualifiedName();
+
+ if (!isAccessor || !propertyNames.contains(qname))
+ {
+ writeNewline();
+
+ emitMemberName(node);
+ 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);
+
+ emitParamters(((IFunctionNode) mnode).getParameterNodes());
+ }
+
+ write(ASEmitterTokens.SEMICOLON);
+ }
+ }
+ }
+
+ @Override
+ public void emitField(IVariableNode node)
+ {
+ IClassDefinition definition = getClassDefinition(node);
+
+ IDefinition def = null;
+ IExpressionNode enode = node.getVariableTypeNode();//getAssignedValueNode();
+ if (enode != null)
+ def = enode.resolveType(getWalker().getProject());
+
+ getDoc().emitFieldDoc(node, def);
+
+ /* 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);
+ }
+ }
+ }
+ }
+
+ @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")
+ getDoc().emitVarDoc(node, def);
+ }
+ else
+ {
+ getDoc().emitVarDoc(node, null);
+ }
+
+ emitDeclarationName(node);
+ 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);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void emitGetAccessor(IGetterNode node)
+ {
+ emitObjectDefineProperty(node);
+ }
+
+ @Override
+ public void emitSetAccessor(ISetterNode node)
+ {
+ emitObjectDefineProperty(node);
+ }
+
+ private 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);
+ }
+ }
+
+ @Override
+ public void emitMethod(IFunctionNode node)
+ {
+ FunctionNode fn = (FunctionNode) node;
+ fn.parseFunctionBody(new ArrayList<ICompilerProblem>());
+
+ ICompilerProject project = getWalker().getProject();
+
+ getDoc().emitMethodDoc(node, project);
+
+ boolean isConstructor = node.isConstructor();
+
+ String qname = getTypeDefinition(node).getQualifiedName();
+ if (qname != null && !qname.equals(""))
+ {
+ write(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);
+
+ emitParamters(node.getParameterNodes());
+
+ boolean hasSuperClass = hasSuperClass(node);
+
+ if (isConstructor && node.getScopedNode().getChildCount() == 0)
+ {
+ write(ASEmitterTokens.SPACE);
+ write(ASEmitterTokens.BLOCK_OPEN);
+ if (hasSuperClass)
+ emitSuperCall(node, CONSTRUCTOR_EMPTY);
+ writeNewline();
+ write(ASEmitterTokens.BLOCK_CLOSE);
+ }
+
+ if (!isConstructor || node.getScopedNode().getChildCount() > 0)
+ emitMethodScope(node.getScopedNode());
+
+ if (isConstructor && hasSuperClass)
+ {
+ writeNewline();
+ write(JSGoogEmitterTokens.GOOG_INHERITS);
+ write(ASEmitterTokens.PAREN_OPEN);
+ write(qname);
+ writeToken(ASEmitterTokens.COMMA);
+ String sname = getSuperClassDefinition(node, project)
+ .getQualifiedName();
+ write(sname);
+ write(ASEmitterTokens.PAREN_CLOSE);
+ }
+ }
+
+ @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());
+
+ write(ASEmitterTokens.PAREN_OPEN);
+ walkArguments(node.getArgumentNodes());
+ write(ASEmitterTokens.PAREN_CLOSE);
+ }
+ else
+ {
+ emitSuperCall(node, SUPER_FUNCTION_CALL);
+ }
+ }
+
+ @Override
+ public void emitIdentifier(IIdentifierNode node)
+ {
+ ICompilerProject project = getWalker().getProject();
+
+ IClassNode cnode = (IClassNode) node
+ .getAncestorOfType(IClassNode.class);
+
+ IDefinition def = ((IIdentifierNode) node).resolve(project);
+
+ ITypeDefinition type = ((IIdentifierNode) 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;
+ }
+ }
+ }
+ }
+
+ // XXX (erikdebruin) I desperately needed a way to bypass the addition
+ // of the 'self' prefix when running the tests... Or
+ // I'd have to put the prefix in ~150 asserts!
+ boolean isRunningInTestMode = cnode != null
+ && cnode.getQualifiedName().equalsIgnoreCase("A");
+ if (writeSelf && !isRunningInTestMode)
+ {
+ write(JSGoogEmitterTokens.SELF);
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ }
+ else
+ {
+ String pname = (type != null) ? type.getPackageName() : "";
+ if (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)
+ {
+ if (hasBody(node))
+ emitSelfReference(node);
+
+ if (node.isConstructor() && hasSuperClass(node)
+ && !hasSuperCall(node.getScopedNode()))
+ emitSuperCall(node, CONSTRUCTOR_FULL);
+
+ emitRestParameterCodeBlock(node);
+
+ emitDefaultParameterCodeBlock(node);
+ }
+
+ private void emitSelfReference(IFunctionNode node)
+ {
+ writeToken(ASEmitterTokens.VAR);
+ writeToken(JSGoogEmitterTokens.SELF);
+ writeToken(ASEmitterTokens.EQUAL);
+ write(ASEmitterTokens.THIS);
+ writeNewline(ASEmitterTokens.SEMICOLON);
+ }
+
+ private void emitSuperCall(IASNode node, String type)
+ {
+ IFunctionNode fnode = (node instanceof IFunctionNode) ? (IFunctionNode) node
+ : null;
+ IFunctionCallNode fcnode = (node instanceof IFunctionCallNode) ? (FunctionCallNode) node
+ : null;
+
+ if (type == CONSTRUCTOR_EMPTY)
+ {
+ indentPush();
+ writeNewline();
+ indentPop();
+ }
+ else if (type == SUPER_FUNCTION_CALL)
+ {
+ if (fnode == null)
+ fnode = (IFunctionNode) fcnode
+ .getAncestorOfType(IFunctionNode.class);
+ }
+
+ write(JSGoogEmitterTokens.GOOG_BASE);
+ write(ASEmitterTokens.PAREN_OPEN);
+ write(ASEmitterTokens.THIS);
+
+ 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 == CONSTRUCTOR_FULL)
+ {
+ write(ASEmitterTokens.SEMICOLON);
+ writeNewline();
+ }
+ else if (type == CONSTRUCTOR_EMPTY)
+ {
+ write(ASEmitterTokens.SEMICOLON);
+ }
+ }
+
+ private void emitDefaultParameterCodeBlock(IFunctionNode node)
+ {
+ IParameterNode[] pnodes = node.getParameterNodes();
+ if (pnodes.length == 0)
+ return;
+
+ Map<Integer, IParameterNode> defaults = getDefaults(pnodes);
+
+ if (defaults != null)
+ {
+ final StringBuilder code = new StringBuilder();
+
+ if (!hasBody(node))
+ {
+ indentPush();
+ write(ASEmitterTokens.INDENT);
+ }
+
+ 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 && !hasBody(node))
+ indentPop();
+
+ writeNewline();
+ }
+ }
+ }
+ }
+
+ private void emitRestParameterCodeBlock(IFunctionNode node)
+ {
+ IParameterNode[] pnodes = node.getParameterNodes();
+
+ IParameterNode rest = 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
+ protected void emitAssignedValue(IExpressionNode node)
+ {
+ if (node != null)
+ {
+ write(ASEmitterTokens.SPACE);
+ writeToken(ASEmitterTokens.EQUAL);
+ if (node.getNodeID() == ASTNodeID.ClassReferenceID)
+ {
+ IDefinition definition = node.resolve(getWalker().getProject());
+ write(definition.getQualifiedName());
+ }
+ else
+ {
+ getWalker().walk(node);
+ }
+ }
+ }
+
+ @Override
+ public void emitTypedExpression(ITypedExpressionNode node)
+ {
+ getWalker().walk(node.getCollectionNode());
+ }
+
+ @Override
+ public void emitForEachLoop(IForLoopNode node)
+ {
+ IContainerNode xnode = (IContainerNode) node.getChild(1);
+ IBinaryOperatorNode bnode = (IBinaryOperatorNode) node
+ .getConditionalsContainerNode().getChild(0);
+ IVariableNode vnode = (IVariableNode) bnode.getChild(0).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);
+ write(vnode.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);
+ }
+
+ private Map<Integer, IParameterNode> getDefaults(IParameterNode[] nodes)
+ {
+ Map<Integer, IParameterNode> result = new HashMap<Integer, IParameterNode>();
+ int i = 0;
+ boolean hasDefaults = false;
+ for (IParameterNode node : nodes)
+ {
+ if (node.hasDefaultValue())
+ {
+ hasDefaults = true;
+ result.put(i, node);
+ }
+ else
+ {
+ result.put(i, null);
+ }
+ i++;
+ }
+
+ if (!hasDefaults)
+ return null;
+
+ return result;
+ }
+
+ private IParameterNode getRest(IParameterNode[] nodes)
+ {
+ for (IParameterNode node : nodes)
+ {
+ if (node.isRest())
+ return node;
+ }
+
+ return null;
+ }
+
+ private static ITypeDefinition getTypeDefinition(IDefinitionNode node)
+ {
+ ITypeNode tnode = (ITypeNode) node.getAncestorOfType(ITypeNode.class);
+ return (ITypeDefinition) tnode.getDefinition();
+ }
+
+ private static IClassDefinition getClassDefinition(IDefinitionNode node)
+ {
+ IClassNode tnode = (IClassNode) node
+ .getAncestorOfType(IClassNode.class);
+ return tnode.getDefinition();
+ }
+
+ private static IClassDefinition getSuperClassDefinition(
+ IDefinitionNode node, ICompilerProject project)
+ {
+ IClassDefinition parent = (IClassDefinition) node.getDefinition()
+ .getParent();
+ IClassDefinition superClass = parent.resolveBaseClass(project);
+ return superClass;
+ }
+
+ private boolean hasSuperClass(IDefinitionNode node)
+ {
+ ICompilerProject project = getWalker().getProject();
+ IClassDefinition superClassDefinition = getSuperClassDefinition(node,
+ project);
+ // XXX (mschmalle) this is nulling for MXML super class, figure out why
+ if (superClassDefinition == null)
+ return false;
+ String qname = superClassDefinition.getQualifiedName();
+ return superClassDefinition != null
+ && !qname.equals(IASLanguageConstants.Object);
+ }
+
+ private boolean hasSuperCall(IScopedNode node)
+ {
+ for (int i = node.getChildCount() - 1; i > -1; i--)
+ {
+ IASNode cnode = node.getChild(i);
+ if (cnode.getNodeID() == ASTNodeID.FunctionCallID
+ && cnode.getChild(0).getNodeID() == ASTNodeID.SuperID)
+ return true;
+ }
+
+ return false;
+ }
+
+ private static boolean hasBody(IFunctionNode node)
+ {
+ IScopedNode scope = node.getScopedNode();
+ return scope.getChildCount() > 0;
+ }
+
+ private void emitObjectDefineProperty(IAccessorNode node)
+ {
+ /*
+ Object.defineProperty(
+ A.prototype,
+ 'foo',
+ {get: function() {return -1;},
+ configurable: true}
+ );
+ */
+
+ FunctionNode fn = (FunctionNode) node;
+ fn.parseFunctionBody(problems);
+
+ // 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);
+ emitParamters(node.getParameterNodes());
+
+ emitMethodScope(node.getScopedNode());
+
+ 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);
+ }
+
+ //--------------------------------------------------------------------------
+ // Operators
+ //--------------------------------------------------------------------------
+
+ @Override
+ public void emitNamespaceAccessExpression(NamespaceAccessExpressionNode node)
+ {
+ getWalker().walk(node.getLeftOperandNode());
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ getWalker().walk(node.getRightOperandNode());
+ }
+
+ @Override
+ public void emitBinaryOperator(IBinaryOperatorNode node)
+ {
+ 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());
+ }
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ //--------------------------------------------------------------------------
+
+ private List<String> resolveImports(ITypeDefinition type)
+ {
+ ClassDefinition cdefinition = (ClassDefinition) type;
+ ArrayList<String> list = new ArrayList<String>();
+ IScopedNode scopeNode = type.getContainedScope().getScopeNode();
+ if (scopeNode != null)
+ {
+ scopeNode.getAllImports(list);
+ }
+ else
+ {
+ // MXML
+ String[] implicitImports = cdefinition.getImplicitImports();
+ for (String imp : implicitImports)
+ {
+ list.add(imp);
+ }
+ }
+ return list;
+ }
+}
Propchange: flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogEmitter.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogEmitterTokens.java
URL: http://svn.apache.org/viewvc/flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogEmitterTokens.java?rev=1452955&view=auto
==============================================================================
--- flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogEmitterTokens.java (added)
+++ flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogEmitterTokens.java Tue Mar 5 19:22:05 2013
@@ -0,0 +1,27 @@
+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("goog.base"),
+ GOOG_INHERITS("goog.inherits"),
+ GOOG_PROVIDE("goog.provide"),
+ GOOG_REQUIRE("goog.require"),
+ OBJECT("Object"),
+ SELF("self");
+
+ private String token;
+
+ private JSGoogEmitterTokens(String value)
+ {
+ token = value;
+ }
+
+ public String getToken()
+ {
+ return token;
+ }
+}
Propchange: flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogEmitterTokens.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogPublisher.java
URL: http://svn.apache.org/viewvc/flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogPublisher.java?rev=1452955&view=auto
==============================================================================
--- flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogPublisher.java (added)
+++ flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogPublisher.java Tue Mar 5 19:22:05 2013
@@ -0,0 +1,287 @@
+package org.apache.flex.compiler.internal.codegen.js.goog;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+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.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);
+ }
+
+ public File getOutputFolder()
+ {
+ File outputFolder = new File(configuration.getTargetFileDirectory())
+ .getParentFile();
+ outputFolder = new File(outputFolder,
+ JSGoogPublisher.GOOG_INTERMEDIATE_DIR_NAME);
+
+ return outputFolder;
+ }
+
+ public void publish() 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 String vanillaSDKSrcLibDirPath = ((JSGoogConfiguration) configuration)
+ .getVanillaSDKLib();
+ 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, 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);
+
+ 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 = (String[]) optionList.toArray(new String[0]);
+
+ JSClosureCompilerUtil.run(options);
+
+ appendSourceMapLocation(projectReleaseJSFilePath);
+
+ System.out.println("The project '" + projectName
+ + "' has been successfully compiled and optimized.");
+ }
+
+ 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);
+ }
+
+ private void appendSourceMapLocation(String path) throws IOException
+ {
+ StringBuilder appendString = new StringBuilder();
+ appendString.append("\n//@ sourceMappingURL=./Example.js.map");
+ writeFile(path, appendString.toString(), true);
+ }
+
+ private 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));
+ }
+
+ private 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);
+ }
+
+ private 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();
+ }
+
+ 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()
+ {
+ }
+ }
+}
Propchange: flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogPublisher.java
------------------------------------------------------------------------------
svn:eol-style = native