This is an automated email from the ASF dual-hosted git repository. aharui pushed a commit to branch develop in repository https://gitbox.apache.org/repos/asf/royale-compiler.git
commit 3c577e240b65c4f7be27b7af45a340f97e737793 Author: Alex Harui <aha...@apache.org> AuthorDate: Tue Nov 20 11:24:33 2018 -0800 externs-report seems to work --- .../royale/compiler/clients/MXMLJSCRoyale.java | 199 ++++++++++++++++++++- 1 file changed, 196 insertions(+), 3 deletions(-) diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/clients/MXMLJSCRoyale.java b/compiler-jx/src/main/java/org/apache/royale/compiler/clients/MXMLJSCRoyale.java index 8d0e167..2e9686d 100644 --- a/compiler-jx/src/main/java/org/apache/royale/compiler/clients/MXMLJSCRoyale.java +++ b/compiler-jx/src/main/java/org/apache/royale/compiler/clients/MXMLJSCRoyale.java @@ -32,6 +32,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; @@ -49,19 +50,31 @@ import org.apache.royale.compiler.config.Configuration; import org.apache.royale.compiler.config.ConfigurationBuffer; import org.apache.royale.compiler.config.Configurator; import org.apache.royale.compiler.config.ICompilerSettingsConstants; +import org.apache.royale.compiler.definitions.IDefinition; import org.apache.royale.compiler.driver.IBackend; import org.apache.royale.compiler.driver.js.IJSApplication; import org.apache.royale.compiler.exceptions.ConfigurationException; import org.apache.royale.compiler.exceptions.ConfigurationException.IOError; import org.apache.royale.compiler.exceptions.ConfigurationException.MustSpecifyTarget; import org.apache.royale.compiler.exceptions.ConfigurationException.OnlyOneSource; +import org.apache.royale.compiler.internal.codegen.as.ASEmitterTokens; +import org.apache.royale.compiler.internal.codegen.js.goog.JSGoogDocEmitter; +import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitter; import org.apache.royale.compiler.internal.config.FlashBuilderConfigurator; +import org.apache.royale.compiler.internal.definitions.AccessorDefinition; +import org.apache.royale.compiler.internal.definitions.ClassDefinition; +import org.apache.royale.compiler.internal.definitions.FunctionDefinition; +import org.apache.royale.compiler.internal.definitions.InterfaceDefinition; +import org.apache.royale.compiler.internal.definitions.ParameterDefinition; +import org.apache.royale.compiler.internal.definitions.ScopedDefinitionBase; import org.apache.royale.compiler.internal.driver.js.goog.JSGoogConfiguration; import org.apache.royale.compiler.internal.driver.mxml.royale.MXMLRoyaleBackend; import org.apache.royale.compiler.internal.parsing.as.RoyaleASDocDelegate; import org.apache.royale.compiler.internal.projects.CompilerProject; import org.apache.royale.compiler.internal.projects.RoyaleJSProject; import org.apache.royale.compiler.internal.projects.ISourceFileHandler; +import org.apache.royale.compiler.internal.scopes.ASProjectScope.DefinitionPromise; +import org.apache.royale.compiler.internal.scopes.ASScope; import org.apache.royale.compiler.internal.targets.RoyaleJSTarget; import org.apache.royale.compiler.internal.targets.JSTarget; import org.apache.royale.compiler.internal.units.ResourceBundleCompilationUnit; @@ -74,6 +87,7 @@ import org.apache.royale.compiler.problems.InternalCompilerProblem; import org.apache.royale.compiler.problems.UnableToBuildSWFProblem; import org.apache.royale.compiler.problems.UnexpectedExceptionProblem; import org.apache.royale.compiler.projects.ICompilerProject; +import org.apache.royale.compiler.scopes.IDefinitionSet; import org.apache.royale.compiler.targets.ITarget; import org.apache.royale.compiler.targets.ITarget.TargetType; import org.apache.royale.compiler.targets.ITargetSettings; @@ -442,10 +456,189 @@ public class MXMLJSCRoyale implements JSCompilerEntryPoint, ProblemQueryProvider private void generateExternsReport(File externsReportFile, List<ICompilationUnit> reachableCompilationUnits, - ProblemQuery problems2) { - // TODO Auto-generated method stub - + ProblemQuery problems) { + + System.out.println("Generating externs report: " + externsReportFile.getAbsolutePath()); + + ArrayList<String> packageNames = new ArrayList<String>(); + + StringBuilder sb = new StringBuilder(); + sb.append("/**\n"); + sb.append(" * Generated by Apache Royale Compiler\n"); + sb.append(" *\n"); + sb.append(" * @fileoverview\n"); + sb.append(" * @externs\n"); + sb.append(" *\n"); + // need to suppress access controls so access to protected/private from defineProperties + // doesn't generate warnings. + sb.append(" * @suppress {checkTypes|accessControls}\n"); + sb.append(" */\n"); + + for (ICompilationUnit cu : reachableCompilationUnits) + { + if (project.isExternalLinkage(cu)) continue; + + List<IDefinition> dp = cu.getDefinitionPromises(); + + if (dp.size() == 0) + return; + + IDefinition def = dp.get(0); + IDefinition actualDef = ((DefinitionPromise) def).getActualDefinition(); + if (actualDef instanceof ClassDefinition) + { + sb.append("\n\n"); + ClassDefinition cdef = (ClassDefinition)actualDef; + String pkgName = cdef.getPackageName(); + if (pkgName.length() > 0 && !packageNames.contains(pkgName)) + { + packageNames.add(pkgName); + String[] parts = pkgName.split("\\."); + String current = ""; + boolean firstOne = true; + for (String part : parts) + { + current += part; + sb.append("/** @const */\n"); + if (firstOne) + { + sb.append("var "); + firstOne = false; + } + sb.append(current); + sb.append(" = {}"); + sb.append(ASEmitterTokens.SEMICOLON.getToken() + "\n"); + current += "."; + } + } + sb.append("\n\n"); + sb.append("/**\n"); + sb.append(" * @constructor\n"); + String baseString = cdef.getBaseClassAsDisplayString(); + if (baseString.length() > 0) + sb.append(" * @extends {" + baseString + "}\n"); + String[] ifaces = cdef.getImplementedInterfacesAsDisplayStrings(); + for (String iface : ifaces) + sb.append(" * @implements {" + iface + "}\n"); + sb.append(" */\n"); + sb.append("function " + cdef.getQualifiedName() + "() {}\n"); + + ASScope cscope = cdef.getContainedScope(); + Collection<IDefinitionSet> defSets = cscope.getAllLocalDefinitionSets(); + IDefinitionSet[] arrayOfDefSets = new IDefinitionSet[defSets.size()]; + defSets.toArray(arrayOfDefSets); + for (IDefinitionSet defSet : arrayOfDefSets) + { + int n = defSet.getSize(); + for (int i = 0; i < n; i++) + { + IDefinition api = defSet.getDefinition(i); + if (!api.isOverride() && (api.isProtected() || api.isPublic())) + { + if (!(api instanceof FunctionDefinition) || + api instanceof AccessorDefinition) + { + sb.append("\n\n"); + sb.append("/**\n"); + sb.append(" * @type {" + getJSType(api.getTypeAsDisplayString()) + "}\n"); + sb.append(" */\n"); + sb.append(cdef.getQualifiedName() + "."); + if (!api.isStatic()) + sb.append("prototype."); + sb.append(api.getBaseName() + ";\n"); + } + else + { + FunctionDefinition method = (FunctionDefinition)api; + ParameterDefinition[] params = method.getParameters(); + sb.append("\n\n"); + sb.append("/**\n"); + for (ParameterDefinition param : params) + sb.append(" * @param {" + getJSType(param.getTypeAsDisplayString()) + "} " + param.getBaseName() + "\n"); + String ret = getJSType(method.getReturnTypeAsDisplayString()); + if (!ret.equals("void")) + sb.append(" * @returns {" + ret + "}\n"); + sb.append(" */\n"); + sb.append(cdef.getQualifiedName() + "."); + if (!api.isStatic()) + sb.append("prototype."); + sb.append(api.getBaseName()); + sb.append(" = function("); + int m = params.length; + for (int j = 0; j < m; j++) + { + if (j > 0) + sb.append(","); + sb.append(params[j].getBaseName()); + } + sb.append(") {"); + if (!ret.equals("void")) + { + if (ret.equals("number")) + sb.append(" return 0; "); + else if (ret.equals("boolean")) + sb.append(" return false; "); + else + sb.append(" return null; "); + } + sb.append("};\n"); + } + } + } + } + } + else if (actualDef instanceof InterfaceDefinition) + { + sb.append("\n\n"); + InterfaceDefinition cdef = (InterfaceDefinition)actualDef; + String pkgName = cdef.getPackageName(); + if (pkgName.length() > 0 && !packageNames.contains(pkgName)) + { + packageNames.add(pkgName); + String[] parts = pkgName.split("\\."); + String current = ""; + boolean firstOne = true; + for (String part : parts) + { + current += part; + sb.append("/** @const */\n"); + if (firstOne) + { + sb.append("var "); + firstOne = false; + } + sb.append(current); + sb.append(" = {}"); + sb.append(ASEmitterTokens.SEMICOLON.getToken() + "\n"); + current += "."; + } + } + sb.append("\n\n"); + sb.append("/**\n"); + sb.append(" * @interface\n"); + String[] ifaces = cdef.getExtendedInterfacesAsDisplayStrings(); + for (String iface : ifaces) + sb.append(" * @extends {" + iface + "}\n"); + sb.append(" */\n"); + sb.append("function " + cdef.getQualifiedName() + "() {}\n"); + } + } + System.out.println("Writing externs report: " + externsReportFile.getAbsolutePath()); + FileWriter fw; + try { + fw = new FileWriter(externsReportFile, false); + fw.write(sb.toString()); + fw.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } } + + private String getJSType(String s) + { + return JSGoogDocEmitter.convertASTypeToJSType(s, ""); + } private void outputResourceBundle(ResourceBundleCompilationUnit cu, File outputFolder) { // TODO Auto-generated method stub