in compiler-jx/src/main/java/org/apache/royale/compiler/clients/MXMLJSCRoyale.java [547:761]
private void generateExternsReport(File externsReportFile,
List<ICompilationUnit> reachableCompilationUnits,
ProblemQuery problems) {
if (config.isVerbose())
{
System.out.println("Generating externs report: " + externsReportFile.getAbsolutePath());
}
ArrayList<String> packageNames = new ArrayList<String>();
ArrayList<String> partNames = 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.getPackageName().contains("goog")) continue;
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;
if (partNames.contains(current))
{
firstOne = false;
current += ".";
continue;
}
partNames.add(current);
sb.append("/**\n * @suppress {duplicate}\n * @const\n */\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");
if (pkgName.length() == 0)
sb.append("function " + cdef.getQualifiedName() + "() {}\n");
else
sb.append(cdef.getQualifiedName() + " = function() {}\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);
String apiName = api.getBaseName();
if (apiName.startsWith("#")) continue; // invalid in externs
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)
{
if (param.getBaseName().isEmpty())
sb.append(" * @param {*=} opt_rest\n");
else
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(",");
if (params[j].getBaseName().isEmpty())
sb.append("opt_rest");
else
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;
if (partNames.contains(current))
{
firstOne = false;
current += ".";
continue;
}
partNames.add(current);
sb.append("/**\n * @suppress {duplicate}\n * @const\n */\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(cdef.getQualifiedName() + " = function() {}\n");
}
}
if (config.isVerbose())
{
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();
}
}