in compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/PackageFooterEmitter.java [262:541]
public void collectReflectionData(ITypeNode tnode)
{
JSRoyaleEmitter fjs = (JSRoyaleEmitter)getEmitter();
exportProperties = new ArrayList<String>();
exportSymbols = new ArrayList<String>();
ICompilerProject project = getWalker().getProject();
Set<String> exportMetadata = Collections.<String> emptySet();
if (project instanceof RoyaleJSProject)
{
RoyaleJSProject fjsp = ((RoyaleJSProject)project);
if (fjsp.config != null)
exportMetadata = fjsp.config.getCompilerKeepCodeWithMetadata();
}
varData = new ArrayList<VariableData>();
accessorData = new ArrayList<AccessorData>();
methodData = new ArrayList<MethodData>();
/*
* Reflection
*
* @return {Object.<string, Function>}
*/
IDefinitionNode[] dnodes;
String name;
//bindables:
HashMap<String, BindableVarInfo> bindableVars = getModel().getBindableVars();
boolean isInterface = tnode instanceof IInterfaceNode;
if (!isInterface)
dnodes = ((IClassNode) tnode).getAllMemberNodes();
else
dnodes = ((IInterfaceNode) tnode).getAllMemberDefinitionNodes();
reflectionKind = isInterface ? ReflectionKind.INTERFACE : ReflectionKind.CLASS;
for (IDefinitionNode dnode : dnodes)
{
ModifiersSet modifierSet = dnode.getDefinition().getModifiers();
boolean isStatic = (modifierSet != null && modifierSet
.hasModifier(ASModifier.STATIC));
if ((dnode.getNodeID() == ASTNodeID.VariableID ||
dnode.getNodeID() == ASTNodeID.BindableVariableID))
{
IVariableNode varNode = (IVariableNode)dnode;
String ns = varNode.getNamespace();
boolean isConst = varNode.isConst();
if (isConst) {
//todo consider outputting consts, none output for now
continue;
}
//explicit exclusion from reflection data:
if (getModel().suppressedExportNodes.contains(varNode)) {
continue;
}
String altNS = null;
if (ns != null && EmitterUtils.isCustomNamespace(ns)) {
altNS = ((INamespaceDefinition)(((VariableNode) varNode).getNamespaceNode().resolve(getProject()))).getURI();
}
if (isInterface || (ns != null && ns.equals(IASKeywordConstants.PUBLIC )) || altNS != null)
{
name = varNode.getName();
IMetaTagsNode metaData = varNode.getMetaTags();
//first deal with 'Bindable' upgrades to getters/setters
if (!isInterface && bindableVars.containsKey(name)
&& bindableVars.get(name).namespace.equals(IASKeywordConstants.PUBLIC)) {
AccessorData bindableAccessor = new AccessorData();
bindableAccessor.customNS = altNS;
bindableAccessor.name = name;
bindableAccessor.access = "readwrite";
bindableAccessor.type = bindableVars.get(name).type;
bindableAccessor.declaredBy = fjs.formatQualifiedName(tnode.getQualifiedName(), true);
bindableAccessor.isStatic = isStatic;
//attribute the metadata from the var definition to the Bindable Accessor implementation
if (metaData != null)
{
IMetaTagNode[] tags = metaData.getAllTags();
if (tags.length > 0)
bindableAccessor.metaData = tags;
}
accessorData.add(bindableAccessor);
//skip processing this varNode as a variable, it has now be added as an accessor
continue;
}
VariableData data = new VariableData();
varData.add(data);
data.name = name;
data.customNS = altNS;
data.isStatic = isStatic;
String qualifiedTypeName = varNode.getVariableTypeNode().resolveType(getProject()).getQualifiedName();
data.type = fjs.formatQualifiedName(qualifiedTypeName, true);
if (metaData != null)
{
IMetaTagNode[] tags = metaData.getAllTags();
if (tags.length > 0)
{
data.metaData = tags;
for (IMetaTagNode tag : tags)
{
String tagName = tag.getTagName();
if (exportMetadata.contains(tagName))
{
if (data.isStatic)
exportSymbols.add(data.name);
else
exportProperties.add(data.name);
}
}
}
}
}
}
}
if (getModel().hasStaticBindableVars()) {
//we have an implicit implementation of a static event dispatcher
//so add the 'staticEventDispatcher' accessor to the reflection data
AccessorData staticEventDispatcher = new AccessorData();
staticEventDispatcher.name = BindableEmitter.STATIC_DISPATCHER_GETTER;
staticEventDispatcher.access = "readonly";
staticEventDispatcher.type = fjs.formatQualifiedName(BindableEmitter.DISPATCHER_CLASS_QNAME, true);
staticEventDispatcher.declaredBy = fjs.formatQualifiedName(tnode.getQualifiedName(), true);
staticEventDispatcher.isStatic = true;
accessorData.add(staticEventDispatcher);
}
HashMap<String, AccessorData> instanceAccessorMap = new HashMap<String, AccessorData>();
HashMap<String, AccessorData> staticAccessorMap = new HashMap<String, AccessorData>();
for (IDefinitionNode dnode : dnodes)
{
ModifiersSet modifierSet = dnode.getDefinition().getModifiers();
boolean isStatic = (modifierSet != null && modifierSet
.hasModifier(ASModifier.STATIC));
HashMap<String, AccessorData> accessorMap = isStatic ? staticAccessorMap : instanceAccessorMap;
if ((dnode.getNodeID() == ASTNodeID.GetterID ||
dnode.getNodeID() == ASTNodeID.SetterID))
{
IFunctionNode fnNode = (IFunctionNode)dnode;
String ns = fnNode.getNamespace();
boolean suppressed = getModel().suppressedExportNodes.contains(fnNode);
String altNS = null;
if (ns != null && EmitterUtils.isCustomNamespace(ns)) {
altNS = ((INamespaceDefinition)(((FunctionNode) fnNode).getNamespaceNode().resolve(getProject()))).getURI();
}
if (isInterface || (ns != null && ns.equals(IASKeywordConstants.PUBLIC)) || altNS != null)
{
String accessorName = fnNode.getName();
String nameKey = altNS!=null? altNS+accessorName : accessorName;
AccessorData data = accessorMap.get(nameKey);
if (data == null) {
if (suppressed) continue;
data = new AccessorData();
} else {
if (suppressed) {
accessorData.remove(data);
accessorMap.remove(nameKey);
continue;
}
}
data.name = accessorName;
data.customNS = altNS;
if (!accessorData.contains(data)) accessorData.add(data);
if (dnode.getNodeID() == ASTNodeID.GetterID) {
String qualifiedTypeName = fnNode.getReturnType();
if (!(qualifiedTypeName.equals("") || qualifiedTypeName.equals("void"))) {
qualifiedTypeName = fnNode.getReturnTypeNode().resolveType(getProject()).getQualifiedName();
}
data.type = fjs.formatQualifiedName(qualifiedTypeName, true);
if (data.access == null) {
data.access = "readonly";
} else data.access = "readwrite";
}
else {
data.type = ((SetterNode)fnNode).getVariableTypeNode().resolveType(getProject()).getQualifiedName();
if (data.access == null) {
data.access = "writeonly";
} else data.access = "readwrite";
}
accessorMap.put(nameKey, data);
data.type = fjs.formatQualifiedName(data.type, true);
IClassNode declarer = (IClassNode)fnNode.getAncestorOfType(IClassNode.class);
String declarant = fjs.formatQualifiedName(tnode.getQualifiedName(), true);
if (declarer != null)
declarant = fjs.formatQualifiedName(declarer.getQualifiedName(), true);
data.declaredBy = declarant;
data.isStatic = isStatic;
IMetaTagsNode metaData = fnNode.getMetaTags();
if (metaData != null)
{
IMetaTagNode[] tags = metaData.getAllTags();
if (tags.length > 0)
{
data.metaData = tags;
/* accessors don't need exportProp since they are referenced via the defineProp data structure
for (IMetaTagNode tag : tags)
{
String tagName = tag.getTagName();
if (exportMetadata.contains(tagName))
{
if (data.isStatic)
exportSymbols.add(data.name);
else
exportProperties.add(data.name);
}
}
*/
}
}
}
}
}
for (IDefinitionNode dnode : dnodes)
{
ModifiersSet modifierSet = dnode.getDefinition().getModifiers();
boolean isStatic = (modifierSet != null && modifierSet
.hasModifier(ASModifier.STATIC));
if (dnode.getNodeID() == ASTNodeID.FunctionID )
{
IFunctionNode fnNode = (IFunctionNode)dnode;
String ns = fnNode.getNamespace();
String altNS = null;
if (ns != null && EmitterUtils.isCustomNamespace(ns)) {
altNS = ((INamespaceDefinition)(((FunctionNode) fnNode).getNamespaceNode().resolve(getProject()))).getURI();
}
if (isInterface || (ns != null && ns.equals(IASKeywordConstants.PUBLIC)) || altNS != null)
{
if (getModel().suppressedExportNodes.contains(fnNode)) continue;
MethodData data = new MethodData();
data.isStatic = isStatic;
methodData.add(data);
data.name = fnNode.getName();
data.customNS = altNS;
String qualifiedTypeName = fnNode.getReturnType();
if (!(qualifiedTypeName.equals("") || qualifiedTypeName.equals("void"))) {
qualifiedTypeName = fnNode.getReturnTypeNode().resolveType(getProject()).getQualifiedName();
}
data.type = fjs.formatQualifiedName(qualifiedTypeName, true);
ITypeNode declarer;
if (isInterface)
declarer = (IInterfaceNode)fnNode.getAncestorOfType(IInterfaceNode.class);
else
declarer = (IClassNode)fnNode.getAncestorOfType(IClassNode.class);
String declarant = fjs.formatQualifiedName(tnode.getQualifiedName(), true);
if (declarer != null)
declarant = fjs.formatQualifiedName(declarer.getQualifiedName(), true);
data.declaredBy = declarant;
IMetaTagsNode metaData = fnNode.getMetaTags();
if (metaData != null)
{
IMetaTagNode[] tags = metaData.getAllTags();
if (tags.length > 0)
{
data.metaData = tags;
for (IMetaTagNode tag : tags)
{
String tagName = tag.getTagName();
if (exportMetadata.contains(tagName))
{
if (data.isStatic)
exportSymbols.add(data.name);
else
exportProperties.add(data.name);
}
}
}
}
IParameterNode[] paramNodes = fnNode.getParameterNodes();
if (paramNodes != null) {
data.parameters = paramNodes;
}
}
}
}
}