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/22 15:13:19 UTC
[6/6] git commit: [flex-falcon]
[refs/heads/feature/maven-migration-test] - - Merged upstream changes
- Merged upstream changes
Project: http://git-wip-us.apache.org/repos/asf/flex-falcon/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-falcon/commit/58409300
Tree: http://git-wip-us.apache.org/repos/asf/flex-falcon/tree/58409300
Diff: http://git-wip-us.apache.org/repos/asf/flex-falcon/diff/58409300
Branch: refs/heads/feature/maven-migration-test
Commit: 5840930016ccc94355666ae59657ae860c400742
Parents: 28f5f13 b4e4fad
Author: Christofer Dutz <ch...@codecentric.de>
Authored: Fri Apr 22 15:13:05 2016 +0200
Committer: Christofer Dutz <ch...@codecentric.de>
Committed: Fri Apr 22 15:13:05 2016 +0200
----------------------------------------------------------------------
.../compiler/clients/ExternCConfiguration.java | 54 +++++++++
.../externals/reference/ClassReference.java | 30 ++++-
.../codegen/js/jx/PackageHeaderEmitter.java | 119 +++++++++++++------
.../codegen/js/node/NodeEmitterTokens.java | 21 ++++
.../internal/projects/FlexJSProject.java | 61 ++++++++++
externs/node/node-compile-config.xml | 64 +++++++++-
6 files changed, 312 insertions(+), 37 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/58409300/compiler-jx/src/main/java/org/apache/flex/compiler/clients/ExternCConfiguration.java
----------------------------------------------------------------------
diff --cc compiler-jx/src/main/java/org/apache/flex/compiler/clients/ExternCConfiguration.java
index c15786a,0000000..c6e7212
mode 100644,000000..100644
--- a/compiler-jx/src/main/java/org/apache/flex/compiler/clients/ExternCConfiguration.java
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/clients/ExternCConfiguration.java
@@@ -1,364 -1,0 +1,418 @@@
+/*
+ *
+ * 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.clients;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.flex.compiler.config.Configuration;
+import org.apache.flex.compiler.config.ConfigurationValue;
+import org.apache.flex.compiler.exceptions.ConfigurationException.CannotOpen;
+import org.apache.flex.compiler.exceptions.ConfigurationException.IncorrectArgumentCount;
+import org.apache.flex.compiler.internal.codegen.externals.pass.ReferenceCompiler.ExternalFile;
+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.FieldReference;
+import org.apache.flex.compiler.internal.codegen.externals.reference.MemberReference;
+import org.apache.flex.compiler.internal.config.annotations.Arguments;
+import org.apache.flex.compiler.internal.config.annotations.Config;
+import org.apache.flex.compiler.internal.config.annotations.InfiniteArguments;
+import org.apache.flex.compiler.internal.config.annotations.Mapping;
+import org.apache.flex.utils.FilenameNormalization;
+
+public class ExternCConfiguration extends Configuration
+{
+ private File jsRoot;
+
+ private File asRoot;
+
+ private File asClassRoot;
+ private File asInterfaceRoot;
+ private File asFunctionRoot;
+ private File asConstantRoot;
+ private File asTypeDefRoot;
+ private File asDuplicatesRoot;
+
+ private List<ExternalFile> externals = new ArrayList<ExternalFile>();
+ private List<ExternalFile> externalExterns = new ArrayList<ExternalFile>();
+
++ private List<String> namedModules = new ArrayList<String>();
++
+ private List<String> classToFunctions = new ArrayList<String>();
+ private List<ExcludedMember> excludesClass = new ArrayList<ExcludedMember>();
+ private List<ExcludedMember> excludesField = new ArrayList<ExcludedMember>();
+ private List<ExcludedMember> excludes = new ArrayList<ExcludedMember>();
+
+ public ExternCConfiguration()
+ {
+ }
+
+ public File getAsRoot()
+ {
+ return asRoot;
+ }
+
+ @Config
+ @Mapping("as-root")
+ public void setASRoot(ConfigurationValue cfgval, String filename) throws CannotOpen
+ {
+ setASRoot(new File(FilenameNormalization.normalize(getOutputPath(cfgval, filename))));
+ }
+
+ public void setASRoot(File file)
+ {
+ this.asRoot = file;
+
+ asClassRoot = new File(asRoot, "classes");
+ asInterfaceRoot = new File(asRoot, "interfaces");
+ asFunctionRoot = new File(asRoot, "functions");
+ asConstantRoot = new File(asRoot, "constants");
+ asTypeDefRoot = new File(asRoot, "typedefs");
+ asDuplicatesRoot = new File(asRoot, "duplicates");
+ }
+
+ public File getAsClassRoot()
+ {
+ return asClassRoot;
+ }
+
+ public File getAsInterfaceRoot()
+ {
+ return asInterfaceRoot;
+ }
+
+ public File getAsFunctionRoot()
+ {
+ return asFunctionRoot;
+ }
+
+ public File getAsConstantRoot()
+ {
+ return asConstantRoot;
+ }
+
+ public File getAsTypeDefRoot()
+ {
+ return asTypeDefRoot;
+ }
+
+ public File getAsDuplicatesRoot()
+ {
+ return asDuplicatesRoot;
+ }
+
+ public Collection<ExternalFile> getExternals()
+ {
+ return externals;
+ }
+
+ public Collection<ExternalFile> getExternalExterns()
+ {
+ return externalExterns;
+ }
+
+ public boolean isClassToFunctions(String className)
+ {
+ return classToFunctions.contains(className);
+ }
+
+ public void addClassToFunction(String className)
+ {
+ classToFunctions.add(className);
+ }
+
+ public void addExternal(File file) throws IOException
+ {
+ if (!file.exists())
+ throw new IOException(file.getAbsolutePath() + " does not exist.");
+ externals.add(new ExternalFile(file));
+ }
+
+ public void addExternal(String externalFile) throws IOException
+ {
+ addExternal(new File(FilenameNormalization.normalize(externalFile)));
+ }
+
+ public void addExternalExtern(File file) throws IOException
+ {
+ if (!file.exists())
+ throw new IOException(file.getAbsolutePath() + " does not exist.");
+ externalExterns.add(new ExternalFile(file));
+ }
+
+ public void addExternalExtern(String externalFile) throws IOException
+ {
+ addExternalExtern(new File(FilenameNormalization.normalize(externalFile)));
+ }
+
+ @Config(allowMultiple = true)
+ @Mapping("class-to-function")
+ @Arguments(Arguments.CLASS)
+ public void setClassToFunctions(ConfigurationValue cfgval, List<String> values) throws IncorrectArgumentCount
+ {
+ addClassToFunction(values.get(0));
+ }
+
+ @Config(allowMultiple = true, isPath = true)
+ @Mapping("external")
+ @Arguments(Arguments.PATH_ELEMENT)
+ @InfiniteArguments
+ public void setExternal(ConfigurationValue cfgval, String[] vals) throws IOException, CannotOpen
+ {
+ for (String val : vals)
+ addExternal(resolvePathStrict(val, cfgval));
+ }
+
+ @Config(allowMultiple = true, isPath = true)
+ @Mapping("external-externs")
+ @Arguments(Arguments.PATH_ELEMENT)
+ @InfiniteArguments
+ public void setExternalExterns(ConfigurationValue cfgval, String[] vals) throws IOException, CannotOpen
+ {
+ for (String val : vals)
+ addExternalExtern(resolvePathStrict(val, cfgval));
+ }
+
+ public boolean isExternalExtern(BaseReference reference)
+ {
+ String sourceFileName = reference.getNode().getSourceFileName();
+ for (ExternalFile file : externalExterns)
+ {
+ if (sourceFileName.equals("[" + file.getName() + "]"))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public ExcludedMember isExcludedClass(ClassReference classReference)
+ {
+ for (ExcludedMember memeber : excludesClass)
+ {
+ if (memeber.isExcluded(classReference, null))
+ return memeber;
+ }
+ return null;
+ }
+
+ public ExcludedMember isExcludedMember(ClassReference classReference,
+ MemberReference memberReference)
+ {
+ if (memberReference instanceof FieldReference)
+ {
+ for (ExcludedMember memeber : excludesField)
+ {
+ if (memeber.isExcluded(classReference, memberReference))
+ return memeber;
+ }
+ }
+ for (ExcludedMember memeber : excludes)
+ {
+ if (memeber.isExcluded(classReference, memberReference))
+ return memeber;
+ }
+ return null;
+ }
+
+ @Config(allowMultiple = true)
+ @Mapping("exclude")
+ @Arguments({"class", "name"})
+ public void setExcludes(ConfigurationValue cfgval, List<String> values) throws IncorrectArgumentCount
+ {
+ final int size = values.size();
+ if (size % 2 != 0)
+ throw new IncorrectArgumentCount(size + 1, size, cfgval.getVar(), cfgval.getSource(), cfgval.getLine());
+
+ for (int nameIndex = 0; nameIndex < size - 1; nameIndex += 2)
+ {
+ final String className = values.get(nameIndex);
+ final String name = values.get(nameIndex + 1);
+ addExclude(className, name);
+ }
+ }
+
+ public void addExclude(String className, String name)
+ {
+ excludes.add(new ExcludedMember(className, name));
+ }
+
+ public void addExclude(String className, String name, String description)
+ {
+ excludes.add(new ExcludedMember(className, name, description));
+ }
+
+ @Config(allowMultiple = true)
+ @Mapping("field-exclude")
+ @Arguments({"class", "field"})
+ public void setFieldExcludes(ConfigurationValue cfgval, List<String> values) throws IncorrectArgumentCount
+ {
+ final int size = values.size();
+ if (size % 2 != 0)
+ throw new IncorrectArgumentCount(size + 1, size, cfgval.getVar(), cfgval.getSource(), cfgval.getLine());
+
+ for (int nameIndex = 0; nameIndex < size - 1; nameIndex += 2)
+ {
+ final String className = values.get(nameIndex);
+ final String fieldName = values.get(nameIndex + 1);
+ addFieldExclude(className, fieldName);
+ }
+ }
+
+ public void addFieldExclude(String className, String fieldName)
+ {
+ excludesField.add(new ExcludedMember(className, fieldName, ""));
+ }
+
+ @Config(allowMultiple = true)
+ @Mapping("class-exclude")
+ @Arguments("class")
+ public void setClassExcludes(ConfigurationValue cfgval, List<String> values)
+ {
+ for (String className : values)
+ addClassExclude(className);
+ }
+ public void addClassExclude(String className)
+ {
+ excludesClass.add(new ExcludedMember(className, null, ""));
+ }
+
++ @Config(allowMultiple = true)
++ @Mapping("named-module")
++ @Arguments("module")
++ @InfiniteArguments
++ public void setNamedModules(ConfigurationValue cfgval, List<String> values)
++ {
++ for (String moduleName : values)
++ {
++ addNamedModule(moduleName);
++ }
++ }
++ public void addNamedModule(String moduleName)
++ {
++ namedModules.add(moduleName);
++ }
++
++ public String isNamedModule(ClassReference classReference)
++ {
++ String basePackageName = classReference.getPackageName();
++ int packageIndex = basePackageName.indexOf(".");
++ if (packageIndex != -1)
++ {
++ basePackageName = basePackageName.substring(0, packageIndex);
++ }
++ for (String module : namedModules)
++ {
++ //convert to camel case
++ String camelCaseModule = module;
++ int moduleIndex = camelCaseModule.indexOf("-");
++ while (moduleIndex != -1 && moduleIndex < camelCaseModule.length() - 1)
++ {
++ camelCaseModule = camelCaseModule.substring(0, moduleIndex)
++ + camelCaseModule.substring(moduleIndex + 1, moduleIndex + 2).toUpperCase()
++ + camelCaseModule.substring(moduleIndex + 2);
++ moduleIndex = camelCaseModule.indexOf("-");
++ }
++ if(basePackageName.length() == 0)
++ {
++ if (classReference.getBaseName().equals(camelCaseModule))
++ {
++ return module;
++ }
++ continue;
++ }
++ if(basePackageName.equals(camelCaseModule))
++ {
++ return module;
++ }
++ }
++ return null;
++ }
++
+ public File getJsRoot()
+ {
+ return jsRoot;
+ }
+
+ @Config
+ @Mapping("js-root")
+ public void setJSRoot(ConfigurationValue cfgval, String filename) throws CannotOpen
+ {
+ this.jsRoot = new File(filename);
+ }
+
+
+ public static class ExcludedMember
+ {
+ private String className;
+ private String name;
+ private String description;
+
+ public String getClassName()
+ {
+ return className;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public String getDescription()
+ {
+ return description;
+ }
+
+ public ExcludedMember(String className, String name)
+ {
+ this.className = className;
+ this.name = name;
+ }
+
+ public ExcludedMember(String className, String name, String description)
+ {
+ this.className = className;
+ this.name = name;
+ this.description = description;
+ }
+
+ public boolean isExcluded(ClassReference classReference,
+ MemberReference memberReference)
+ {
+ if (memberReference == null)
+ {
+ return classReference.getQualifiedName().equals(className);
+ }
+ return classReference.getQualifiedName().equals(className)
+ && memberReference.getQualifiedName().equals(name);
+ }
+
+ public void print(StringBuilder sb)
+ {
+ if (description != null)
+ sb.append("// " + description + "\n");
+ sb.append("//");
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/58409300/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/reference/ClassReference.java
----------------------------------------------------------------------
diff --cc compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/reference/ClassReference.java
index b04fb0e,0000000..fc1df39
mode 100644,000000..100644
--- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/reference/ClassReference.java
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/reference/ClassReference.java
@@@ -1,890 -1,0 +1,918 @@@
+/*
+ *
+ * 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.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.flex.compiler.internal.codegen.externals.utils.DebugLogUtils;
+import org.apache.flex.compiler.internal.codegen.externals.utils.JSTypeUtils;
+
+import com.google.javascript.rhino.JSDocInfo;
+import com.google.javascript.rhino.JSDocInfoBuilder;
+import com.google.javascript.rhino.JSTypeExpression;
+import com.google.javascript.rhino.Node;
+import com.google.javascript.rhino.jstype.JSType;
+
+public class ClassReference extends BaseReference
+{
+ private boolean isFinal;
+ private boolean isDynamic;
++ private String moduleName;
+ private int enumConstantCounter = 0;
+
+ private Set<String> imports = new HashSet<String>();
+ private MethodReference constructor;
+ private Map<String, FieldReference> instanceFields = new HashMap<String, FieldReference>();
+ private Map<String, FieldReference> staticFields = new HashMap<String, FieldReference>();
+ private Map<String, MethodReference> instanceMethods = new HashMap<String, MethodReference>();
+ private Map<String, MethodReference> staticMethods = new HashMap<String, MethodReference>();
+
+ private Node nameNode;
+
+ private Node functionNode;
+
+ @SuppressWarnings("unused")
+ private Node paramListNode;
+
+ private boolean isNamespace;
+
+ public final int getEnumConstant()
+ {
+ return enumConstantCounter;
+ }
+
+ public final void nextEnumConstant()
+ {
+ enumConstantCounter++;
+ }
+
+ public void setIsNamespace(boolean isNamespace)
+ {
+ this.isNamespace = isNamespace;
+ }
+
+ public boolean isNamespace()
+ {
+ return isNamespace;
+ }
+
+ public MethodReference getConstructor()
+ {
+ return constructor;
+ }
+
+ public ArrayList<FieldReference> getAllFields()
+ {
+ ArrayList<FieldReference> allMethods = new ArrayList<FieldReference>();
+ if (!isInterface())
+ allMethods.addAll(staticFields.values());
+ allMethods.addAll(instanceFields.values());
+ return allMethods;
+ }
+
+ public ArrayList<MethodReference> getAllMethods()
+ {
+ ArrayList<MethodReference> allMethods = new ArrayList<MethodReference>();
+ if (!isInterface())
+ allMethods.addAll(staticMethods.values());
+ allMethods.addAll(instanceMethods.values());
+ return allMethods;
+ }
+
+ public FieldReference getStaticField(String name)
+ {
+ return staticFields.get(name);
+ }
+
+ public FieldReference getInstanceField(String name)
+ {
+ return instanceFields.get(name);
+ }
+
+ public MethodReference getStaticMethod(String name)
+ {
+ return staticMethods.get(name);
+ }
+
+ public MethodReference getInstanceMethod(String name)
+ {
+ return instanceMethods.get(name);
+ }
+
+ public boolean isDynamic()
+ {
+ return isDynamic;
+ }
+
+ public void setDynamic(boolean isDynamic)
+ {
+ this.isDynamic = isDynamic;
+ }
+
+ public boolean isFinal()
+ {
+ return isFinal;
+ }
+
+ public void setFinal(boolean isFinal)
+ {
+ this.isFinal = isFinal;
+ }
+
++ public String getModuleName()
++ {
++ return moduleName;
++ }
++
++ public void setModuleName(String moduleName)
++ {
++ this.moduleName = moduleName;
++ }
++
+ public final boolean isInterface()
+ {
+ return getComment().isInterface();
+ }
+
+ /**
+ *
+ * @param model
+ * @param node (FUNCTION [NAME, PARAM_LIST, BLOCK]), or (ASSIGN [FUNCTION [NAME, PARAM_LIST, BLOCK]])
+ * @param qualifiedName
+ */
+ public ClassReference(ReferenceModel model, Node node, String qualifiedName)
+ {
+ super(model, node, qualifiedName, node.getJSDocInfo());
+
+ indent = "";
+
+ nameNode = null;
+ functionNode = null;
+ paramListNode = null;
+
+ if (comment.hasEnumParameterType())
+ {
+ /*
+ var Foo = { ...
+
+ VAR 35 [jsdoc_info: JSDocInfo]
+ NAME FontFaceSetLoadStatus
+ OBJECTLIT
+ STRING_KEY LOADED
+ STRING loaded
+ STRING_KEY LOADING
+ STRING loading
+
+ Or..
+
+ foo.bar.baz.QualifiedEnum = { ...
+
+ ASSIGN 50 [jsdoc_info: JSDocInfo]
+ GETPROP
+ GETPROP
+ ...
+ STRING QualifiedEnum
+ OBJECTLIT 50
+ */
+
+ String overrideStringType = JSTypeUtils.toEnumTypeString(this);
+
+ Node objLit = null;
+ if (node.isVar())
+ {
+ objLit = node.getFirstChild().getFirstChild();
+ }
+ else if (node.isAssign())
+ {
+ objLit = node.getLastChild();
+ }
+
+ if (objLit != null)
+ {
+ for (Node stringKey : objLit.children())
+ {
+ if (stringKey.isStringKey())
+ {
+ Node valueNode = stringKey.getFirstChild();
+
+ JSDocInfoBuilder b = new JSDocInfoBuilder(true);
+ JSDocInfo fieldComment = b.build();
+ String fieldName = stringKey.getString();
+ FieldReference field = addField(stringKey, fieldName, fieldComment, true);
+ field.setConst(true);
+ field.setOverrideStringType(overrideStringType);
+ field.setConstantValueNode(valueNode);
+ }
+ }
+ }
+ }
+ else if (comment.getTypedefType() != null)
+ {
+ //System.out.println(node.toStringTree());
+ /*
+ VAR 727 [jsdoc_info: JSDocInfo] [source_file: [w3c_rtc]] [length: 21]
+ NAME MediaConstraints 727 [source_file: [w3c_rtc]] [length: 16]
+ */
+ }
+ else if (comment.isConstant())
+ {
+ /*
+ VAR 882 [jsdoc_info: JSDocInfo]
+ NAME Math
+ OBJECTLIT
+ */
+ constructor = new NullConstructorReference(model, this, node, getBaseName(), comment);
+ }
+ else if (node.isFunction())
+ {
+ /*
+ FUNCTION FooVarArgs 43 [jsdoc_info: JSDocInfo]
+ NAME FooVarArgs
+ PARAM_LIST
+ NAME arg1
+ NAME var_args
+ BLOCK 43
+ */
+ nameNode = node.getChildAtIndex(0);
+ functionNode = node;
+ paramListNode = functionNode.getChildAtIndex(1);
+ }
+ else if (node.isVar())
+ {
+ /*
+ VAR 67 [jsdoc_info: JSDocInfo]
+ NAME VarAssignFooNoArgs
+ FUNCTION
+ NAME
+ PARAM_LIST
+ BLOCK
+ */
+ nameNode = node.getChildAtIndex(0);
+ functionNode = nameNode.getChildAtIndex(0);
+ try
+ {
+ paramListNode = functionNode.getChildAtIndex(1);
+ }
+ catch (Exception e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ else if (node.isAssign() && node.getChildAtIndex(1).isFunction())
+ {
+ /*
+ ASSIGN 60 [jsdoc_info: JSDocInfo]
+ NAME AssignFooNoArgs
+ FUNCTION
+ NAME
+ PARAM_LIST
+ BLOCK
+ */
+ nameNode = node.getFirstChild();
+ functionNode = node.getLastChild();
+ // this is an anonymous function assignment, no name
+ //functionNameNode = functionNode.getChildAtIndex(0);
+ paramListNode = functionNode.getChildAtIndex(1);
+ }
+
+ if (functionNode != null)
+ {
+ constructor = new MethodReference(model, this, functionNode, getBaseName(), comment, false);
+ }
+
++ moduleName = model.getConfiguration().isNamedModule(this);
++
+ }
+
+ private static List<String> definedPackages = new ArrayList<String>();
+
+ @Override
+ public void emit(StringBuilder sb)
+ {
+ enumConstantCounter = 0;
+
+ String packageName = getPackageName();
+
+ if (outputJS)
+ {
+ sb.append("/** @fileoverview Auto-generated Externs files\n * @externs\n */\n");
+ if (!packageName.isEmpty())
+ {
+ if (!definedPackages.contains(packageName))
+ {
+ definedPackages.add(packageName);
+ String[] pieces = packageName.split("\\.");
+ String chain = "";
+ int n = pieces.length;
+ for (int i = 0; i < n; i++)
+ {
+ String piece = pieces[i];
+ sb.append("\n");
+ sb.append("\n");
+ sb.append("/**\n * @const\n * @suppress {duplicate|const} */\n");
+ if (chain.isEmpty())
+ sb.append("var " + piece + " = {};\n\n\n");
+ else
+ sb.append(chain + "." + piece + " = {}\n\n\n");
+ chain = chain + "." + piece;
+ }
+ }
+ }
+ }
+ else
+ {
+ sb.append("package ");
+ if (!packageName.equals(""))
+ sb.append(packageName).append(" ");
+ sb.append("{\n");
+ sb.append("\n");
+
+ emitImports(sb);
+ }
++
++ if (moduleName != null)
++ {
++ sb.append("[JSModule");
++ if (packageName.length() > 0 || !getBaseName().equals(moduleName))
++ {
++ sb.append("(");
++ sb.append("name=\"");
++ sb.append(moduleName);
++ sb.append("\"");
++ sb.append(")");
++ }
++ sb.append("]");
++ sb.append("\n");
++ }
+
+ emitComment(sb);
+
+ boolean isInterface = isInterface();
+
+ if (isInterface)
+ {
+ emitInterface(sb);
+ }
+ else
+ {
+ emitClass(sb);
+ }
+
+ if (!outputJS)
+ {
+ sb.append("{\n");
+ sb.append("\n");
+ }
+
+ if (!isInterface)
+ {
+ emitConstructor(sb);
+ sb.append("\n");
+ }
+
+ emitFields(sb);
+ emitMethods(sb);
+
+ if (!outputJS)
+ {
+ sb.append("}\n");
+ sb.append("}\n"); // package
+ }
+ }
+
+ public boolean hasSuperField(String fieldName)
+ {
+ List<ClassReference> list = getSuperClasses();
+ for (ClassReference reference : list)
+ {
+ if (reference.hasInstanceField(fieldName))
+ return true;
+ }
+ return false;
+ }
+
+ public boolean hasSuperMethod(String methodName)
+ {
+ List<ClassReference> list = getSuperClasses();
+ for (ClassReference reference : list)
+ {
+ if (reference.hasInstanceMethod(methodName))
+ return true;
+ }
+ return false;
+ }
+
+ public MethodReference getSuperMethod(String methodName)
+ {
+ List<ClassReference> list = getSuperClasses();
+ for (ClassReference reference : list)
+ {
+ if (reference.hasInstanceMethod(methodName))
+ return reference.getInstanceMethod(methodName);
+ }
+
+ list = getAllImplInterfaces(); // return all our interfaces and all superclass
+ for (ClassReference reference : list)
+ {
+ if (reference.hasInstanceMethod(methodName))
+ return reference.getInstanceMethod(methodName);
+ }
+
+ return null;
+ }
+
+ public List<ClassReference> getSuperClasses()
+ {
+ ArrayList<ClassReference> result = new ArrayList<ClassReference>();
+ ClassReference superClass = getSuperClass();
+ while (superClass != null)
+ {
+ result.add(superClass);
+ superClass = superClass.getSuperClass();
+ }
+
+ return result;
+ }
+
+ public List<ClassReference> getAllImplInterfaces()
+ {
+ ArrayList<ClassReference> result = new ArrayList<ClassReference>();
+ for (JSTypeExpression jsTypeExpression : getComment().getImplementedInterfaces())
+ {
+ String interfaceName = getModel().evaluate(jsTypeExpression).getDisplayName();
+ ClassReference classReference = getModel().getClassReference(interfaceName);
+ if (classReference != null)
+ result.add(classReference);
+ }
+
+ return result;
+ }
+
+ public List<ClassReference> getImplementedInterfaces()
+ {
+ ArrayList<ClassReference> result = new ArrayList<ClassReference>();
+ for (JSTypeExpression jsTypeExpression : getComment().getImplementedInterfaces())
+ {
+ String interfaceName = getModel().evaluate(jsTypeExpression).toAnnotationString();
+ ClassReference reference = getModel().getClassReference(interfaceName);
+ if (reference != null)
+ result.add(reference);
+ }
+ return result;
+ }
+
+ public List<ClassReference> getExtendedInterfaces()
+ {
+ ArrayList<ClassReference> result = new ArrayList<ClassReference>();
+ for (JSTypeExpression jsTypeExpression : getComment().getExtendedInterfaces())
+ {
+ String interfaceName = getModel().evaluate(jsTypeExpression).toAnnotationString();
+ ClassReference reference = getModel().getClassReference(interfaceName);
+ if (reference != null)
+ result.add(reference);
+ }
+ return result;
+ }
+
+ public List<ClassReference> getInterfaces()
+ {
+ ArrayList<ClassReference> result = new ArrayList<ClassReference>();
+ List<JSTypeExpression> implementedInterfaces = getComment().getImplementedInterfaces();
+ for (JSTypeExpression jsTypeExpression : implementedInterfaces)
+ {
+ JSType jsType = getModel().evaluate(jsTypeExpression);
+ String interfaceName = jsType.toAnnotationString();
+ result.add(getModel().getClassReference(interfaceName));
+ }
+ return result;
+ }
+
+ public List<ClassReference> getSuperInterfaces()
+ {
+ ArrayList<ClassReference> result = new ArrayList<ClassReference>();
+ result.addAll(getInterfaces());
+
+ ClassReference superClass = getSuperClass();
+ while (superClass != null)
+ {
+ result.addAll(superClass.getInterfaces());
+ superClass = superClass.getSuperClass();
+ }
+
+ return result;
+ }
+
+ public boolean hasInstanceField(String fieldName)
+ {
+ return instanceFields.containsKey(fieldName);
+ }
+
+ public boolean hasStaticField(String fieldName)
+ {
+ return staticFields.containsKey(fieldName);
+ }
+
+ public boolean hasInstanceMethod(String fieldName)
+ {
+ return instanceMethods.containsKey(fieldName);
+ }
+
+ public boolean hasStaticMethod(String fieldName)
+ {
+ return staticMethods.containsKey(fieldName);
+ }
+
+ public FieldReference addField(Node node, String fieldName, JSDocInfo comment, boolean isStatic)
+ {
+ if (isStatic ? hasStaticField(fieldName) : hasInstanceField(fieldName))
+ {
+ // XXX Warning
+ return null;
+ }
+
+ /* AJH This doesn't make sense to me
+ if (isNamespace)
+ isStatic = false;
+ */
+
+ if (comment == null)
+ {
+ DebugLogUtils.err("Field comment null for; " + node.getQualifiedName());
+ //DebugLogUtils.err(node);
+ JSDocInfoBuilder b = new JSDocInfoBuilder(true);
+ b.recordBlockDescription("Generated doc for missing field JSDoc.");
+ comment = b.build();
+ }
+
+ FieldReference field = new FieldReference(getModel(), this, node, fieldName, comment, isStatic);
+
+ if (isStatic)
+ staticFields.put(fieldName, field);
+ else
+ instanceFields.put(fieldName, field);
+ return field;
+ }
+
+ public MethodReference addMethod(Node node, String functionName, JSDocInfo comment, boolean isStatic)
+ {
+ /* AJH This doesn't make sense to me
+ if (isNamespace)
+ isStatic = false;
+ */
+
+ if (comment == null)
+ {
+ DebugLogUtils.err("Method comment null for; " + node.getQualifiedName());
+ //DebugLogUtils.err(node);
+ JSDocInfoBuilder b = new JSDocInfoBuilder(true);
+ b.recordBlockDescription("Generated doc for missing method JSDoc.");
+ comment = b.build();
+ }
+
+ MethodReference method = new MethodReference(getModel(), this, node, functionName, comment, isStatic);
+
+ if (isStatic)
+ {
+ staticMethods.put(functionName, method);
+ }
+ else if (getQualifiedName().equals("Object") && functionName.equals("toString"))
+ {
+ // skipping Object.prototype.toString() allows toString(opt_radix) for Number, int and uint
+ }
+ else
+ {
+ instanceMethods.put(functionName, method);
+ }
+ return method;
+ }
+
+ public boolean isMethodOverrideFromInterface(MethodReference reference)
+ {
+ boolean isMethodOverrideFromInterface = false;
+
+ if (!hasImplementations())
+ {
+ List<JSTypeExpression> implementedInterfaces = getComment().getImplementedInterfaces();
+ for (JSTypeExpression jsTypeExpression : implementedInterfaces)
+ {
+ String interfaceName = getModel().evaluate(jsTypeExpression).getDisplayName();
+ ClassReference classReference = getModel().getClassReference(interfaceName);
+ if (classReference.hasSuperMethod(reference.getQualifiedName()))
+ {
+ isMethodOverrideFromInterface = true;
+ break;
+ }
+ }
+ }
+
+ return isMethodOverrideFromInterface;
+ }
+
+ public MethodReference getMethodOverrideFromInterface(MethodReference reference)
+ {
+ // get all super classes, reverse and search top down
+ List<ClassReference> superClasses = getSuperClasses();
+ superClasses.add(0, this);
+ Collections.reverse(superClasses);
+
+ // for each superclass, get all implemented interfaces
+ for (ClassReference classReference : superClasses)
+ {
+ List<ClassReference> interfaces = classReference.getImplementedInterfaces();
+ for (ClassReference interfaceReference : interfaces)
+ {
+ // check for the method on the interface
+ MethodReference method = interfaceReference.getInstanceMethod(reference.getBaseName());
+ if (method != null)
+ return method;
+ }
+ }
+
+ return null;
+ }
+
+ public ClassReference getSuperClass()
+ {
+ if (getBaseName().equals("Object"))
+ return null;
+
+ JSTypeExpression baseType = getComment().getBaseType();
+ if (baseType != null)
+ {
+ JSType jsType = getModel().evaluate(baseType);
+ if (jsType != null)
+ return getModel().getClassReference(jsType.getDisplayName());
+ }
+ else
+ {
+ return getModel().getObjectReference();
+ }
+
+ return null;
+ }
+
+ public boolean hasSuperFieldConflict(FieldReference reference)
+ {
+ // ClassReference2 superClass = getSuperClass();
+ // if (superClass != null)
+ // return superClass.getInstanceFields().containsKey(
+ // reference.getName());
+ return false;
+ }
+
+ public boolean isPropertyInterfaceImplementation(String fieldName)
+ {
+ List<ClassReference> superInterfaces = getSuperInterfaces();
+ for (ClassReference interfaceRef : superInterfaces)
+ {
+ if (interfaceRef == null)
+ {
+ System.err.println("isPropertyInterfaceImplementation() null");
+ continue;
+ }
+ if (interfaceRef.hasInstanceField(fieldName))
+ return true;
+ }
+ return false;
+ }
+
+ public boolean hasLocalMethodConflict(String functionName)
+ {
+ return instanceMethods.containsKey(functionName) || staticMethods.containsKey(functionName);
+ }
+
+ public void addImport(ClassReference reference)
+ {
+ if (reference != null)
+ {
+ imports.add(reference.getQualifiedName());
+ }
+ }
+
+ public boolean hasImport(String qualifiedName)
+ {
+ return imports.contains(qualifiedName);
+ }
+
+ private boolean hasImplementations()
+ {
+ return getComment().getImplementedInterfaceCount() > 0;
+ }
+
+ private void emitImports(StringBuilder sb)
+ {
+ if (imports.size() > 0)
+ {
+ for (String anImport : imports)
+ {
+ sb.append("import ").append(anImport).append(";\n");
+ }
+ sb.append("\n");
+ }
+ }
+
+ @Override
+ protected void emitCommentBody(StringBuilder sb)
+ {
+ super.emitCommentBody(sb);
+ if (isInterface())
+ sb.append(" * @interface\n");
+ else
+ sb.append(" * @constructor ");
+ if (getComment().hasBaseType())
+ {
+ emitSuperClass(sb);
+ }
+ if (!isInterface())
+ {
+ emitImplements(sb);
+ }
+ }
+
+ private void emitClass(StringBuilder sb)
+ {
+ if (outputJS)
+ return;
-
++
+ sb.append("public ");
+ if (isDynamic)
+ {
+ sb.append("dynamic ");
+ }
+
+ if (isFinal)
+ {
+ sb.append("final ");
+ }
+
+ sb.append("class ");
+ sb.append(getBaseName()).append(" ");
+
+ if (getComment().hasBaseType())
+ {
+ emitSuperClass(sb);
+ sb.append(" ");
+ }
+ else
+ {
+ // XXX JSObject extends
+ //sb.append("extends JSObject ");
+ }
+
+ if (!isInterface())
+ {
+ emitImplements(sb);
+ }
+ }
+
+ private void emitInterface(StringBuilder sb)
+ {
+ sb.append("public interface ");
+
+ sb.append(getBaseName()).append(" ");
+
+ List<JSTypeExpression> extendedInterfaces = getComment().getExtendedInterfaces();
+ int len = extendedInterfaces.size();
+ if (len > 0)
+ {
+ sb.append("extends ");
+ for (JSTypeExpression jsTypeExpression : extendedInterfaces)
+ {
+ String value = getModel().evaluate(jsTypeExpression).toAnnotationString();
+ sb.append(value);
+ if (--len > 0)
+ sb.append(", ");
+ }
+ sb.append(" ");
+ }
+ }
+
+ private void emitSuperClass(StringBuilder sb)
+ {
+ if (outputJS)
+ {
+ sb.append(" * @extends ");
+ String value = JSTypeUtils.toClassTypeString(this);
+ sb.append(value);
+ sb.append("\n");
+ }
+ else
+ {
+ sb.append("extends ");
+ String value = JSTypeUtils.toClassTypeString(this);
+ sb.append(value);
+ }
+ }
+
+ private void emitImplements(StringBuilder sb)
+ {
+ List<JSTypeExpression> implementedInterfaces = getComment().getImplementedInterfaces();
+ if (implementedInterfaces.size() == 0)
+ return;
+
+ if (outputJS)
+ sb.append(" * @implements ");
+ else
+ sb.append("implements ");
+
+ int len = implementedInterfaces.size();
+ for (int i = 0; i < len; i++)
+ {
+ String value = getModel().evaluate(implementedInterfaces.get(i)).getDisplayName();
+
+ sb.append(value);
+ if (outputJS)
+ sb.append("\n");
+ else
+ {
+ if (i < len - 1)
+ sb.append(", ");
+ }
+ }
+
+ sb.append(" ");
+ }
+
+ private void emitConstructor(StringBuilder sb)
+ {
+ if (constructor != null)
+ {
+ constructor.emit(sb);
+ }
+ }
+
+ private void emitFields(StringBuilder sb)
+ {
+ for (FieldReference field : getAllFields())
+ {
+ field.emit(sb);
+ sb.append("\n");
+ nextEnumConstant();
+ }
+ }
+
+ private void emitMethods(StringBuilder sb)
+ {
+ for (MethodReference method : getAllMethods())
+ {
+ method.emit(sb);
+ sb.append("\n");
+ }
+ }
+
+ public File getFile(File asSourceRoot)
+ {
+ File jsRoot = getModel().getConfiguration().getJsRoot();
+ if (jsRoot == null)
+ {
+ String packagePath = toPackagePath();
+ return new File(asSourceRoot, packagePath + File.separator + getBaseName() + ".as");
+ }
+
+ return new File(jsRoot, getBaseName() + ".js");
+ }
+
+ private String toPackagePath()
+ {
+ String packageName = getPackageName();
+
+ String[] cname = packageName.split("\\.");
+ String sdirPath = "";
+ if (cname.length > 0)
+ {
+ for (final String aCname : cname)
+ {
+ sdirPath += aCname + File.separator;
+ }
+
+ return sdirPath;
+ }
+
+ return "";
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/58409300/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/PackageHeaderEmitter.java
----------------------------------------------------------------------
diff --cc compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/PackageHeaderEmitter.java
index d47c6dc,0000000..6ce6328
mode 100644,000000..100644
--- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/PackageHeaderEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/PackageHeaderEmitter.java
@@@ -1,290 -1,0 +1,339 @@@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.codegen.js.jx;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.flex.compiler.asdoc.flexjs.ASDocComment;
+import org.apache.flex.compiler.codegen.ISubEmitter;
+import org.apache.flex.compiler.codegen.js.IJSEmitter;
+import org.apache.flex.compiler.definitions.IDefinition;
+import org.apache.flex.compiler.definitions.IFunctionDefinition;
+import org.apache.flex.compiler.definitions.IPackageDefinition;
+import org.apache.flex.compiler.definitions.ITypeDefinition;
+import org.apache.flex.compiler.definitions.IVariableDefinition;
+import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
+import org.apache.flex.compiler.internal.codegen.js.JSSubEmitter;
+import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSEmitter;
+import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSEmitterTokens;
+import org.apache.flex.compiler.internal.codegen.js.goog.JSGoogEmitterTokens;
++import org.apache.flex.compiler.internal.codegen.js.node.NodeEmitterTokens;
+import org.apache.flex.compiler.internal.codegen.js.utils.EmitterUtils;
+import org.apache.flex.compiler.internal.projects.FlexJSProject;
+import org.apache.flex.compiler.internal.scopes.ASProjectScope;
+import org.apache.flex.compiler.internal.scopes.PackageScope;
+import org.apache.flex.compiler.internal.tree.as.ClassNode;
+import org.apache.flex.compiler.projects.ICompilerProject;
+import org.apache.flex.compiler.scopes.IASScope;
+import org.apache.flex.compiler.targets.ITarget.TargetType;
+import org.apache.flex.compiler.tree.as.ITypeNode;
+import org.apache.flex.compiler.units.ICompilationUnit;
+import org.apache.flex.compiler.utils.NativeUtils;
+
+public class PackageHeaderEmitter extends JSSubEmitter implements
+ ISubEmitter<IPackageDefinition>
+{
+
+ public PackageHeaderEmitter(IJSEmitter emitter)
+ {
+ super(emitter);
+ }
+
+ @Override
+ public void emit(IPackageDefinition definition)
+ {
+ IASScope containedScope = definition.getContainedScope();
+ ITypeDefinition type = EmitterUtils.findType(containedScope
+ .getAllLocalDefinitions());
+ String qname = null;
+ if (type != null)
+ {
+ qname = type.getQualifiedName();
+ }
+ if (qname == null)
+ {
+ IFunctionDefinition fn = EmitterUtils.findFunction(containedScope
+ .getAllLocalDefinitions());
+ if(fn != null)
+ {
+ qname = fn.getQualifiedName();
+ }
+ }
+ if (qname == null)
+ {
+ IVariableDefinition variable = EmitterUtils.findVariable(containedScope
+ .getAllLocalDefinitions());
+ if(variable != null)
+ {
+ qname = variable.getQualifiedName();
+ }
+ }
+ if (qname == null)
+ {
+ return;
+ }
+
+ FlexJSProject project = (FlexJSProject) getProject();
+ List<File> sourcePaths = project.getSourcePath();
+ String sourceName = definition.getSourcePath();
+ for (File sourcePath : sourcePaths)
+ {
+ if (sourceName.startsWith(sourcePath.getAbsolutePath()))
+ {
+ sourceName = sourceName.substring(sourcePath.getAbsolutePath().length() + 1);
+ }
+ }
+
+ writeNewline("/**");
+ writeNewline(" * Generated by Apache Flex Cross-Compiler from " + sourceName);
+ writeNewline(" * " + qname);
+ writeNewline(" *");
+ writeNewline(" * @fileoverview");
+ writeNewline(" *");
+ // need to suppress access controls so access to protected/private from defineProperties
+ // doesn't generate warnings.
+ writeNewline(" * @suppress {checkTypes|accessControls}");
+ writeNewline(" */");
+ writeNewline();
+
+ /* goog.provide('x');\n\n */
+ write(JSGoogEmitterTokens.GOOG_PROVIDE);
+ write(ASEmitterTokens.PAREN_OPEN);
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ write(getEmitter().formatQualifiedName(qname));
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ write(ASEmitterTokens.PAREN_CLOSE);
+ writeNewline(ASEmitterTokens.SEMICOLON);
+ writeNewline();
+ }
+
+ public void emitContents(IPackageDefinition definition)
+ {
+ // TODO (mschmalle) will remove this cast as more things get abstracted
+ JSFlexJSEmitter fjs = (JSFlexJSEmitter) getEmitter();
+
+ getEmitter().pushSourceMapName(definition.getNode());
+
+ PackageScope containedScope = (PackageScope) definition
+ .getContainedScope();
+
+ ArrayList<String> writtenRequires = new ArrayList<String>();
+
+ Collection<IDefinition> localDefinitions = containedScope.getAllLocalDefinitions();
+ ITypeDefinition type = EmitterUtils.findType(localDefinitions);
+ IDefinition otherMainDefinition = null;
+ if (type == null)
+ {
+ if (localDefinitions.isEmpty())
+ return;
+ // function or variable definition
+ otherMainDefinition = localDefinitions.iterator().next();
+ }
+ else
+ {
+ ITypeNode typeNode = type.getNode();
+ if (typeNode instanceof ClassNode)
+ {
+ ClassNode classNode = (ClassNode) typeNode;
+ ASDocComment asDoc = (ASDocComment) classNode.getASDocComment();
+ if (asDoc != null)
+ {
+ String asDocString = asDoc.commentNoEnd();
+ String ignoreToken = JSFlexJSEmitterTokens.IGNORE_IMPORT
+ .getToken();
+ int ignoreIndex = asDocString.indexOf(ignoreToken);
+ while (ignoreIndex != -1)
+ {
+ String ignorable = asDocString.substring(ignoreIndex
+ + ignoreToken.length());
+ int endIndex = ignorable.indexOf("\n");
+ ignorable = ignorable.substring(0, endIndex);
+ ignorable = ignorable.trim();
+ // pretend we've already written the goog.requires for this
+ writtenRequires.add(ignorable);
+ ignoreIndex = asDocString.indexOf(ignoreToken,
+ ignoreIndex + ignoreToken.length());
+ }
+ }
+ }
+ }
+
+ // if (project == null)
+ // project = getWalker().getProject();
+
+ FlexJSProject flexProject = (FlexJSProject) getProject();
+ ASProjectScope projectScope = (ASProjectScope) flexProject.getScope();
+ ICompilationUnit cu = projectScope
+ .getCompilationUnitForDefinition(type != null ? type : otherMainDefinition);
+ ArrayList<String> requiresList = flexProject.getRequires(cu);
+ ArrayList<String> interfacesList = flexProject.getInterfaces(cu);
++ ArrayList<String> externalRequiresList = flexProject.getExternalRequires(cu);
+
+ String cname = (type != null) ? type.getQualifiedName() : otherMainDefinition.getQualifiedName();
+ writtenRequires.add(cname); // make sure we don't add ourselves
+
++ boolean emitsRequires = emitRequires(requiresList, writtenRequires, cname);
++ boolean emitsInterfaces = emitInterfaces(interfacesList, writtenRequires);
++
++ // erikdebruin: Add missing language feature support, with e.g. 'is' and
++ // 'as' operators. We don't need to worry about requiring
++ // this in every project: ADVANCED_OPTIMISATIONS will NOT
++ // include any of the code if it is not used in the project.
++ boolean makingSWC = flexProject.getSWFTarget() != null &&
++ flexProject.getSWFTarget().getTargetType() == TargetType.SWC;
++ boolean isMainCU = flexProject.mainCU != null
++ && cu.getName().equals(flexProject.mainCU.getName());
++ if (isMainCU || makingSWC)
++ {
++ ICompilerProject project = this.getProject();
++ if (project instanceof FlexJSProject)
++ {
++ if (((FlexJSProject)project).needLanguage)
++ {
++ write(JSGoogEmitterTokens.GOOG_REQUIRE);
++ write(ASEmitterTokens.PAREN_OPEN);
++ write(ASEmitterTokens.SINGLE_QUOTE);
++ write(JSFlexJSEmitterTokens.LANGUAGE_QNAME);
++ write(ASEmitterTokens.SINGLE_QUOTE);
++ write(ASEmitterTokens.PAREN_CLOSE);
++ writeNewline(ASEmitterTokens.SEMICOLON);
++ }
++ }
++ }
++
++ boolean emitsExternalRequires = emitExternalRequires(externalRequiresList, writtenRequires);
++
++ if (emitsRequires || emitsInterfaces || emitsExternalRequires || isMainCU)
++ {
++ writeNewline();
++ }
++
++ writeNewline();
++ writeNewline();
++ }
++
++ private boolean emitRequires(List<String> requiresList, List<String> writtenRequires, String cname)
++ {
+ boolean emitsRequires = false;
+ if (requiresList != null)
+ {
+ Collections.sort(requiresList);
+ for (String imp : requiresList)
+ {
+ if (imp.contains(JSGoogEmitterTokens.AS3.getToken()))
+ continue;
+
+ if (imp.equals(JSGoogEmitterTokens.GOOG_BIND.getToken()))
+ continue;
+
+ if (imp.equals(cname))
+ continue;
+
+ if (NativeUtils.isNative(imp))
+ {
- if (!(imp.equals("QName") || imp.equals("Namespace") || imp.equals("XML") || imp.equals("XMLList")))
- continue;
++ if (!(imp.equals("QName") || imp.equals("Namespace") || imp.equals("XML") || imp.equals("XMLList")))
++ continue;
+ }
+
+ if (writtenRequires.indexOf(imp) == -1)
+ {
+
+ /* goog.require('x');\n */
+ write(JSGoogEmitterTokens.GOOG_REQUIRE);
+ write(ASEmitterTokens.PAREN_OPEN);
+ write(ASEmitterTokens.SINGLE_QUOTE);
- write(fjs.formatQualifiedName(imp));
++ write(getEmitter().formatQualifiedName(imp));
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ write(ASEmitterTokens.PAREN_CLOSE);
+ writeNewline(ASEmitterTokens.SEMICOLON);
+
+ writtenRequires.add(imp);
+
+ emitsRequires = true;
+ }
+ }
+ }
-
++ return emitsRequires;
++ }
++
++ private boolean emitInterfaces(List<String> interfacesList, List<String> writtenRequires)
++ {
+ boolean emitsInterfaces = false;
+ if (interfacesList != null)
+ {
+ Collections.sort(interfacesList);
+ for (String imp : interfacesList)
+ {
+ if (writtenRequires.indexOf(imp) == -1)
+ {
+ write(JSGoogEmitterTokens.GOOG_REQUIRE);
+ write(ASEmitterTokens.PAREN_OPEN);
+ write(ASEmitterTokens.SINGLE_QUOTE);
- write(fjs.formatQualifiedName(imp));
++ write(getEmitter().formatQualifiedName(imp));
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ write(ASEmitterTokens.PAREN_CLOSE);
+ writeNewline(ASEmitterTokens.SEMICOLON);
+
+ emitsInterfaces = true;
+ }
+ }
+ }
-
- // erikdebruin: Add missing language feature support, with e.g. 'is' and
- // 'as' operators. We don't need to worry about requiring
- // this in every project: ADVANCED_OPTIMISATIONS will NOT
- // include any of the code if it is not used in the project.
- boolean makingSWC = flexProject.getSWFTarget() != null &&
- flexProject.getSWFTarget().getTargetType() == TargetType.SWC;
- boolean isMainCU = flexProject.mainCU != null
- && cu.getName().equals(flexProject.mainCU.getName());
- if (isMainCU || makingSWC)
++ return emitsInterfaces;
++ }
++
++ private boolean emitExternalRequires(List<String> externalRequiresList, List<String> writtenRequires)
++ {
++ boolean emitsExternalRequires = false;
++ if (externalRequiresList != null)
+ {
- ICompilerProject project = this.getProject();
- if (project instanceof FlexJSProject)
++ Collections.sort(externalRequiresList);
++ for (String imp : externalRequiresList)
+ {
- if (((FlexJSProject)project).needLanguage)
- {
- write(JSGoogEmitterTokens.GOOG_REQUIRE);
- write(ASEmitterTokens.PAREN_OPEN);
- write(ASEmitterTokens.SINGLE_QUOTE);
- write(JSFlexJSEmitterTokens.LANGUAGE_QNAME);
- write(ASEmitterTokens.SINGLE_QUOTE);
- write(ASEmitterTokens.PAREN_CLOSE);
- writeNewline(ASEmitterTokens.SEMICOLON);
- }
- }
- }
++ if (writtenRequires.indexOf(imp) == -1)
++ {
++ /* var x = require('x');\n */
++ write(ASEmitterTokens.VAR);
++ write(ASEmitterTokens.SPACE);
++ write(imp);
++ write(ASEmitterTokens.SPACE);
++ write(ASEmitterTokens.EQUAL);
++ write(ASEmitterTokens.SPACE);
++ write(NodeEmitterTokens.REQUIRE);
++ write(ASEmitterTokens.PAREN_OPEN);
++ write(ASEmitterTokens.SINGLE_QUOTE);
++ write(imp);
++ write(ASEmitterTokens.SINGLE_QUOTE);
++ write(ASEmitterTokens.PAREN_CLOSE);
++ writeNewline(ASEmitterTokens.SEMICOLON);
+
- if (emitsRequires || emitsInterfaces || isMainCU)
- {
- writeNewline();
- }
++ writtenRequires.add(imp);
+
- writeNewline();
- writeNewline();
++ emitsExternalRequires = true;
++ }
++ }
++ }
++ return emitsExternalRequires;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/58409300/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/node/NodeEmitterTokens.java
----------------------------------------------------------------------
diff --cc compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/node/NodeEmitterTokens.java
index 0000000,0000000..dddcf90
new file mode 100644
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/node/NodeEmitterTokens.java
@@@ -1,0 -1,0 +1,21 @@@
++package org.apache.flex.compiler.internal.codegen.js.node;
++
++import org.apache.flex.compiler.codegen.IEmitterTokens;
++
++public enum NodeEmitterTokens implements IEmitterTokens
++{
++ REQUIRE("require"),
++ EXPORTS("exports");
++
++ private String token;
++
++ private NodeEmitterTokens(String value)
++ {
++ token = value;
++ }
++
++ public String getToken()
++ {
++ return token;
++ }
++}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/58409300/compiler-jx/src/main/java/org/apache/flex/compiler/internal/projects/FlexJSProject.java
----------------------------------------------------------------------
diff --cc compiler-jx/src/main/java/org/apache/flex/compiler/internal/projects/FlexJSProject.java
index 67869ab,0000000..dab4843
mode 100644,000000..100644
--- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/projects/FlexJSProject.java
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/projects/FlexJSProject.java
@@@ -1,267 -1,0 +1,328 @@@
+/*
+ *
+ * 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.projects;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
++import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.flex.compiler.common.DependencyType;
+import org.apache.flex.compiler.definitions.IDefinition;
++import org.apache.flex.compiler.definitions.metadata.IMetaTag;
++import org.apache.flex.compiler.definitions.metadata.IMetaTagAttribute;
+import org.apache.flex.compiler.internal.codegen.mxml.flexjs.MXMLFlexJSEmitterTokens;
+import org.apache.flex.compiler.internal.css.codegen.CSSCompilationSession;
+import org.apache.flex.compiler.internal.definitions.InterfaceDefinition;
+import org.apache.flex.compiler.internal.driver.js.flexjs.JSCSSCompilationSession;
+import org.apache.flex.compiler.internal.driver.js.goog.JSGoogConfiguration;
+import org.apache.flex.compiler.internal.scopes.ASProjectScope.DefinitionPromise;
+import org.apache.flex.compiler.internal.targets.LinkageChecker;
+import org.apache.flex.compiler.internal.tree.mxml.MXMLClassDefinitionNode;
+import org.apache.flex.compiler.internal.units.SWCCompilationUnit;
+import org.apache.flex.compiler.internal.workspaces.Workspace;
+import org.apache.flex.compiler.targets.ITargetSettings;
+import org.apache.flex.compiler.tree.as.IASNode;
+import org.apache.flex.compiler.units.ICompilationUnit;
+
+/**
+ * @author aharui
+ *
+ */
+public class FlexJSProject extends FlexProject
+{
+
+ /**
+ * Constructor
+ *
+ * @param workspace The {@code Workspace} containing this project.
+ */
+ public FlexJSProject(Workspace workspace)
+ {
+ super(workspace);
+ MXMLClassDefinitionNode.GENERATED_ID_BASE = MXMLFlexJSEmitterTokens.ID_PREFIX.getToken();
+ }
+
+ private HashMap<ICompilationUnit, HashMap<String, String>> interfaces = new HashMap<ICompilationUnit, HashMap<String, String>>();
+ private HashMap<ICompilationUnit, HashMap<String, DependencyType>> requires = new HashMap<ICompilationUnit, HashMap<String, DependencyType>>();
++ private HashMap<ICompilationUnit, HashMap<String, DependencyType>> jsModules = new HashMap<ICompilationUnit, HashMap<String, DependencyType>>();
+
+ public JSGoogConfiguration config;
+
+ public ICompilationUnit mainCU;
+
+ @Override
+ public void addDependency(ICompilationUnit from, ICompilationUnit to,
+ DependencyType dt, String qname)
+ {
+ // ToDo (erikdebruin): add VF2JS conditional -> only use check during full SDK compilation
+ List<IDefinition> dp = to.getDefinitionPromises();
+
+ if (dp.size() == 0)
+ return;
+
+ IDefinition def = dp.get(0);
+ // IDefinition def = to.getDefinitionPromises().get(0);
+ IDefinition actualDef = ((DefinitionPromise) def).getActualDefinition();
+ boolean isInterface = actualDef instanceof InterfaceDefinition;
+ if (!isInterface)
+ {
+ if (from != to)
+ {
+ HashMap<String, DependencyType> reqs;
+ if (requires.containsKey(from))
+ reqs = requires.get(from);
+ else
+ {
+ reqs = new HashMap<String, DependencyType>();
+ requires.put(from, reqs);
+ }
+ if (reqs.containsKey(qname))
+ {
+ // inheritance is important so remember it
+ if (reqs.get(qname) != DependencyType.INHERITANCE)
+ {
+ if (!isExternalLinkage(to))
+ reqs.put(qname, dt);
+ }
+ }
+ else if (!isExternalLinkage(to) || qname.equals("Namespace"))
+ {
+ if (qname.equals("XML"))
+ needXML = true;
+ reqs.put(qname, dt);
+ }
++ if (jsModules.containsKey(from))
++ {
++ reqs = jsModules.get(from);
++ }
++ else
++ {
++ reqs = new HashMap<String, DependencyType>();
++ jsModules.put(from, reqs);
++ }
++ IMetaTag tag = getJSModuleMetadata(to);
++ if (tag != null)
++ {
++ IMetaTagAttribute nameAttribute = tag.getAttribute("name");
++ if (nameAttribute != null)
++ {
++ reqs.put(nameAttribute.getValue(), dt);
++ }
++ else
++ {
++ reqs.put(qname, dt);
++ }
++ }
+ }
+ }
+ else
+ {
+ if (from != to)
+ {
+ HashMap<String, String> interfacesArr;
+
+ if (interfaces.containsKey(from))
+ {
+ interfacesArr = interfaces.get(from);
+ }
+ else
+ {
+ interfacesArr = new HashMap<String, String>();
+ interfaces.put(from, interfacesArr);
+ }
+
+ if (!interfacesArr.containsKey(qname))
+ {
+ if (qname.equals("org.apache.flex.core.IValuesImpl"))
+ needCSS = true;
+ interfacesArr.put(qname, qname);
+ }
+ }
+ }
+
+ super.addDependency(from, to, dt, qname);
+ }
+
+ public boolean needLanguage;
+ public boolean needCSS;
+ public boolean needXML;
+
+ private LinkageChecker linkageChecker;
+ private ITargetSettings ts;
+
+ // definitions that should be considered external linkage
+ public Collection<String> unitTestExterns;
+
++ private IMetaTag getJSModuleMetadata(ICompilationUnit cu)
++ {
++ try
++ {
++ Iterator<IDefinition> iterator = cu.getFileScopeRequest().get().getExternallyVisibleDefinitions().iterator();
++ while(iterator.hasNext())
++ {
++ IDefinition def = iterator.next();
++ if (def.hasMetaTagByName("JSModule"))
++ {
++ return def.getMetaTagByName("JSModule");
++ }
++ }
++ }
++ catch (Exception ex)
++ {
++ //it's safe to ignore an exception here
++ }
++ return null;
++ }
++
+ private boolean isExternalLinkage(ICompilationUnit cu)
+ {
+ if (linkageChecker == null)
+ {
+ ts = getTargetSettings();
+ linkageChecker = new LinkageChecker(this, ts);
+ }
+ // in unit tests, ts may be null and LinkageChecker NPEs
+ if (ts == null)
+ {
+ if (unitTestExterns != null)
+ {
+ try {
+ if (!(cu instanceof SWCCompilationUnit))
+ if (unitTestExterns.contains(cu.getQualifiedNames().get(0)))
+ return true;
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ return false;
+ }
+
+ List<String> qnames;
+ try {
+ qnames = cu.getQualifiedNames();
+ String qname = qnames.get(0);
+ if (qname.equals("QName"))
+ return false;
+ } catch (InterruptedException e1) {
+ // TODO Auto-generated catch block
+ e1.printStackTrace();
+ }
+ try
+ {
+ return linkageChecker.isExternal(cu);
+ }
+ catch (InterruptedException e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ public ArrayList<String> getInterfaces(ICompilationUnit from)
+ {
+ if (interfaces.containsKey(from))
+ {
+ HashMap<String, String> map = interfaces.get(from);
+ ArrayList<String> arr = new ArrayList<String>();
+ Set<String> cus = map.keySet();
+ for (String s : cus)
+ arr.add(s);
+ return arr;
+ }
+ return null;
+ }
+
+ public ArrayList<String> getRequires(ICompilationUnit from)
+ {
+ if (requires.containsKey(from))
+ {
+ HashMap<String, DependencyType> map = requires.get(from);
+ ArrayList<String> arr = new ArrayList<String>();
+ Set<String> cus = map.keySet();
+ for (String s : cus)
+ arr.add(s);
+ return arr;
+ }
+ return null;
+ }
+
++ public ArrayList<String> getExternalRequires(ICompilationUnit from)
++ {
++ if (jsModules.containsKey(from))
++ {
++ HashMap<String, DependencyType> map = jsModules.get(from);
++ ArrayList<String> arr = new ArrayList<String>();
++ Set<String> cus = map.keySet();
++ for (String s : cus)
++ arr.add(s);
++ return arr;
++ }
++ return null;
++ }
++
+ JSCSSCompilationSession cssSession = new JSCSSCompilationSession();
+
+ @Override
+ public CSSCompilationSession getCSSCompilationSession()
+ {
+ // When building SWFs, each MXML document may have its own styles
+ // specified by fx:Style blocks. The CSS is separately compiled and
+ // stored in the class definition for the MXML document. That helps
+ // with deferred loading of classes. The styles and thus the
+ // classes for an MXML document are not initialized until the MXML
+ // class is initialized.
+ // For JS compilation, the CSS for non-standard CSS could be done the
+ // same way, but AFAICT, standard CSS properties are best loaded by
+ // specifying a .CSS file in the HTML. The CSS is probably less text
+ // than its codegen'd representation, and the browser can probably
+ // load a .CSS file faster than us trying to run code to update the
+ // styles.
+ // So, for FlexJS, all style blocks from all MXML files are gathered into
+ // one .css file and a corresponding codegen block that is output as
+ // part of the main .JS file.
+ return cssSession;
+ }
+
+ private HashMap<IASNode, String> astCache = new HashMap<IASNode, String>();
+
+ @Override
+ public void addToASTCache(IASNode ast)
+ {
+ astCache.put(ast, "");
+ }
+
+ @Override
+ public void setTargetSettings(ITargetSettings value)
+ {
+ super.setTargetSettings(value);
+ ts = value;
+ linkageChecker = new LinkageChecker(this, value);
+ try {
+ linkageChecker.initExterns();
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+}