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:36 UTC
[44/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/externals/reference/ReferenceModel.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/reference/ReferenceModel.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/reference/ReferenceModel.java
new file mode 100644
index 0000000..090eb63
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/reference/ReferenceModel.java
@@ -0,0 +1,357 @@
+/*
+ *
+ * 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.externals.reference;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+
+import org.apache.flex.compiler.clients.ExternCConfiguration;
+import org.apache.flex.compiler.clients.ExternCConfiguration.ExcludedMember;
+import org.apache.flex.compiler.internal.codegen.externals.utils.DebugLogUtils;
+
+import com.google.javascript.jscomp.Compiler;
+import com.google.javascript.jscomp.NodeUtil;
+import com.google.javascript.rhino.JSDocInfo;
+import com.google.javascript.rhino.JSTypeExpression;
+import com.google.javascript.rhino.Node;
+import com.google.javascript.rhino.jstype.JSType;
+
+public class ReferenceModel
+{
+ private ExternCConfiguration configuration;
+ private Compiler jscompiler;
+
+ private List<String> namespaces = new ArrayList<String>();
+
+ private HashMap<String, ClassReference> typedefs = new HashMap<String, ClassReference>();
+ private HashMap<String, ClassReference> classes = new HashMap<String, ClassReference>();
+ private HashMap<String, FunctionReference> functions = new HashMap<String, FunctionReference>();
+ private HashMap<String, ConstantReference> constants = new HashMap<String, ConstantReference>();
+
+ // public Compiler getJSCompiler()
+ // {
+ // return jscompiler;
+ // }
+
+ public void setJSCompiler(Compiler compiler)
+ {
+ this.jscompiler = compiler;
+ }
+
+ public ExternCConfiguration getConfiguration()
+ {
+ return configuration;
+ }
+
+ public ClassReference getObjectReference()
+ {
+ return classes.get("Object");
+ }
+
+ public Collection<String> getNamespaces()
+ {
+ return namespaces;
+ }
+
+ public Collection<ClassReference> getTypedefs()
+ {
+ return typedefs.values();
+ }
+
+ public Collection<ClassReference> getClasses()
+ {
+ return classes.values();
+ }
+
+ public Collection<FunctionReference> getFunctions()
+ {
+ return functions.values();
+ }
+
+ public Collection<ConstantReference> getConstants()
+ {
+ return constants.values();
+ }
+
+ public ReferenceModel(ExternCConfiguration config)
+ {
+ this.configuration = config;
+ }
+
+ public ClassReference getClassReference(String qualifiedName)
+ {
+ return classes.get(qualifiedName);
+ }
+
+ public ClassReference getInterfaceReference(String qualifiedName)
+ {
+ ClassReference reference = classes.get(qualifiedName);
+ if (reference != null && reference.isInterface())
+ return reference;
+ return null;
+ }
+
+ public void addNamespace(Node node, String qualifiedName)
+ {
+ if (namespaces.contains(qualifiedName))
+ {
+ err("Duplicate namesapce [" + qualifiedName + "]");
+ return;
+ }
+
+ log("Model.addNamespace(" + qualifiedName + ")");
+
+ namespaces.add(qualifiedName);
+ }
+
+ public void addClass(Node node, String qualifiedName)
+ {
+ if (getConfiguration().isClassToFunctions(qualifiedName))
+ {
+ addFunction(node, qualifiedName);
+ return;
+ }
+
+ if (classes.containsKey(qualifiedName))
+ {
+ err("Duplicate class [" + qualifiedName + "]");
+ return;
+ }
+
+ log("Model.addClass(" + qualifiedName + ")");
+ ClassReference reference = new ClassReference(this, node, qualifiedName);
+
+ // TODO (mschmalle) Figure out if gcc makes any decisions about what is final or dynamic
+ if (reference.getQualifiedName().equals("Object"))
+ reference.setDynamic(true);
+
+ classes.put(qualifiedName, reference);
+ }
+
+ public void addEnum(Node node, String qualifiedName)
+ {
+ if (classes.containsKey(qualifiedName))
+ {
+ err("Duplicate class, @enum conflict [" + qualifiedName + "]");
+ return;
+ }
+
+ log("Model.addEnum(" + qualifiedName + ")");
+ ClassReference reference = new ClassReference(this, node, qualifiedName);
+ classes.put(qualifiedName, reference);
+ }
+
+ public void addTypeDef(Node node, String qualifiedName)
+ {
+ if (typedefs.containsKey(qualifiedName))
+ {
+ err("Duplicate @typedef [" + qualifiedName + "]");
+ return;
+ }
+
+ log("Model.addTypeDef(" + qualifiedName + ")");
+
+ ClassReference reference = new ClassReference(this, node, qualifiedName);
+ typedefs.put(qualifiedName, reference);
+ }
+
+ public void addInterface(Node node, String qualifiedName)
+ {
+ if (classes.containsKey(qualifiedName))
+ {
+ err("Duplicate @interface [" + qualifiedName + "]");
+ return;
+ }
+
+ log("Model.addInterface(" + qualifiedName + ")");
+
+ ClassReference reference = new ClassReference(this, node, qualifiedName);
+ classes.put(qualifiedName, reference);
+ }
+
+ public void addFinalClass(Node node, String qualifiedName)
+ {
+ if (classes.containsKey(qualifiedName))
+ {
+ err("Duplicate final class [" + qualifiedName + "]");
+ return;
+ }
+
+ log("Model.addFinalClass(" + qualifiedName + ")");
+
+ ClassReference reference = new ClassReference(this, node, qualifiedName);
+ reference.setFinal(true);
+ classes.put(qualifiedName, reference);
+ }
+
+ public void addFunction(Node node, String qualifiedName)
+ {
+ if (functions.containsKey(qualifiedName))
+ {
+ err("Duplicate global function [" + qualifiedName + "]");
+ return;
+ }
+
+ log("Model.addFunction(" + qualifiedName + ")");
+
+ FunctionReference reference = new FunctionReference(this, node, qualifiedName, node.getJSDocInfo());
+ functions.put(qualifiedName, reference);
+ }
+
+ public boolean hasClass(String className)
+ {
+ return classes.containsKey(className);
+ }
+
+ public boolean hasConstant(String qualifiedName)
+ {
+ return constants.containsKey(qualifiedName);
+ }
+
+ public void addConstant(Node node, String qualifiedName)
+ {
+ if (constants.containsKey(qualifiedName))
+ {
+ // XXX Record warning;
+ return;
+ }
+
+ log("Model.addConstant(" + qualifiedName + ")");
+
+ ConstantReference reference = new ConstantReference(this, node, qualifiedName, node.getJSDocInfo());
+ constants.put(qualifiedName, reference);
+ }
+
+ public void addConstantType(Node node, String qualifiedName, JSType type)
+ {
+ if (constants.containsKey(qualifiedName))
+ {
+ // XXX Record warning;
+ return;
+ }
+
+ log("Model.addConstantType(" + qualifiedName + ")");
+
+ ConstantReference reference = new ConstantReference(this, node, qualifiedName, node.getJSDocInfo(), type);
+ constants.put(qualifiedName, reference);
+ }
+
+ public void addField(Node node, String className, String memberName)
+ {
+ ClassReference classReference = getClassReference(className);
+ if (classReference != null)
+ classReference.addField(node, memberName, node.getJSDocInfo(), false);
+ }
+
+ public void addStaticField(Node node, String className, String memberName)
+ {
+ ClassReference classReference = getClassReference(className);
+ // XXX this is here because for now, the doc might be on the parent ASSIGN node
+ // if it's a static property with a value
+ JSDocInfo comment = NodeUtil.getBestJSDocInfo(node);
+ if (classReference != null)
+ {
+ classReference.addField(node, memberName, comment, true);
+ }
+ else
+ {
+ err(">>>> {ReferenceModel} Class [" + className + "] not found in " + node.getSourceFileName());
+ }
+ }
+
+ public void addMethod(Node node, String className, String memberName)
+ {
+ JSDocInfo comment = NodeUtil.getBestJSDocInfo(node);
+ ClassReference classReference = getClassReference(className);
+ if (classReference != null)
+ classReference.addMethod(node, memberName, comment, false);
+ }
+
+ public void addStaticMethod(Node node, String className, String memberName)
+ {
+ ClassReference classReference = getClassReference(className);
+ // XXX this is here because for now, the doc might be on the parent ASSIGN node
+ // if it's a static property with a value
+ JSDocInfo comment = NodeUtil.getBestJSDocInfo(node);
+ if (classReference != null)
+ {
+ classReference.addMethod(node, memberName, comment, true);
+ }
+ else
+ {
+ err(">>>> {ReferenceModel} Class [" + className + "] not found in " + node.getSourceFileName());
+ }
+ }
+
+ public final JSType evaluate(JSTypeExpression expression)
+ {
+ JSType jsType = null;
+
+ if (expression != null)
+ {
+ try
+ {
+ jsType = expression.evaluate(null, jscompiler.getTypeRegistry());
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ return jsType;
+ }
+
+ //--------------------------------------------------------------------------
+
+ public ExcludedMember isExcludedClass(ClassReference classReference)
+ {
+ return getConfiguration().isExcludedClass(classReference);
+ }
+
+ public ExcludedMember isExcludedMember(ClassReference classReference, MemberReference memberReference)
+ {
+ return getConfiguration().isExcludedMember(classReference, memberReference);
+ }
+
+ //--------------------------------------------------------------------------
+
+ protected void log(Node n)
+ {
+ DebugLogUtils.err(n);
+ }
+
+ protected void err(Node n)
+ {
+ DebugLogUtils.err(n);
+ }
+
+ protected void log(String message)
+ {
+ DebugLogUtils.log(message);
+ }
+
+ protected void err(String message)
+ {
+ DebugLogUtils.err(message);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/utils/DebugLogUtils.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/utils/DebugLogUtils.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/utils/DebugLogUtils.java
new file mode 100644
index 0000000..5dcdc48
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/utils/DebugLogUtils.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.externals.utils;
+
+import com.google.javascript.rhino.Node;
+
+public final class DebugLogUtils
+{
+ private static boolean logEnabled = false;
+ private static boolean errEnabled = false;
+
+ public static void log(Node n)
+ {
+ log("StringTree -------------------------------------");
+ log(n.toStringTree());
+ }
+
+ public static void log(String message)
+ {
+ if (logEnabled)
+ System.out.println(message);
+ }
+
+ public static void err(String message)
+ {
+ if (errEnabled)
+ System.err.println(message);
+ }
+
+ public static void err(Node n)
+ {
+ err("StringTree -------------------------------------");
+ err(n.toStringTree());
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/utils/FunctionUtils.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/utils/FunctionUtils.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/utils/FunctionUtils.java
new file mode 100644
index 0000000..473e42c
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/utils/FunctionUtils.java
@@ -0,0 +1,232 @@
+/*
+ *
+ * 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.externals.utils;
+
+import org.apache.flex.compiler.internal.codegen.externals.reference.BaseReference;
+import org.apache.flex.compiler.internal.codegen.externals.reference.ClassReference;
+import org.apache.flex.compiler.internal.codegen.externals.reference.ReferenceModel;
+
+import com.google.common.base.Strings;
+import com.google.javascript.rhino.JSDocInfo;
+import com.google.javascript.rhino.JSTypeExpression;
+import com.google.javascript.rhino.Node;
+
+public class FunctionUtils
+{
+ /**
+ * Compute the type of a function or method parameter.
+ *
+ * @param reference The FunctionReference or MethodReference the parameter belongs to
+ * @param name The name of the parameter
+ * @return the type of a function or method parameter
+ */
+ public static String toParameterType(final BaseReference reference, final String name)
+ {
+
+ String parameterType;
+ if (FunctionUtils.hasTemplate(reference) && FunctionUtils.containsTemplate(reference, name))
+ {
+ parameterType = "Object";
+ }
+ else
+ {
+ parameterType = JSTypeUtils.toParamTypeString(reference, name);
+ }
+
+ return parameterType;
+ }
+
+ public static String toReturnString(BaseReference reference)
+ {
+ final StringBuilder sb = new StringBuilder();
+
+ String returnType;
+
+ if (hasTemplate(reference))
+ {
+ returnType = JSTypeUtils.toReturnTypeString(reference);
+ if (containsTemplate(reference, returnType))
+ returnType = "*";
+ else if (returnType.equals("RESULT"))
+ returnType = "Object";
+ }
+ else
+ {
+ returnType = JSTypeUtils.toReturnTypeString(reference);
+ }
+
+ sb.append(returnType);
+
+ return sb.toString();
+ }
+
+ public static String toParameterString(BaseReference reference, JSDocInfo comment, Node paramNode, boolean outputJS)
+ {
+ final StringBuilder sb = new StringBuilder();
+
+ sb.append("(");
+
+ if (paramNode != null)
+ {
+ int index = 0;
+ int len = comment.getParameterCount();
+ if (len == 0)
+ {
+ // Missing JSDocInf @param tags, so instead of using the @param tags
+ // we use the actual Node list from the AST
+ len = paramNode.getChildCount();
+ if (len > 0)
+ {
+ for (Node param : paramNode.children())
+ {
+ sb.append(param.getString());
+ if (!outputJS)
+ sb.append(":Object");
+ if (index < len - 1)
+ sb.append(", ");
+ index++;
+ }
+ }
+ }
+ else
+ {
+ for (String paramName : comment.getParameterNames())
+ {
+ sb.append(toParameter(reference, comment, paramName, comment.getParameterType(paramName), outputJS));
+
+ if (index < len - 1)
+ sb.append(", ");
+
+ index++;
+ }
+ }
+ }
+
+ sb.append(")");
+
+ return sb.toString();
+ }
+
+ /**
+ * Check we can import the given type into the given package.
+ *
+ * @param model The containing reference model
+ * @param node The containing node
+ * @param typeName The type we want check
+ * @param packageName The current package
+ * @return true if we can import the given type into the given package
+ */
+ public static boolean canBeImported(final ReferenceModel model, final Node node, final String typeName,
+ final String packageName)
+ {
+ boolean canImport = false;
+
+ if (model != null && node != null && !Strings.isNullOrEmpty(typeName))
+ {
+ final ClassReference reference = new ClassReference(null, node, typeName);
+
+ final int lastDotPosition = typeName.lastIndexOf(".");
+
+ // Can import when the type to import does not belong to the current package.
+ canImport = lastDotPosition > -1 && !typeName.substring(0, lastDotPosition).equals(packageName);
+
+ // And is not excluded.
+ canImport &= model.isExcludedClass(reference) == null;
+ }
+
+ return canImport;
+ }
+
+ private static String toParameter(BaseReference reference, JSDocInfo comment, String paramName,
+ JSTypeExpression parameterType, boolean outputJS)
+ {
+ final StringBuilder sb = new StringBuilder();
+
+ String paramType;
+
+ if (parameterType == null)
+ {
+ System.out.println("no parameter type for " + paramName + " " + reference.getQualifiedName());
+ paramType = "Object";
+ if (outputJS)
+ sb.append(paramName);
+ }
+ else if (parameterType.isVarArgs())
+ {
+ if (outputJS)
+ sb.append("var_").append(paramName);
+ else
+ sb.append("...").append(paramName);
+ }
+ else
+ {
+ paramType = JSTypeUtils.toParamTypeString(reference, paramName);
+ if (hasTemplate(reference) && containsTemplate(reference, paramType))
+ {
+ paramType = "Object";
+ }
+
+ sb.append(paramName);
+ if (!outputJS)
+ {
+ sb.append(":");
+ sb.append(paramType);
+ if (parameterType.isOptionalArg())
+ {
+ sb.append(" = ");
+ sb.append(toDefaultParameterValue(paramType));
+ }
+ }
+ }
+
+ return sb.toString();
+ }
+
+ private static String toDefaultParameterValue(String paramType)
+ {
+ if (paramType.equals("Function"))
+ return "null";
+ else if (paramType.equals("Number"))
+ return "0";
+ else if (paramType.equals("String"))
+ return "''";
+ else if (paramType.equals("Boolean"))
+ return "false";
+ return "null";
+ }
+
+ public static boolean hasTemplate(BaseReference reference)
+ {
+ return reference.getComment().getTemplateTypeNames().size() > 0;
+ }
+
+ public static boolean containsTemplate(BaseReference reference, String name)
+ {
+ for (String template : reference.getComment().getTemplateTypeNames())
+ {
+ if (name.contains("<" + template + ">"))
+ return true;
+ if (name.equals(template))
+ return true;
+ }
+ return false;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/utils/JSTypeUtils.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/utils/JSTypeUtils.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/utils/JSTypeUtils.java
new file mode 100644
index 0000000..c14ddb8
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/utils/JSTypeUtils.java
@@ -0,0 +1,169 @@
+/*
+ *
+ * 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.externals.utils;
+
+import java.util.HashMap;
+
+import org.apache.flex.compiler.internal.codegen.externals.reference.BaseReference;
+import org.apache.flex.compiler.internal.codegen.externals.reference.ClassReference;
+import org.apache.flex.compiler.internal.codegen.externals.reference.ConstantReference;
+import org.apache.flex.compiler.internal.codegen.externals.reference.ReferenceModel;
+
+import com.google.javascript.rhino.JSTypeExpression;
+import com.google.javascript.rhino.jstype.JSType;
+import com.google.javascript.rhino.jstype.UnionType;
+
+public class JSTypeUtils
+{
+ public static String toClassTypeString(ClassReference reference)
+ {
+ String type = getJsType(reference.getModel(), reference.getComment().getBaseType()).toString();
+ return type;
+ }
+
+ public static String toParamTypeString(BaseReference reference, String paramName)
+ {
+ JSTypeExpression expression = reference.getComment().getParameterType(paramName);
+ if (expression == null)
+ return "Object";
+
+ String type = toTypeExpressionString(reference, expression);
+ type = transformType(type);
+
+ return type;
+ }
+
+ public static String toReturnTypeString(BaseReference reference)
+ {
+ JSTypeExpression expression = reference.getComment().getReturnType();
+ if (expression == null)
+ return "void";
+
+ String type = toTypeExpressionString(reference, expression);
+ type = transformType(type);
+
+ return type;
+ }
+
+ public static String toFieldTypeString(BaseReference reference)
+ {
+ JSTypeExpression expression = reference.getComment().getType();
+ if (expression == null)
+ return "Object";
+
+ String type = toTypeExpressionString(reference, expression);
+ type = transformType(type);
+
+ return type;
+ }
+
+ public static String toEnumTypeString(BaseReference reference)
+ {
+ JSTypeExpression enumParameterType = reference.getComment().getEnumParameterType();
+ String overrideStringType = transformType(reference.getModel().evaluate(enumParameterType).toAnnotationString());
+
+ return overrideStringType;
+ }
+
+ public static String toConstantTypeString(ConstantReference reference)
+ {
+ JSTypeExpression expression = reference.getComment().getType();
+ if (expression == null)
+ return "Object";
+
+ String type = toTypeExpressionString(reference, expression);
+ type = transformType(type);
+
+ return type;
+ }
+
+ //--------------------------------------------------------------------------
+
+ public static String transformType(String type)
+ {
+ // XXX This is an error but, needs to be reduced in @param union
+ if (type.indexOf("|") != -1)
+ return "Object";
+
+ HashMap<String, String> map = new HashMap<String, String>();
+ map.put("?", "Object /* ? */");
+ map.put("*", "*");
+ map.put("string", "String");
+ map.put("number", "Number");
+ map.put("boolean", "Boolean");
+ map.put("undefined", "Object /* undefined */");
+ map.put("null", "Object /* null */");
+
+ if (map.containsKey(type))
+ return map.get(type);
+
+ return type;
+ }
+
+ private static String toTypeExpressionString(BaseReference reference, JSTypeExpression expression)
+ {
+ JSType jsType = getJsType(reference.getModel(), expression);
+ String type = toTypeString(jsType);
+ return type;
+ }
+
+ private static String toTypeString(JSType jsType)
+ {
+ String type = jsType.toString();
+
+ if (jsType.isFunctionType())
+ {
+ return "Function /* " + type + " */";
+ }
+ else if (jsType.isRecordType())
+ {
+ return "Object /* " + type + " */";
+ }
+ else
+ {
+ if (type.indexOf("Array<") == 0)
+ {
+ return "Array";
+ }
+ else if (type.indexOf("Object<") == 0)
+ {
+ return "Object";
+ }
+ }
+
+ return type;
+ }
+
+ private static JSType getJsType(ReferenceModel model, JSTypeExpression typeExpression)
+ {
+ JSType jsType = model.evaluate(typeExpression);
+
+ if (jsType.isUnionType())
+ {
+ UnionType ut = (UnionType) jsType;
+ JSType jsType2 = ut.restrictByNotNullOrUndefined();
+
+ if (!jsType2.isUnionType())
+ jsType = jsType2;
+ }
+
+ return jsType;
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSDocEmitter.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSDocEmitter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSDocEmitter.java
new file mode 100644
index 0000000..743ecce
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSDocEmitter.java
@@ -0,0 +1,174 @@
+/*
+ *
+ * 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;
+
+import org.apache.flex.compiler.codegen.IDocEmitter;
+import org.apache.flex.compiler.codegen.IEmitter;
+import org.apache.flex.compiler.codegen.IEmitterTokens;
+import org.apache.flex.compiler.codegen.js.IJSEmitter;
+import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
+import org.apache.flex.compiler.tree.as.IASNode;
+
+public class JSDocEmitter implements IDocEmitter, IEmitter
+{
+
+ private int currentIndent = 0;
+
+ protected IEmitter emitter;
+
+ private StringBuilder builder;
+
+ protected StringBuilder getBuilder()
+ {
+ return builder;
+ }
+
+ private boolean bufferWrite;
+
+ public boolean isBufferWrite()
+ {
+ return bufferWrite;
+ }
+
+ public void setBufferWrite(boolean value)
+ {
+ bufferWrite = value;
+ }
+
+ public String flushBuffer()
+ {
+ setBufferWrite(false);
+ String result = builder.toString();
+ builder.setLength(0);
+ return result;
+ }
+
+ public JSDocEmitter(IJSEmitter emitter)
+ {
+ this.emitter = (IEmitter) emitter;
+
+ builder = new StringBuilder();
+ }
+
+ @Override
+ public void indentPush()
+ {
+ currentIndent++;
+ }
+
+ @Override
+ public void indentPop()
+ {
+ currentIndent--;
+ }
+
+ @Override
+ public void write(IEmitterTokens value)
+ {
+ write(value.getToken());
+ }
+
+ @Override
+ public void write(String value)
+ {
+ if (!bufferWrite)
+ emitter.write(value);
+ else
+ builder.append(value);
+ }
+
+ @Override
+ public void writeNewline()
+ {
+ write(ASEmitterTokens.NEW_LINE);
+ }
+
+ @Override
+ public void writeNewline(String value)
+ {
+ write(value);
+ writeNewline();
+ }
+
+ @Override
+ public void writeNewline(IEmitterTokens value)
+ {
+ writeNewline(value.getToken());
+ }
+
+ @Override
+ public void writeNewline(String value, boolean pushIndent)
+ {
+ if (pushIndent)
+ indentPush();
+ else
+ indentPop();
+ write(value);
+ writeNewline();
+ }
+
+ @Override
+ public void writeNewline(IEmitterTokens value, boolean pushIndent)
+ {
+ writeNewline(value.getToken(), pushIndent);
+ }
+
+ @Override
+ public void writeToken(IEmitterTokens value)
+ {
+ writeToken(value.getToken());
+ }
+
+ @Override
+ public void writeToken(String value)
+ {
+ write(value);
+ write(ASEmitterTokens.SPACE);
+ }
+
+ public void writeBlockClose()
+ {
+ write(ASEmitterTokens.BLOCK_CLOSE);
+ }
+
+ public void writeBlockOpen()
+ {
+ write(ASEmitterTokens.BLOCK_OPEN);
+ }
+
+ @Override
+ public void begin()
+ {
+ writeNewline(JSDocEmitterTokens.JSDOC_OPEN);
+ }
+
+ @Override
+ public void end()
+ {
+ write(ASEmitterTokens.SPACE);
+ writeNewline(JSDocEmitterTokens.JSDOC_CLOSE);
+ }
+
+ @Override
+ public String stringifyNode(IASNode node)
+ {
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSDocEmitterTokens.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSDocEmitterTokens.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSDocEmitterTokens.java
new file mode 100644
index 0000000..813e36b
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSDocEmitterTokens.java
@@ -0,0 +1,38 @@
+/*
+ *
+ * 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;
+
+import org.apache.flex.compiler.codegen.IEmitterTokens;
+
+public enum JSDocEmitterTokens implements IEmitterTokens
+{
+ JSDOC_CLOSE("*/"), JSDOC_OPEN("/**");
+
+ private String token;
+
+ private JSDocEmitterTokens(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/JSEmitter.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSEmitter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSEmitter.java
new file mode 100644
index 0000000..a50e288
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSEmitter.java
@@ -0,0 +1,453 @@
+/*
+ *
+ * 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;
+
+import java.io.FilterWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+import org.apache.flex.compiler.codegen.js.IJSEmitter;
+import org.apache.flex.compiler.common.ASModifier;
+import org.apache.flex.compiler.common.ISourceLocation;
+import org.apache.flex.compiler.definitions.ITypeDefinition;
+import org.apache.flex.compiler.internal.codegen.as.ASEmitter;
+import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
+import org.apache.flex.compiler.internal.codegen.js.jx.DoWhileLoopEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.DynamicAccessEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.ForLoopEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.FunctionCallArgumentsEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.IfEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.IterationFlowEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.LanguageIdentifierEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.LiteralContainerEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.MemberKeywordEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.NumericLiteralEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.ObjectLiteralValuePairEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.ParameterEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.ParametersEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.ReturnEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.SourceMapDirectiveEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.StatementEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.TernaryOperatorEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.UnaryOperatorEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.WhileLoopEmitter;
+import org.apache.flex.compiler.internal.codegen.js.utils.EmitterUtils;
+import org.apache.flex.compiler.internal.tree.as.FunctionNode;
+import org.apache.flex.compiler.tree.as.IASNode;
+import org.apache.flex.compiler.tree.as.IContainerNode;
+import org.apache.flex.compiler.tree.as.IDefinitionNode;
+import org.apache.flex.compiler.tree.as.IDynamicAccessNode;
+import org.apache.flex.compiler.tree.as.IForLoopNode;
+import org.apache.flex.compiler.tree.as.IFunctionNode;
+import org.apache.flex.compiler.tree.as.IFunctionObjectNode;
+import org.apache.flex.compiler.tree.as.IIfNode;
+import org.apache.flex.compiler.tree.as.IIterationFlowNode;
+import org.apache.flex.compiler.tree.as.ILanguageIdentifierNode;
+import org.apache.flex.compiler.tree.as.ILiteralContainerNode;
+import org.apache.flex.compiler.tree.as.INumericLiteralNode;
+import org.apache.flex.compiler.tree.as.IObjectLiteralValuePairNode;
+import org.apache.flex.compiler.tree.as.IPackageNode;
+import org.apache.flex.compiler.tree.as.IParameterNode;
+import org.apache.flex.compiler.tree.as.IReturnNode;
+import org.apache.flex.compiler.tree.as.ITernaryOperatorNode;
+import org.apache.flex.compiler.tree.as.ITypeNode;
+import org.apache.flex.compiler.tree.as.ITypedExpressionNode;
+import org.apache.flex.compiler.tree.as.IUnaryOperatorNode;
+import org.apache.flex.compiler.tree.as.IWhileLoopNode;
+
+import com.google.debugging.sourcemap.FilePosition;
+
+/**
+ * @author Michael Schmalle
+ */
+public class JSEmitter extends ASEmitter implements IJSEmitter
+{
+ private JSSessionModel model;
+
+ public NumericLiteralEmitter numericLiteralEmitter;
+ public ParametersEmitter parametersEmitter;
+ public ParameterEmitter parameterEmitter;
+ public FunctionCallArgumentsEmitter functionCallArgumentsEmitter;
+ public LiteralContainerEmitter literalContainerEmitter;
+ public ObjectLiteralValuePairEmitter objectLiteralValuePairEmitter;
+ public ReturnEmitter returnEmitter;
+ public DynamicAccessEmitter dynamicAccessEmitter;
+ public UnaryOperatorEmitter unaryOperatorEmitter;
+ public TernaryOperatorEmitter ternaryOperatorEmitter;
+ public MemberKeywordEmitter memberKeywordEmitter;
+ public IfEmitter ifEmitter;
+ public WhileLoopEmitter whileLoopEmitter;
+ public DoWhileLoopEmitter doWhileLoopEmitter;
+ public ForLoopEmitter forLoopEmitter;
+ public IterationFlowEmitter interationFlowEmitter;
+ public StatementEmitter statementEmitter;
+ public LanguageIdentifierEmitter languageIdentifierEmitter;
+ public SourceMapDirectiveEmitter sourceMapDirectiveEmitter;
+
+ @Override
+ public JSSessionModel getModel()
+ {
+ return model;
+ }
+
+ private SourceMapMapping lastMapping;
+
+ private Stack<String> nameStack = new Stack<String>();
+
+ private List<SourceMapMapping> sourceMapMappings;
+
+ public List<SourceMapMapping> getSourceMapMappings()
+ {
+ return sourceMapMappings;
+ }
+
+ public JSEmitter(FilterWriter out)
+ {
+ super(out);
+
+ model = new JSSessionModel();
+ sourceMapMappings = new ArrayList<SourceMapMapping>();
+
+ numericLiteralEmitter = new NumericLiteralEmitter(this);
+ parametersEmitter = new ParametersEmitter(this);
+ parameterEmitter = new ParameterEmitter(this);
+ functionCallArgumentsEmitter = new FunctionCallArgumentsEmitter(this);
+ literalContainerEmitter = new LiteralContainerEmitter(this);
+ objectLiteralValuePairEmitter = new ObjectLiteralValuePairEmitter(this);
+ returnEmitter = new ReturnEmitter(this);
+ dynamicAccessEmitter = new DynamicAccessEmitter(this);
+ unaryOperatorEmitter = new UnaryOperatorEmitter(this);
+ ternaryOperatorEmitter = new TernaryOperatorEmitter(this);
+ memberKeywordEmitter = new MemberKeywordEmitter(this);
+ ifEmitter = new IfEmitter(this);
+ whileLoopEmitter = new WhileLoopEmitter(this);
+ doWhileLoopEmitter = new DoWhileLoopEmitter(this);
+ forLoopEmitter = new ForLoopEmitter(this);
+ interationFlowEmitter = new IterationFlowEmitter(this);
+ statementEmitter = new StatementEmitter(this);
+ languageIdentifierEmitter = new LanguageIdentifierEmitter(this);
+ sourceMapDirectiveEmitter = new SourceMapDirectiveEmitter(this);
+ }
+
+ @Override
+ public String formatQualifiedName(String name)
+ {
+ return name;
+ }
+
+ @Override
+ public void emitLocalNamedFunction(IFunctionNode node)
+ {
+ startMapping(node);
+ FunctionNode fnode = (FunctionNode)node;
+ write(ASEmitterTokens.FUNCTION);
+ write(ASEmitterTokens.SPACE);
+ write(fnode.getName());
+ endMapping(node);
+ emitParameters(fnode.getParametersContainerNode());
+ emitFunctionScope(fnode.getScopedNode());
+ }
+
+ @Override
+ public void emitFunctionObject(IFunctionObjectNode node)
+ {
+ startMapping(node);
+ FunctionNode fnode = node.getFunctionNode();
+ write(ASEmitterTokens.FUNCTION);
+ endMapping(node);
+ emitParameters(fnode.getParametersContainerNode());
+ emitFunctionScope(fnode.getScopedNode());
+ }
+
+ public void emitClosureStart()
+ {
+
+ }
+
+ public void emitClosureEnd(IASNode node)
+ {
+
+ }
+
+ public void emitSourceMapDirective(ITypeNode node)
+ {
+ sourceMapDirectiveEmitter.emit(node);
+ }
+
+ public void emitParameters(IContainerNode node)
+ {
+ parametersEmitter.emit(node);
+ }
+
+ @Override
+ public void emitParameter(IParameterNode node)
+ {
+ parameterEmitter.emit(node);
+ }
+
+ @Override
+ public void emitArguments(IContainerNode node)
+ {
+ functionCallArgumentsEmitter.emit(node);
+ }
+
+ @Override
+ public void emitNumericLiteral(INumericLiteralNode node)
+ {
+ numericLiteralEmitter.emit(node);
+ }
+
+ @Override
+ public void emitLiteralContainer(ILiteralContainerNode node)
+ {
+ literalContainerEmitter.emit(node);
+ }
+
+ @Override
+ public void emitObjectLiteralValuePair(IObjectLiteralValuePairNode node)
+ {
+ objectLiteralValuePairEmitter.emit(node);
+ }
+
+ @Override
+ public void emitReturn(IReturnNode node)
+ {
+ returnEmitter.emit(node);
+ }
+
+ @Override
+ public void emitTypedExpression(ITypedExpressionNode node)
+ {
+ write(JSEmitterTokens.ARRAY);
+ }
+
+ @Override
+ public void emitDynamicAccess(IDynamicAccessNode node)
+ {
+ dynamicAccessEmitter.emit(node);
+ }
+
+ @Override
+ public void emitMemberKeyword(IDefinitionNode node)
+ {
+ memberKeywordEmitter.emit(node);
+ }
+
+ @Override
+ public void emitUnaryOperator(IUnaryOperatorNode node)
+ {
+ unaryOperatorEmitter.emit(node);
+ }
+
+ @Override
+ public void emitTernaryOperator(ITernaryOperatorNode node)
+ {
+ ternaryOperatorEmitter.emit(node);
+ }
+
+ @Override
+ public void emitLanguageIdentifier(ILanguageIdentifierNode node)
+ {
+ languageIdentifierEmitter.emit(node);
+ }
+
+ @Override
+ public void emitStatement(IASNode node)
+ {
+ statementEmitter.emit(node);
+ }
+
+ @Override
+ public void emitIf(IIfNode node)
+ {
+ ifEmitter.emit(node);
+ }
+
+ @Override
+ public void emitWhileLoop(IWhileLoopNode node)
+ {
+ whileLoopEmitter.emit(node);
+ }
+
+ @Override
+ public void emitDoLoop(IWhileLoopNode node)
+ {
+ doWhileLoopEmitter.emit(node);
+ }
+
+ @Override
+ public void emitForLoop(IForLoopNode node)
+ {
+ forLoopEmitter.emit(node);
+ }
+
+ @Override
+ public void emitIterationFlow(IIterationFlowNode node)
+ {
+ interationFlowEmitter.emit(node);
+ }
+
+ public void pushSourceMapName(ISourceLocation node)
+ {
+ boolean isValidMappingScope = node instanceof ITypeNode
+ || node instanceof IPackageNode
+ || node instanceof IFunctionNode;
+ if(!isValidMappingScope)
+ {
+ throw new IllegalStateException("A source mapping scope must be a package, type, or function.");
+ }
+
+ IDefinitionNode definitionNode = (IDefinitionNode) node;
+ String nodeName = definitionNode.getQualifiedName();
+ ITypeDefinition typeDef = EmitterUtils.getTypeDefinition(definitionNode);
+ if (typeDef != null)
+ {
+ boolean isConstructor = node instanceof IFunctionNode &&
+ ((IFunctionNode) node).isConstructor();
+ boolean isStatic = definitionNode.hasModifier(ASModifier.STATIC);
+ if (isConstructor)
+ {
+ nodeName = typeDef.getQualifiedName() + ".constructor";
+ }
+ else if (isStatic)
+ {
+ nodeName = typeDef.getQualifiedName() + "." + nodeName;
+ }
+ else
+ {
+ nodeName = typeDef.getQualifiedName() + ".prototype." + nodeName;
+ }
+ }
+ nameStack.push(nodeName);
+ }
+
+ public void popSourceMapName()
+ {
+ nameStack.pop();
+ }
+
+ public void startMapping(ISourceLocation node)
+ {
+ startMapping(node, node.getLine(), node.getColumn());
+ }
+
+ public void startMapping(ISourceLocation node, ISourceLocation nodeBeforeMapping)
+ {
+ startMapping(node, nodeBeforeMapping.getLine(), nodeBeforeMapping.getColumn() + nodeBeforeMapping.getAbsoluteEnd() - nodeBeforeMapping.getAbsoluteStart());
+ }
+
+ public void startMapping(ISourceLocation node, int line, int column)
+ {
+ if (lastMapping != null)
+ {
+ FilePosition sourceStartPosition = lastMapping.sourceStartPosition;
+ throw new IllegalStateException("Cannot start new mapping when another mapping is already started. "
+ + "Previous mapping at Line " + sourceStartPosition.getLine()
+ + " and Column " + sourceStartPosition.getColumn()
+ + " in file " + lastMapping.sourcePath);
+ }
+
+ String sourcePath = node.getSourcePath();
+ if (sourcePath == null)
+ {
+ //if the source path is null, this node may have been generated by
+ //the compiler automatically. for example, an untyped variable will
+ //have a node for the * type.
+ if (node instanceof IASNode)
+ {
+ IASNode parentNode = ((IASNode) node).getParent();
+ if (parentNode != null)
+ {
+ //try the parent node
+ startMapping(parentNode, line, column);
+ return;
+ }
+ }
+ }
+
+ String nodeName = null;
+ if (nameStack.size() > 0)
+ {
+ nodeName = nameStack.lastElement();
+ }
+ SourceMapMapping mapping = new SourceMapMapping();
+ mapping.sourcePath = sourcePath;
+ mapping.name = nodeName;
+ mapping.sourceStartPosition = new FilePosition(line, column);
+ mapping.destStartPosition = new FilePosition(getCurrentLine(), getCurrentColumn());
+ lastMapping = mapping;
+ }
+
+ public void endMapping(ISourceLocation node)
+ {
+ if (lastMapping == null)
+ {
+ throw new IllegalStateException("Cannot end mapping when a mapping has not been started");
+ }
+
+ lastMapping.destEndPosition = new FilePosition(getCurrentLine(), getCurrentColumn());
+ sourceMapMappings.add(lastMapping);
+ lastMapping = null;
+ }
+
+ /**
+ * Adjusts the line numbers saved in the source map when a line should be
+ * added during post processing.
+ *
+ * @param lineIndex
+ */
+ protected void addLineToMappings(int lineIndex)
+ {
+ for (SourceMapMapping mapping : sourceMapMappings)
+ {
+ FilePosition destStartPosition = mapping.destStartPosition;
+ int startLine = destStartPosition.getLine();
+ if(startLine > lineIndex)
+ {
+ mapping.destStartPosition = new FilePosition(startLine + 1, destStartPosition.getColumn());
+ FilePosition destEndPosition = mapping.destEndPosition;
+ mapping.destEndPosition = new FilePosition(destEndPosition.getLine() + 1, destEndPosition.getColumn());
+ }
+ }
+ }
+
+ /**
+ * Adjusts the line numbers saved in the source map when a line should be
+ * removed during post processing.
+ *
+ * @param lineIndex
+ */
+ protected void removeLineFromMappings(int lineIndex)
+ {
+ for (SourceMapMapping mapping : sourceMapMappings)
+ {
+ FilePosition destStartPosition = mapping.destStartPosition;
+ int startLine = destStartPosition.getLine();
+ if(startLine > lineIndex)
+ {
+ mapping.destStartPosition = new FilePosition(startLine - 1, destStartPosition.getColumn());
+ FilePosition destEndPosition = mapping.destEndPosition;
+ mapping.destEndPosition = new FilePosition(destEndPosition.getLine() - 1, destEndPosition.getColumn());
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSEmitterTokens.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSEmitterTokens.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSEmitterTokens.java
new file mode 100644
index 0000000..82935af
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSEmitterTokens.java
@@ -0,0 +1,47 @@
+/*
+ *
+ * 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;
+
+import org.apache.flex.compiler.codegen.IEmitterTokens;
+
+public enum JSEmitterTokens implements IEmitterTokens
+{
+ ARGUMENTS("arguments"),
+ CALL("call"),
+ CONFIGURABLE("configurable"),
+ CONSTRUCTOR("constructor"),
+ DEFINE_PROPERTY("defineProperty"),
+ DEFINE_PROPERTIES("defineProperties"),
+ INTERFACE("interface"),
+ PROTOTYPE("prototype"),
+ SLICE("slice"),
+ ARRAY("Array");
+
+ private String token;
+
+ private JSEmitterTokens(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/JSFilterWriter.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSFilterWriter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSFilterWriter.java
new file mode 100644
index 0000000..bf17a87
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSFilterWriter.java
@@ -0,0 +1,43 @@
+/*
+ *
+ * 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;
+
+import java.io.Writer;
+
+import org.apache.flex.compiler.internal.codegen.as.ASFilterWriter;
+
+/**
+ * @author Michael Schmalle
+ */
+public class JSFilterWriter extends ASFilterWriter
+{
+
+ public JSFilterWriter(Writer out)
+ {
+ super(out);
+ }
+
+ @Override
+ public String toString()
+ {
+ return out.toString();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSPublisher.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSPublisher.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSPublisher.java
new file mode 100644
index 0000000..cc49504
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSPublisher.java
@@ -0,0 +1,85 @@
+/*
+ *
+ * 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;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.flex.compiler.clients.problems.ProblemQuery;
+import org.apache.flex.compiler.codegen.js.IJSPublisher;
+import org.apache.flex.compiler.config.Configuration;
+
+public class JSPublisher implements IJSPublisher
+{
+
+ public JSPublisher(Configuration config)
+ {
+ this.configuration = config;
+ }
+
+ protected File outputFolder;
+ protected File outputParentFolder;
+
+
+ protected Configuration configuration;
+
+ public File getOutputFolder()
+ {
+ outputFolder = new File(getOutputFilePath());
+ if (!outputFolder.isDirectory())
+ outputFolder = outputFolder.getParentFile();
+
+ outputParentFolder = outputFolder;
+
+ setupOutputFolder();
+
+ return outputFolder;
+ }
+
+ protected void setupOutputFolder()
+ {
+ if (outputParentFolder.exists())
+ org.apache.commons.io.FileUtils.deleteQuietly(outputParentFolder);
+
+ if (!outputFolder.exists())
+ outputFolder.mkdirs();
+ }
+
+ private String getOutputFilePath()
+ {
+ if (configuration.getOutput() == null)
+ {
+ final String extension = "." + JSSharedData.OUTPUT_EXTENSION;
+ return FilenameUtils.removeExtension(configuration.getTargetFile())
+ .concat(extension);
+ }
+ else
+ return configuration.getOutput();
+ }
+
+ public boolean publish(ProblemQuery problems) throws IOException
+ {
+ System.out
+ .println("The project has been successfully compiled and optimized.");
+ return true;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSessionModel.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSessionModel.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSessionModel.java
new file mode 100644
index 0000000..5c45227
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSessionModel.java
@@ -0,0 +1,180 @@
+/*
+ *
+ * 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;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Stack;
+
+import org.apache.flex.compiler.definitions.IClassDefinition;
+import org.apache.flex.compiler.tree.as.IFunctionNode;
+import org.apache.flex.compiler.tree.as.IGetterNode;
+import org.apache.flex.compiler.tree.as.ISetterNode;
+import org.apache.flex.compiler.tree.as.IVariableNode;
+
+/**
+ * @author Michael Schmalle
+ */
+public class JSSessionModel
+{
+ public static final String CONSTRUCTOR_EMPTY = "emptyConstructor";
+ public static final String CONSTRUCTOR_FULL = "fullConstructor";
+ public static final String SUPER_FUNCTION_CALL = "replaceSuperFunction";
+
+ private IClassDefinition currentClass;
+
+ public static class PropertyNodes
+ {
+ public IGetterNode getter;
+ public ISetterNode setter;
+ }
+
+ private static class Context
+ {
+ public LinkedHashMap<String, PropertyNodes> propertyMap;
+ public List<String> interfacePropertyMap;
+ public LinkedHashMap<String, PropertyNodes> staticPropertyMap;
+ public ArrayList<String> bindableVars;
+ public ArrayList<IVariableNode> vars;
+ public ArrayList<IFunctionNode> methods;
+ public IClassDefinition classDefinition;
+ }
+ private Stack<Context> stack = new Stack<Context>();
+
+ private LinkedHashMap<String, PropertyNodes> propertyMap = new LinkedHashMap<String, PropertyNodes>();
+
+ private List<String> interfacePropertyMap = new ArrayList<String>();
+
+ private LinkedHashMap<String, PropertyNodes> staticPropertyMap = new LinkedHashMap<String, PropertyNodes>();
+
+ private ArrayList<String> bindableVars = new ArrayList<String>();
+
+ private ArrayList<IVariableNode> vars = new ArrayList<IVariableNode>();
+
+ private ArrayList<IFunctionNode> methods = new ArrayList<IFunctionNode>();
+
+ private HashMap<String, String> internalClasses;
+
+ private int foreachLoopCount = 0;
+
+ public IClassDefinition getCurrentClass()
+ {
+ return currentClass;
+ }
+
+ public void setCurrentClass(IClassDefinition currentClass)
+ {
+ this.currentClass = currentClass;
+ }
+
+ public void pushClass(IClassDefinition currentClass)
+ {
+ Context context = new Context();
+ context.bindableVars = bindableVars;
+ context.interfacePropertyMap = interfacePropertyMap;
+ context.propertyMap = propertyMap;
+ context.staticPropertyMap = staticPropertyMap;
+ context.classDefinition = this.currentClass;
+ context.vars = vars;
+ context.methods = methods;
+ stack.push(context);
+ this.currentClass = currentClass;
+ bindableVars = new ArrayList<String>();
+ staticPropertyMap = new LinkedHashMap<String, PropertyNodes>();
+ interfacePropertyMap = new ArrayList<String>();
+ propertyMap = new LinkedHashMap<String, PropertyNodes>();
+ vars = new ArrayList<IVariableNode>();
+ methods = new ArrayList<IFunctionNode>();
+ }
+
+ public void popClass()
+ {
+ Context context = stack.pop();
+ this.currentClass = context.classDefinition;
+ bindableVars = context.bindableVars;
+ staticPropertyMap = context.staticPropertyMap;
+ propertyMap = context.propertyMap;
+ interfacePropertyMap = context.interfacePropertyMap;
+ vars = context.vars;
+ methods = context.methods;
+ }
+
+ public HashMap<String, PropertyNodes> getPropertyMap()
+ {
+ return propertyMap;
+ }
+
+ public List<String> getInterfacePropertyMap()
+ {
+ return interfacePropertyMap;
+ }
+
+ public HashMap<String, PropertyNodes> getStaticPropertyMap()
+ {
+ return staticPropertyMap;
+ }
+
+ public boolean hasBindableVars()
+ {
+ return bindableVars.size() > 0;
+ }
+
+ public List<String> getBindableVars()
+ {
+ return bindableVars;
+ }
+
+ public List<IVariableNode> getVars()
+ {
+ return vars;
+ }
+
+ public List<IFunctionNode> getMethods()
+ {
+ return methods;
+ }
+
+ public HashMap<String, String> getInternalClasses()
+ {
+ if (internalClasses == null)
+ internalClasses = new HashMap<String, String>();
+ return internalClasses;
+ }
+
+ public boolean isInternalClass(String className)
+ {
+ if (internalClasses == null) return false;
+
+ return internalClasses.containsKey(className);
+ }
+
+ public final void incForeachLoopCount()
+ {
+ foreachLoopCount++;
+ }
+
+ public String getCurrentForeachName()
+ {
+ return "foreachiter" + Integer.toString(foreachLoopCount);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSharedData.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSharedData.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSharedData.java
new file mode 100644
index 0000000..e430a03
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSharedData.java
@@ -0,0 +1,116 @@
+/*
+ *
+ * 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;
+
+import java.io.PrintStream;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.apache.flex.compiler.driver.IBackend;
+import org.apache.flex.compiler.internal.workspaces.Workspace;
+
+// TODO (mschmalle) This class sucks, figure out some other way instead of using
+// a static singleton class like this, change when implementing Configuration
+public class JSSharedData
+{
+
+ public static final String COMPILER_NAME = "MXMLJSC";
+ public static final boolean OUTPUT_TIMESTAMPS = true;
+ public static final String COMPILER_VERSION = "329449.1";
+
+ public final static JSSharedData instance = new JSSharedData();
+
+ public static IBackend backend;
+ public static String OUTPUT_EXTENSION;
+ public static Workspace workspace;
+
+ public static PrintStream STDOUT = System.out;
+ public static PrintStream STDERR = System.err;
+
+ @SuppressWarnings("unused")
+ private Boolean m_verbose = false;
+ private final ReadWriteLock m_verboseLock = new ReentrantReadWriteLock();
+
+ private Object m_codeGenMonitor = new Object();
+ private long m_codeGenCounter = 0;
+ private final ReadWriteLock m_codeGenCounterLock = new ReentrantReadWriteLock();
+
+ public static String now()
+ {
+ final String DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss";
+ Calendar cal = Calendar.getInstance();
+ SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
+ return sdf.format(cal.getTime());
+ }
+
+ public void stdout(String s)
+ {
+ if (STDOUT != null)
+ {
+ m_verboseLock.writeLock().lock();
+ STDOUT.println(s);
+ m_verboseLock.writeLock().unlock();
+ }
+ }
+
+ public void stderr(String s)
+ {
+ if (STDERR != null)
+ {
+ m_verboseLock.writeLock().lock();
+ STDERR.println(s);
+ m_verboseLock.writeLock().unlock();
+ }
+ }
+
+ public void beginCodeGen()
+ {
+ m_codeGenCounterLock.writeLock().lock();
+ m_codeGenCounter++;
+ m_codeGenCounterLock.writeLock().unlock();
+ }
+
+ public void endCodeGen()
+ {
+ m_codeGenCounterLock.writeLock().lock();
+ final long currentCounter = --m_codeGenCounter;
+ m_codeGenCounterLock.writeLock().unlock();
+
+ if (currentCounter == 0)
+ {
+ synchronized (m_codeGenMonitor)
+ {
+ m_codeGenMonitor.notifyAll();
+ }
+ }
+ }
+
+ public static String getTimeStampString()
+ {
+ if (JSSharedData.OUTPUT_TIMESTAMPS)
+ return "CROSS-COMPILED BY " + JSSharedData.COMPILER_NAME + " ("
+ + JSSharedData.COMPILER_VERSION + ") ON "
+ + JSSharedData.now() + "\n";
+ else
+ return "CROSS-COMPILED BY " + JSSharedData.COMPILER_NAME + "\n";
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSourceMapEmitter.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSourceMapEmitter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSourceMapEmitter.java
new file mode 100644
index 0000000..bcdeed5
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSourceMapEmitter.java
@@ -0,0 +1,67 @@
+/*
+ *
+ * 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;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.flex.compiler.codegen.ISourceMapEmitter;
+import org.apache.flex.compiler.codegen.js.IJSEmitter;
+
+import com.google.debugging.sourcemap.SourceMapGeneratorV3;
+
+public class JSSourceMapEmitter implements ISourceMapEmitter
+{
+ private IJSEmitter emitter;
+ private SourceMapGeneratorV3 sourceMapGenerator;
+
+ public JSSourceMapEmitter(IJSEmitter emitter)
+ {
+ this.emitter = emitter;
+ sourceMapGenerator = new SourceMapGeneratorV3();
+ }
+
+ public String emitSourceMap(String fileName, String sourceMapPath, String sourceRoot)
+ {
+ List<IJSEmitter.SourceMapMapping> mappings = this.emitter.getSourceMapMappings();
+ for (IJSEmitter.SourceMapMapping mapping : mappings)
+ {
+ sourceMapGenerator.addMapping(mapping.sourcePath, mapping.name,
+ mapping.sourceStartPosition,
+ mapping.destStartPosition, mapping.destEndPosition);
+ }
+ if (sourceRoot != null)
+ {
+ sourceMapGenerator.setSourceRoot(sourceRoot);
+ }
+
+ StringBuilder builder = new StringBuilder();
+ try
+ {
+ sourceMapGenerator.appendTo(builder, fileName);
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+
+ return builder.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSubEmitter.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSubEmitter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSubEmitter.java
new file mode 100644
index 0000000..be0b9d1
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSubEmitter.java
@@ -0,0 +1,126 @@
+/*
+ *
+ * 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;
+
+import org.apache.flex.compiler.codegen.IEmitterTokens;
+import org.apache.flex.compiler.codegen.js.IJSEmitter;
+import org.apache.flex.compiler.common.ISourceLocation;
+import org.apache.flex.compiler.projects.ICompilerProject;
+import org.apache.flex.compiler.visitor.IBlockWalker;
+
+public class JSSubEmitter
+{
+ private IJSEmitter emitter;
+
+ protected IJSEmitter getEmitter()
+ {
+ return emitter;
+ }
+
+ protected IBlockWalker getWalker()
+ {
+ return emitter.getWalker();
+ }
+
+ protected ICompilerProject getProject()
+ {
+ return emitter.getWalker().getProject();
+ }
+
+ protected JSSessionModel getModel()
+ {
+ return emitter.getModel();
+ }
+
+ public JSSubEmitter(IJSEmitter emitter)
+ {
+ this.emitter = emitter;
+ }
+
+ protected void write(IEmitterTokens value)
+ {
+ emitter.write(value);
+ }
+
+ protected void write(String value)
+ {
+ emitter.write(value);
+ }
+
+ protected void writeToken(IEmitterTokens value)
+ {
+ emitter.writeToken(value);
+ }
+
+ protected void writeToken(String value)
+ {
+ emitter.writeToken(value);
+ }
+
+ protected void writeNewline()
+ {
+ emitter.writeNewline();
+ }
+
+ protected void writeNewline(IEmitterTokens value)
+ {
+ emitter.writeNewline(value);
+ }
+
+ protected void writeNewline(String value)
+ {
+ emitter.writeNewline(value);
+ }
+
+ protected void writeNewline(String value, boolean pushIndent)
+ {
+ emitter.writeNewline(value, pushIndent);
+ }
+
+ protected void indentPush()
+ {
+ emitter.indentPush();
+ }
+
+ protected void indentPop()
+ {
+ emitter.indentPop();
+ }
+
+ protected void startMapping(ISourceLocation node)
+ {
+ emitter.startMapping(node);
+ }
+
+ protected void startMapping(ISourceLocation node, int line, int column)
+ {
+ emitter.startMapping(node, line, column);
+ }
+
+ protected void startMapping(ISourceLocation node, ISourceLocation nodeBeforeMapping)
+ {
+ emitter.startMapping(node, nodeBeforeMapping);
+ }
+
+ protected void endMapping(ISourceLocation node)
+ {
+ emitter.endMapping(node);
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSWriter.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSWriter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSWriter.java
new file mode 100644
index 0000000..e984eda
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSWriter.java
@@ -0,0 +1,166 @@
+/*
+ *
+ * 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;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.Stack;
+
+import org.apache.flex.compiler.codegen.ISourceMapEmitter;
+import org.apache.flex.compiler.codegen.js.IJSEmitter;
+import org.apache.flex.compiler.codegen.js.IJSWriter;
+import org.apache.flex.compiler.driver.js.IJSBackend;
+import org.apache.flex.compiler.problems.ICompilerProblem;
+import org.apache.flex.compiler.projects.IASProject;
+import org.apache.flex.compiler.units.ICompilationUnit;
+import org.apache.flex.compiler.visitor.as.IASBlockWalker;
+
+public class JSWriter implements IJSWriter
+{
+ protected IASProject project;
+
+ protected List<ICompilerProblem> problems;
+
+ protected ICompilationUnit compilationUnit;
+
+ @SuppressWarnings("unused")
+ private boolean enableDebug;
+
+ /**
+ * Create a JSApplication writer.
+ *
+ * @param application the JSApplication model to be encoded
+ * @param useCompression use ZLIB compression if true
+ */
+ public JSWriter(IASProject project, List<ICompilerProblem> problems,
+ ICompilationUnit compilationUnit, boolean enableDebug)
+ {
+ this.project = project;
+ this.problems = problems;
+ this.compilationUnit = compilationUnit;
+ this.enableDebug = enableDebug;
+ }
+
+ @Override
+ public void close() throws IOException
+ {
+ //outputBuffer.close();
+ }
+
+ @Override
+ public void writeTo(OutputStream out)
+ {
+ writeTo(out, null);
+ }
+
+ @Override
+ public int writeTo(File out) throws FileNotFoundException, IOException
+ {
+ return 0;
+ }
+
+ public void writeTo(OutputStream jsOut, File sourceMapOut)
+ {
+ IJSBackend backend = (IJSBackend) JSSharedData.backend;
+ JSFilterWriter writer = (JSFilterWriter) backend.createWriterBuffer(project);
+ IJSEmitter emitter = (IJSEmitter) backend.createEmitter(writer);
+ IASBlockWalker walker = backend.createWalker(project,
+ problems, emitter);
+
+ walker.visitCompilationUnit(compilationUnit);
+
+ try
+ {
+ jsOut.write(emitter.postProcess(writer.toString()).getBytes());
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+
+ if (sourceMapOut != null)
+ {
+ convertMappingSourcePathsToRelative(emitter, sourceMapOut);
+
+ File compilationUnitFile = new File(compilationUnit.getAbsoluteFilename());
+ ISourceMapEmitter sourceMapEmitter = backend.createSourceMapEmitter(emitter);
+ try
+ {
+ String fileName = compilationUnitFile.getName();
+ fileName = fileName.replace(".as", ".js");
+ String sourceMap = sourceMapEmitter.emitSourceMap(fileName, sourceMapOut.getAbsolutePath(), null);
+ BufferedOutputStream outStream = new BufferedOutputStream(new FileOutputStream(sourceMapOut));
+ outStream.write(sourceMap.getBytes());
+ outStream.flush();
+ outStream.close();
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ protected void convertMappingSourcePathsToRelative(IJSEmitter emitter, File relativeToFile)
+ {
+ List<IJSEmitter.SourceMapMapping> mappings = emitter.getSourceMapMappings();
+ for (IJSEmitter.SourceMapMapping mapping : mappings)
+ {
+ mapping.sourcePath = relativePath(mapping.sourcePath, relativeToFile.getAbsolutePath());
+ }
+ }
+
+ //if we ever support Java 7, the java.nio.file.Path relativize() method
+ //should be able to replace this method
+ private String relativePath(String filePath, String relativeToFilePath)
+ {
+ File currentFile = new File(filePath);
+ Stack<String> stack = new Stack<String>();
+ stack.push(currentFile.getName());
+ currentFile = currentFile.getParentFile();
+ while (currentFile != null)
+ {
+ String absoluteCurrentFile = currentFile.getAbsolutePath() + File.separator;
+ if (relativeToFilePath.startsWith(absoluteCurrentFile))
+ {
+ String relativeRelativeToFile = relativeToFilePath.substring(absoluteCurrentFile.length());
+ int separatorCount = relativeRelativeToFile.length() - relativeRelativeToFile.replace(File.separator, "").length();
+ String result = "";
+ while (separatorCount > 0)
+ {
+ result += ".." + File.separator;
+ separatorCount--;
+ }
+ while (stack.size() > 0)
+ {
+ result += stack.pop();
+ }
+ return result;
+ }
+ stack.push(currentFile.getName() + File.separator);
+ currentFile = currentFile.getParentFile();
+ }
+ return null;
+ }
+}