- Renamed the "generate" goal to "generate-extern" - Replicated the changes to the node extern to match the develop branch - Fixed the replace commands in js to generate an identical es3.js (Adjusted the build helper too) - 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/dd503343 Tree: http://git-wip-us.apache.org/repos/asf/flex-falcon/tree/dd503343 Diff: http://git-wip-us.apache.org/repos/asf/flex-falcon/diff/dd503343 Branch: refs/heads/feature/maven-migration-test Commit: dd5033438d69769a6e49e1f32cee6da66a9996a5 Parents: b42cb99 fb2dc7a Author: Christofer Dutz <[email protected]> Authored: Thu Apr 21 13:35:19 2016 +0200 Committer: Christofer Dutz <[email protected]> Committed: Thu Apr 21 13:35:19 2016 +0200 ---------------------------------------------------------------------- .gitignore | 1 + .../patchfiles/ReplaceRegexpOperation.java | 3 + .../compiler/clients/ExternCConfiguration.java | 7 ++ .../externals/emit/ReferenceEmitter.java | 20 +++ .../codegen/externals/pass/AddMemberPass.java | 43 ++++++- .../externals/pass/CollectTypesPass.java | 10 ++ .../externals/reference/FieldReference.java | 9 +- .../externals/reference/MethodReference.java | 33 ++++- .../externals/reference/ParameterReference.java | 6 + .../codegen/externals/utils/FunctionUtils.java | 40 ++++-- .../codegen/js/jx/BinaryOperatorEmitter.java | 7 +- .../codegen/externals/ExternalsTestUtils.java | 26 ---- .../internal/caches/CSSDocumentCache.java | 11 +- .../parsing/as/StreamingASTokenizer.java | 13 ++ compiler/src/test/java/as/ASKeywordTests.java | 21 ++++ externs/js/pom.xml | 3 +- externs/js/src/main/config/externc-config.xml | 12 +- externs/node/pom.xml | 26 ++++ .../node/src/main/config/compile-as-config.xml | 123 ++++++++++++++++++- externs/node/src/main/config/externc-config.xml | 36 +++++- externs/node/src/main/javascript/missing.js | 25 ++++ externs/node/src/main/javascript/node.js | 30 ----- .../apache/flex/maven/flexjs/ExterncMojo.java | 2 +- .../resources/META-INF/plexus/components.xml | 2 +- 24 files changed, 422 insertions(+), 87 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dd503343/.gitignore ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dd503343/compiler-build-tools/src/main/java/org/apache/flex/compiler/tools/patchfiles/ReplaceRegexpOperation.java ---------------------------------------------------------------------- diff --cc compiler-build-tools/src/main/java/org/apache/flex/compiler/tools/patchfiles/ReplaceRegexpOperation.java index f295692,0000000..fbfcd2e mode 100644,000000..100644 --- a/compiler-build-tools/src/main/java/org/apache/flex/compiler/tools/patchfiles/ReplaceRegexpOperation.java +++ b/compiler-build-tools/src/main/java/org/apache/flex/compiler/tools/patchfiles/ReplaceRegexpOperation.java @@@ -1,84 -1,0 +1,87 @@@ +/* + * Copyright 2001-2005 The Apache Software Foundation. + * + * Licensed 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.tools.patchfiles; + +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.io.IOUtils; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; + +/** + * Created by christoferdutz on 16.03.16. + */ +public class ReplaceRegexpOperation extends Operation { + + private String match; + private String replace; + private String flags; + + public ReplaceRegexpOperation() { + } + + public String getMatch() { + return match; + } + + public void setMatch(String match) { + this.match = match; + } + + public String getReplace() { + return replace; + } + + public void setReplace(String replace) { + this.replace = replace; + } + + public String getFlags() { + return flags; + } + + public void setFlags(String flags) { + this.flags = flags; + } + + @Override + public void perform(File file) throws IOException { + String content = IOUtils.toString(new FileInputStream(file), "UTF-8"); + // TODO: Add the "flags" support + String matchExpression = match; + if(matchExpression.contains("§{file.base}")) { + matchExpression = matchExpression.replaceAll("§\\{file.base\\}", FilenameUtils.getBaseName(file.getName())); + } + String replaceExpression = (replace == null) ? "" : replace; + if(replaceExpression.contains("§{file.base}")) { + replaceExpression = replaceExpression.replaceAll("§\\{file.base\\}", FilenameUtils.getBaseName(file.getName())); + } + if(replaceExpression.contains("_")) { + replaceExpression = replaceExpression.replaceAll("_", " "); + } ++ if(replaceExpression.contains("\\n")) { ++ replaceExpression = replaceExpression.replaceAll("\\\\n", "\n"); ++ } + + //content = Pattern.compile(matchExpression, Pattern.DOTALL).matcher(content).replaceAll(replaceExpression); + content = content.replaceAll(matchExpression, replaceExpression); + IOUtils.write(content, new FileOutputStream(file), "UTF-8"); + } + +} http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dd503343/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 7eea457,0000000..c15786a 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,357 -1,0 +1,364 @@@ +/* + * + * 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> 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, "")); + } + + 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/dd503343/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/emit/ReferenceEmitter.java ---------------------------------------------------------------------- diff --cc compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/emit/ReferenceEmitter.java index 957d352,0000000..c7d3c45 mode 100644,000000..100644 --- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/emit/ReferenceEmitter.java +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/emit/ReferenceEmitter.java @@@ -1,166 -1,0 +1,186 @@@ +/* + * + * 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.emit; + +import java.io.File; +import java.io.IOException; + +import org.apache.commons.io.FileUtils; +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.FunctionReference; +import org.apache.flex.compiler.internal.codegen.externals.reference.ReferenceModel; + +public class ReferenceEmitter +{ + private ReferenceModel model; + + public ReferenceEmitter(ReferenceModel model) + { + this.model = model; + } + + public void emit() throws IOException + { + final File asRoot = model.getConfiguration().getAsRoot(); + if (!asRoot.exists()) + asRoot.mkdirs(); + + emitClasses(); + emitInterfaces(); + emitTypedefs(); + emitFunctions(); + emitConstants(); + } + + protected void emitInterfaces() throws IOException + { + final StringBuilder sb = new StringBuilder(); + for (ClassReference reference : model.getClasses()) + { + if (model.isExcludedClass(reference) != null) + continue; + + if (!reference.isInterface()) + continue; + + if (model.getConfiguration().isExternalExtern(reference)) + continue; + + emit(reference, sb); + + File sourceFile = reference.getFile(model.getConfiguration().getAsInterfaceRoot()); ++ if(sourceFile.exists()) ++ { ++ sourceFile = reference.getFile(model.getConfiguration().getAsDuplicatesRoot()); ++ } + FileUtils.write(sourceFile, sb.toString()); + + sb.setLength(0); + } + } + + protected void emitClasses() throws IOException + { + final StringBuilder sb = new StringBuilder(); + for (ClassReference reference : model.getClasses()) + { + if (model.isExcludedClass(reference) != null) + continue; + + if (reference.isInterface()) + continue; + + if (model.getConfiguration().isExternalExtern(reference)) + continue; + + emit(reference, sb); + + File sourceFile = reference.getFile(model.getConfiguration().getAsClassRoot()); ++ if(sourceFile.exists()) ++ { ++ sourceFile = reference.getFile(model.getConfiguration().getAsDuplicatesRoot()); ++ } + FileUtils.write(sourceFile, sb.toString()); + + sb.setLength(0); + } + } + + protected void emitTypedefs() throws IOException + { + final StringBuilder sb = new StringBuilder(); + // TODO figure out how to resolve/emit @typedef + for (ClassReference reference : model.getTypedefs()) + { + if (model.isExcludedClass(reference) != null) + continue; + + if (model.getConfiguration().isExternalExtern(reference)) + continue; + + emit(reference, sb); + + File sourceFile = reference.getFile(model.getConfiguration().getAsTypeDefRoot()); ++ if(sourceFile.exists()) ++ { ++ sourceFile = reference.getFile(model.getConfiguration().getAsDuplicatesRoot()); ++ } + FileUtils.write(sourceFile, sb.toString()); + + sb.setLength(0); + } + } + + protected void emitFunctions() throws IOException + { + final StringBuilder sb = new StringBuilder(); + for (FunctionReference reference : model.getFunctions()) + { + if (model.getConfiguration().isExternalExtern(reference)) + continue; + + emit(reference, sb); + + File sourceFile = reference.getFile(model.getConfiguration().getAsFunctionRoot()); ++ if(sourceFile.exists()) ++ { ++ sourceFile = reference.getFile(model.getConfiguration().getAsDuplicatesRoot()); ++ } + FileUtils.write(sourceFile, sb.toString()); + + sb.setLength(0); + } + } + + protected void emitConstants() throws IOException + { + final StringBuilder sb = new StringBuilder(); + for (ConstantReference reference : model.getConstants()) + { + if (model.getConfiguration().isExternalExtern(reference)) + continue; + + emit(reference, sb); + + File sourceFile = reference.getFile(model.getConfiguration().getAsConstantRoot()); ++ if(sourceFile.exists()) ++ { ++ sourceFile = reference.getFile(model.getConfiguration().getAsDuplicatesRoot()); ++ } + FileUtils.write(sourceFile, sb.toString()); + + sb.setLength(0); + } + } + + public void emit(BaseReference reference, StringBuilder sb) + { + reference.emit(sb); + } + + public String emit(BaseReference reference) + { + final StringBuilder sb = new StringBuilder(); + reference.emit(sb); + return sb.toString(); + } +} http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dd503343/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/pass/AddMemberPass.java ---------------------------------------------------------------------- diff --cc compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/pass/AddMemberPass.java index 8379af9,0000000..9308ff0 mode 100644,000000..100644 --- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/pass/AddMemberPass.java +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/pass/AddMemberPass.java @@@ -1,150 -1,0 +1,191 @@@ +/* + * + * 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.pass; + +import org.apache.flex.compiler.internal.codegen.externals.reference.ReferenceModel; + +import com.google.javascript.jscomp.AbstractCompiler; +import com.google.javascript.jscomp.NodeTraversal; ++import com.google.javascript.rhino.JSDocInfo; +import com.google.javascript.rhino.Node; + +public class AddMemberPass extends AbstractCompilerPass +{ + + public AddMemberPass(ReferenceModel model, AbstractCompiler compiler) + { + super(model, compiler); + } + + @Override + public boolean shouldTraverse(NodeTraversal nodeTraversal, Node n, + Node parent) + { + return n.isBlock() || n.isScript(); + } + + @Override + public void visit(NodeTraversal t, Node n, Node parent) + { + for (Node child : n.children()) + { + //log(child); + + if (child.isExprResult()) + { + Node first = child.getFirstChild(); + + if (first.isVar()) + { + // visitVar(t, n); + } + else if (first.isFunction()) + { + // visitFunction(t, n); + } + else if (first.isAssign()) + { + if (first.getFirstChild().isGetProp() + && first.getLastChild().isFunction()) + { + // instance or static method + visitMethod(t, first); + } + else + { + // DOMException.INDEX_SIZE_ERR = 1; + // The first child of the assign is the GetProp node, + // if later you need the value, either change this or check + // for a parent assign node when creating the FieldReference + // which the value would be n.getLastChild() + // XXX visitStaticField(t, n); + //System.err.println(n.toStringTree()); + } + } + else if (first.isGetProp()) + { - visitGetProp(t, first); ++ JSDocInfo jsDocInfo = first.getJSDocInfo(); ++ if (jsDocInfo != null ++ && (jsDocInfo.getParameterCount() > 0 ++ || jsDocInfo.getReturnType() != null)) ++ { ++ // instance or static method that isn't declared as a ++ // function, but has @param or @returns ++ visitMethodFromJSDoc(t, first); ++ } ++ else ++ { ++ visitGetProp(t, first); ++ } + } + } + } + } + + // n == ASSIGN + private void visitMethod(NodeTraversal t, Node n) + { + String qName = n.getFirstChild().getQualifiedName(); + + if (n.getFirstChild().isGetProp()) + { + int protoType = qName.indexOf(".prototype."); + if (protoType != -1) + { + String className = qName.substring(0, protoType); + String memberName = qName.substring(protoType + 11, + qName.length()); + //log("Prototype:: className [" + className + // + "] memberName [" + memberName + "]"); + model.addMethod(n, className, memberName); + } + else + { + String className = qName.substring(0, qName.lastIndexOf(".")); + String memberName = qName.substring(qName.lastIndexOf(".") + 1, + qName.length()); + //log("className [" + className + "] memberName [" + // + memberName + "]"); + model.addStaticMethod(n, className, memberName); + } + } + else if (n.getFirstChild().isName()) + { + err("visitMethod() non impl"); + log(n); + } + } ++ private void visitMethodFromJSDoc(NodeTraversal t, Node n) ++ { ++ String qName = n.getQualifiedName(); ++ ++ if (n.isGetProp()) ++ { ++ int protoType = qName.indexOf(".prototype."); ++ if (protoType != -1) ++ { ++ String className = qName.substring(0, protoType); ++ String memberName = qName.substring(protoType + 11, ++ qName.length()); ++ model.addMethod(n, className, memberName); ++ } ++ else ++ { ++ String className = qName.substring(0, qName.lastIndexOf(".")); ++ String memberName = qName.substring(qName.lastIndexOf(".") + 1, ++ qName.length()); ++ model.addStaticMethod(n, className, memberName); ++ } ++ } ++ else if (n.isName()) ++ { ++ err("visitMethod() non impl"); ++ log(n); ++ } ++ } + + private void visitGetProp(NodeTraversal t, Node n) + { + String qualifiedName = n.getQualifiedName(); + + log("visitGetProp [" + qualifiedName + "]"); + + int protoType = qualifiedName.indexOf(".prototype."); + if (protoType != -1) + { + String className = qualifiedName.substring(0, protoType); + String memberName = qualifiedName.substring(protoType + 11, + qualifiedName.length()); + //log("Prototype:: className [" + className + // + "] memberName [" + memberName + "]"); + model.addField(n, className, memberName); + } + else + { + String className = qualifiedName.substring(0, + qualifiedName.lastIndexOf(".")); + String memberName = qualifiedName.substring( + qualifiedName.lastIndexOf(".") + 1, qualifiedName.length()); + //log("className [" + className + "] memberName [" + // + memberName + "]"); + model.addStaticField(n, className, memberName); + } + } +} http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dd503343/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/pass/CollectTypesPass.java ---------------------------------------------------------------------- diff --cc compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/pass/CollectTypesPass.java index 8ddde76,0000000..44a9cc4 mode 100644,000000..100644 --- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/pass/CollectTypesPass.java +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/pass/CollectTypesPass.java @@@ -1,165 -1,0 +1,175 @@@ +/* + * + * 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.pass; + +import org.apache.flex.compiler.internal.codegen.externals.reference.ReferenceModel; + +import com.google.javascript.jscomp.AbstractCompiler; +import com.google.javascript.jscomp.NodeTraversal; +import com.google.javascript.rhino.JSDocInfo; +import com.google.javascript.rhino.Node; + +public class CollectTypesPass extends AbstractCompilerPass +{ + public CollectTypesPass(ReferenceModel model, AbstractCompiler compiler) + { + super(model, compiler); + } + + @Override + public boolean shouldTraverse(NodeTraversal nodeTraversal, Node n, + Node parent) + { + return n.isBlock() || n.isScript(); + } + + @Override + public void visit(NodeTraversal t, Node n, Node parent) + { + for (Node child : n.children()) + { + if (child.isVar()) + { + visitVar(child); + } + else if (child.isFunction()) + { + visitFunction(child); + } + else if (child.isExprResult()) + { + visitExprResult(child); + } + } + } + + private void visitExprResult(Node child) + { + JSDocInfo comment = null; + + Node container = child.getFirstChild(); + if (container.isAssign()) + { + comment = container.getJSDocInfo(); + + Node left = container.getFirstChild(); + Node right = container.getLastChild(); + + if (left.isName() && right.isFunction()) + { + if (comment.isConstructor() || comment.isInterface()) + { + // Foo = function () {}; + model.addClass(container, left.getString()); + } + + } + else if (left.isGetProp() && right.isFunction()) + { + boolean isConstructor = comment != null + && (comment.isConstructor() || comment.isInterface()); + // foo.bar.Baz = function () {}; + if (isConstructor) + { + model.addClass(container, left.getQualifiedName()); + } + } + } ++ else ++ { ++ comment = container.getJSDocInfo(); ++ boolean isConstructor = comment != null ++ && (comment.getTypedefType() != null); ++ if (isConstructor) ++ { ++ model.addTypeDef(container, container.getQualifiedName()); ++ } ++ } + } + + private void visitFunction(Node child) + { + JSDocInfo comment = child.getJSDocInfo(); + + boolean isConstructor = comment != null + && (comment.isConstructor() || comment.isInterface()); + + if (isConstructor) + { + // function Goo () {}; + model.addClass(child, child.getFirstChild().getString()); + } + else + { + model.addFunction(child, child.getFirstChild().getString()); + } + } + + private void visitVar(Node child) + { + JSDocInfo comment = child.getJSDocInfo(); + + Node first = child.getFirstChild(); + if (first.isName()) + { + Node subFirst = first.getFirstChild(); + if (subFirst != null && subFirst.isObjectLit()) + { + if (comment.hasEnumParameterType()) + { + + } + else + { + //System.out.println(first.getFirstChild().toStringTree()); + //log("Encountered namespace [" + first.getQualifiedName() + "]"); + model.addNamespace(child, first.getQualifiedName()); + } + } + else if (subFirst != null && subFirst.isFunction()) + { + boolean isConstructor = comment != null + && (comment.isConstructor() || comment.isInterface()); + // foo.bar.Baz = function () {}; + if (isConstructor) + { + model.addClass(child, first.getString()); + } + } + else + { + boolean isConstructor = comment != null + && (comment.getTypedefType() != null); + // * @typedef + // var foo; + if (isConstructor) + { + // model.addClass(child, first.getString()); + model.addTypeDef(child, first.getString()); + } + else if (comment != null && comment.isConstant()) + { + //System.out.println(child.toStringTree()); + model.addConstant(child, first.getString()); + } + } + } + } +} http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dd503343/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/reference/FieldReference.java ---------------------------------------------------------------------- diff --cc compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/reference/FieldReference.java index d99a66d,0000000..e01a72a mode 100644,000000..100644 --- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/reference/FieldReference.java +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/reference/FieldReference.java @@@ -1,264 -1,0 +1,271 @@@ +/* + * + * 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 org.apache.flex.compiler.clients.ExternCConfiguration.ExcludedMember; ++import org.apache.flex.compiler.internal.codegen.externals.utils.FunctionUtils; +import org.apache.flex.compiler.internal.codegen.externals.utils.JSTypeUtils; + +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 FieldReference extends MemberReference +{ + + private boolean isStatic; + private boolean isConst; + private String overrideStringType; + private Node constantValueNode; + + public boolean isStatic() + { + return isStatic; + } + + public void setStatic(boolean isStatic) + { + this.isStatic = isStatic; + } + + public boolean isConst() + { + return isConst; + } + + public void setConst(boolean isConst) + { + this.isConst = isConst; + } + + public void setOverrideStringType(String overrideStringType) + { + this.overrideStringType = overrideStringType; + } + + public void setConstantValueNode(Node constantValueNode) + { + this.constantValueNode = constantValueNode; + } + + public String toTypeAnnotationString() + { + JSType jsType = null; + if (getComment() != null && getComment().getType() != null) + { + jsType = getModel().evaluate(getComment().getType()); + } + return jsType != null ? jsType.toAnnotationString() : "Object"; + } + + public FieldReference(ReferenceModel model, ClassReference classReference, Node node, String name, + JSDocInfo comment, boolean isStatic) + { + super(model, classReference, node, name, comment); + this.isStatic = isStatic; + } + + @Override + public void emit(StringBuilder sb) + { + // XXX HACK TEMP! + if (getComment().isConstructor()) + return; + + // Window has a global var Window that conflicts with the constructor. + if (getQualifiedName().equals(getClassReference().getQualifiedName())) + return; + + if (getClassReference().hasSuperField(getQualifiedName())) + return; + + emitComment(sb); + + ExcludedMember excluded = isExcluded(); + if (excluded != null) + { + excluded.print(sb); + return; // XXX (mschmalle) accessors are not treated right, need to exclude get/set + } + + if (!getClassReference().isInterface() && !getComment().isOverride() + && !getClassReference().isPropertyInterfaceImplementation(getBaseName())) + { + emitVar(sb); + } + else + { + emitAccessor(sb); + } + } + + private void emitAccessor(StringBuilder sb) + { + boolean isInterface = getClassReference().isInterface(); + + String staticValue = (isStatic) ? "static " : ""; + String isPublic = isInterface ? "" : "public "; + String getBody = isInterface ? "" : "{ return null; }"; + String setBody = isInterface ? "" : "{}"; + + String type = toTypeString(); + if (type.contains("|") || type.contains("?")) + type = "*"; + + if (outputJS) + { + sb.append(getClassReference().getPackageName()); + sb.append("."); + sb.append(getClassReference().getBaseName()); + sb.append("."); + if (!isStatic) + sb.append("prototype."); + sb.append(getBaseName()); + sb.append(";\n"); + return; + } + // getter + sb.append(indent); + sb.append(isPublic); + sb.append(staticValue); + sb.append("function get "); + sb.append(getBaseName()); + sb.append("():"); + sb.append(type); + sb.append(getBody); + sb.append(";\n"); + + // setter + sb.append(indent); + sb.append(isPublic); + sb.append(staticValue); + sb.append("function set "); + sb.append(getBaseName()); + sb.append("(value:"); + sb.append(type); + sb.append("):void"); + sb.append(setBody); + sb.append(";\n"); + } + + private void emitVar(StringBuilder sb) + { + String staticValue = (isStatic) ? "static " : ""; + String constVarValue = (isConst) ? "const " : "var "; + + String type = toTypeString(); + if (type.contains("|") || type.contains("?")) + type = "*"; + + if (outputJS) + { + sb.append(getClassReference().getPackageName()); + sb.append("."); + sb.append(getClassReference().getBaseName()); + sb.append("."); + if (!isStatic) + sb.append("prototype."); + sb.append(getBaseName()); + sb.append(";\n"); + return; + } + + sb.append(indent); + sb.append("public "); + sb.append(staticValue); + sb.append(constVarValue); + sb.append(getQualifiedName()); + sb.append(":"); + sb.append(type); + if (isConst) + { + emitConstValue(sb); + } + sb.append(";\n"); + } + + private void emitConstValue(StringBuilder sb) + { + sb.append(" = "); + sb.append(toConstValue(constantValueNode)); + } + + private String toConstValue(Node node) + { + if (toTypeString().equals("Number")) + return Integer.toString(getClassReference().getEnumConstant()); + if (node.isString()) + return "'" + node.getString() + "'"; + return "undefined /* TODO type not set */"; + } + + public String toTypeString() + { + if (overrideStringType != null) + return overrideStringType; - return JSTypeUtils.toFieldTypeString(this); ++ String typeString = JSTypeUtils.toFieldTypeString(this); ++ if (FunctionUtils.hasTemplate(this) ++ && FunctionUtils.containsTemplate(this, typeString)) ++ { ++ return "Object"; ++ } ++ return typeString; + } + + @Override + protected void emitCommentBody(StringBuilder sb) + { + emitBlockDescription(sb); + emitType(sb); + emitSee(sb); + emitSeeSourceFileName(sb); + } + + private void emitType(StringBuilder sb) + { + JSTypeExpression type = getComment().getType(); + if (type != null) + { + if (outputJS) + { + sb.append(indent); + sb.append(" * @type "); + sb.append("{"); + sb.append(mapBackToJS(getModel().evaluate(type).toAnnotationString())); + sb.append("} "); + sb.append("\n"); + } + else + { + sb.append(indent); + sb.append(" * @see JSType - "); + sb.append("["); + sb.append(getModel().evaluate(type).toAnnotationString()); + sb.append("] "); + String description = getComment().getReturnDescription(); + if (description != null) + sb.append(description); + sb.append("\n"); + } + } + } + +} http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dd503343/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/reference/MethodReference.java ---------------------------------------------------------------------- diff --cc compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/reference/MethodReference.java index 96aa9f2,0000000..6cfbadf mode 100644,000000..100644 --- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/reference/MethodReference.java +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/reference/MethodReference.java @@@ -1,316 -1,0 +1,347 @@@ +/* + * + * 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.List; +import java.util.Set; + +import org.apache.flex.compiler.clients.ExternCConfiguration.ExcludedMember; +import org.apache.flex.compiler.internal.codegen.externals.utils.FunctionUtils; + +import com.google.common.collect.Lists; +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 MethodReference extends MemberReference +{ + + private boolean isStatic; + private MethodReference override; + private Node paramNode; + + private List<ParameterReference> parameters; + + private MethodReference getContext() + { + return override == null ? this : override; + } + + public boolean isStatic() + { + return isStatic; + } + + public void setStatic(boolean isStatic) + { + this.isStatic = isStatic; + } + + public List<ParameterReference> getParameters() + { + return parameters; + } + + public Set<String> getParameterNames() + { + return getComment().getParameterNames(); + } + + public String toReturnTypeAnnotationString() + { + JSType jsType = getModel().evaluate(getComment().getReturnType()); + return jsType.toAnnotationString(); + } + + public MethodReference(ReferenceModel model, ClassReference classReference, Node node, String name, + JSDocInfo comment, boolean isStatic) + { + super(model, classReference, node, name, comment); + this.isStatic = isStatic; + + if (node.isFunction()) + { + this.paramNode = node.getChildAtIndex(1); + } + else if (node.getLastChild().isFunction()) + { + this.paramNode = node.getLastChild().getChildAtIndex(1); + } + + addParameterReferences(); + } + + private void addParameterReferences() + { + + parameters = new ArrayList<ParameterReference>(); + + if (paramNode != null) + { + + final boolean isDocumented = comment.getParameterCount() > 0; + List<String> parameterNames = null; + + if (isDocumented) + { + parameterNames = Lists.newArrayList(comment.getParameterNames()); + } + + for (Node param : paramNode.children()) + { + ParameterReference parameterReference; + + if (isDocumented && parameterNames.contains(param.getString())) + { + final String qualifiedName = FunctionUtils.toParameterType(this, param.getString()); + parameterReference = new ParameterReference(getModel(), param, qualifiedName); + } + else + { + parameterReference = new ParameterReference(getModel(), param); + } + + parameters.add(parameterReference); + } + } ++ else if(comment.getParameterCount() > 0 || comment.getReturnType() != null) ++ { ++ for (int i = 0; i < comment.getParameterCount(); i++) ++ { ++ String parameterName = comment.getParameterNameAt(i); ++ String qualifiedName = FunctionUtils.toParameterType(this, parameterName); ++ ParameterReference parameterReference = new ParameterReference(getModel(), parameterName, qualifiedName); ++ parameters.add(parameterReference); ++ } ++ } ++ else ++ { ++ System.out.println(getQualifiedName() + " parameters not found! " + " " + comment.getParameterCount()); ++ } + } + + @Override + public void emit(StringBuilder sb) + { + String className = getClassReference().getBaseName(); + + // XXX HACK TEMP! + if (getComment().isConstructor() && !getBaseName().equals(className)) + return; + + if (isConstructor()) + { + emitConstructor(sb); + return; + } + + String qName = getQualifiedName(); + // skip overrides since they have to have the same signature as the super method + if (getClassReference().hasSuperMethod(qName)) + return; + + emitComment(sb); + + ExcludedMember excluded = isExcluded(); + if (excluded != null) + { + excluded.print(sb); + } + + emitCode(sb); + + override = null; + } + + public void emitCode(StringBuilder sb) + { + String staticValue = (isStatic) ? "static " : ""; + if (getClassReference().isInterface()) + staticValue = ""; + + String isOverride = ""; + + if (!getClassReference().isInterface()) + { + MethodReference overrideFromInterface = getClassReference().getMethodOverrideFromInterface(this); + if (/*isOverride() && */overrideFromInterface != null) + { + override = overrideFromInterface; + } + } + + String qName = getQualifiedName(); + + String publicModifier = ""; + String braces = ""; + String returns = ""; + + String returnString = transformReturnString(); + if (!returnString.equals("void")) + { + if (returnString.equals("Number")) + returns = "return 0;"; + else + returns = " return null;"; + } + + if (!getClassReference().isInterface()) + { + publicModifier = "public "; + braces = " { " + returns + " }"; + } + + if (getClassReference().hasSuperMethod(qName)) + { + isOverride = "override "; + } + + if (outputJS) + { + sb.append(getClassReference().getPackageName()); + sb.append("."); + sb.append(getClassReference().getBaseName()); + sb.append("."); + if (isStatic) + sb.append("prototype."); + sb.append(qName); + sb.append(" = function "); + sb.append(toParameterString()); + sb.append(braces); + sb.append("\n"); + return; + } + + sb.append(indent); + sb.append(publicModifier); + sb.append(isOverride); + sb.append(staticValue); + sb.append("function "); + sb.append(getQualifiedName()); + sb.append(toParameterString()); + sb.append(":"); + sb.append(transformReturnString()); + sb.append(braces); + sb.append("\n"); + } + + private void emitConstructor(StringBuilder sb) + { + if (!outputJS) + emitComment(sb); + + if (outputJS) + { + sb.append(getClassReference().getPackageName()); + sb.append("."); + sb.append(getBaseName()); + sb.append(" = function "); + sb.append(toParameterString()); + sb.append(" {}\n"); + return; + } + + sb.append(indent); + sb.append("public function "); + sb.append(getBaseName()); + if (!getBaseName().equals("Object")) + { + sb.append(toParameterString()); + sb.append(" {\n"); + sb.append(indent); + emitSuperCall(sb); + sb.append(indent); + sb.append("}"); + } + else + { + sb.append("() {}"); + } + + sb.append("\n"); + } + + private void emitSuperCall(StringBuilder sb) + { + + sb.append(indent); + sb.append("super("); + + ClassReference superClass = getClassReference().getSuperClass(); + if (superClass != null && !superClass.getBaseName().equals("Object")) + { + MethodReference constructor = superClass.getConstructor(); + Set<String> parameterNames = constructor.getParameterNames(); + int len = parameterNames.size(); + for (int i = 0; i < len; i++) + { + sb.append("null"); + if (i < len - 1) + sb.append(", "); + } + } + + sb.append(");\n"); + } + + public boolean isConstructor() + { + return getComment().isConstructor(); + } + + public String transformReturnString() + { + return FunctionUtils.toReturnString(getContext()); + } + + private String toParameterString() + { - return FunctionUtils.toParameterString(getContext(), getContext().getComment(), paramNode, outputJS); ++ if (paramNode != null) ++ { ++ return FunctionUtils.toParameterString(getContext(), getContext().getComment(), paramNode, outputJS); ++ } ++ StringBuilder sb = new StringBuilder(); ++ sb.append("("); ++ int len = comment.getParameterCount(); ++ for (int i = 0; i < len; i++) ++ { ++ String parameterName = comment.getParameterNameAt(i); ++ JSTypeExpression parameterType = comment.getParameterType(i); ++ sb.append(FunctionUtils.toParameter(getContext(), comment, parameterName, parameterType, outputJS)); ++ if (i < len - 1) ++ sb.append(", "); ++ } ++ sb.append(")"); ++ return sb.toString(); + } + + public boolean isOverride() + { + return getComment().isOverride(); + } + + @Override + protected void emitCommentBody(StringBuilder sb) + { + emitFunctionCommentBody(sb); + } +} http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dd503343/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/reference/ParameterReference.java ---------------------------------------------------------------------- diff --cc compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/reference/ParameterReference.java index 4823873,0000000..30d7c15 mode 100644,000000..100644 --- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/reference/ParameterReference.java +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/reference/ParameterReference.java @@@ -1,53 -1,0 +1,59 @@@ +/* + * + * 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 com.google.javascript.rhino.Node; + +/** + * @author: Frederic Thomas Date: 05/07/2015 Time: 19:34 + */ +public class ParameterReference extends BaseReference +{ + + private String name; + + public ParameterReference(final ReferenceModel model, final Node node, final String qualifiedName) + { + super(model, node, qualifiedName, null); + name = node.getString(); + } + ++ public ParameterReference(final ReferenceModel model, final String name, final String qualifiedName) ++ { ++ super(model, null, qualifiedName, null); ++ this.name = name; ++ } ++ + public ParameterReference(final ReferenceModel model, final Node parameterNode) + { + this(model, parameterNode, "Object"); + } + + @Override + public void emit(final StringBuilder sb) + { + // Emitted by the Method / Function reference. + } + + public String getName() + { + return name; + } +} http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dd503343/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/utils/FunctionUtils.java ---------------------------------------------------------------------- diff --cc compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/utils/FunctionUtils.java index 473e42c,0000000..5a9b658 mode 100644,000000..100644 --- 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 @@@ -1,232 -1,0 +1,254 @@@ +/* + * + * 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.MemberReference; +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, ++ public 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) + { ++ if(reference instanceof MemberReference) ++ { ++ MemberReference memberRef = (MemberReference) reference; ++ if(memberRef.getClassReference().getComment().getTemplateTypeNames().size() > 0) ++ { ++ return true; ++ } ++ } + 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; ++ if(reference instanceof MemberReference) ++ { ++ MemberReference memberRef = (MemberReference) reference; ++ if(commentContainsTemplate(memberRef.getClassReference().getComment(), name)) ++ { ++ return true; ++ } ++ } ++ return commentContainsTemplate(reference.getComment(), name); ++ } ++ ++ private static boolean commentContainsTemplate(JSDocInfo comment, String name) ++ { ++ for (String template : comment.getTemplateTypeNames()) ++ { ++ if (name.contains("<" + template + ">")) ++ return true; ++ if (name.equals(template)) ++ return true; ++ } ++ return false; + } + +}
