public void emit()

in compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/AccessorEmitter.java [81:741]


    public void emit(IClassDefinition definition)
    {
        // TODO (mschmalle) will remove this cast as more things get abstracted
        JSRoyaleEmitter fjs = (JSRoyaleEmitter) getEmitter();
        RoyaleJSProject project = (RoyaleJSProject)getWalker().getProject();
        boolean emitExports = true;
        if (project != null && project.config != null)
            emitExports = project.config.getExportPublicSymbols();

        if (!getModel().getPropertyMap().isEmpty())
        {
            String qname = definition.getQualifiedName();
            Set<String> propertyNames = getModel().getPropertyMap().keySet();
            for (String propName : propertyNames)
            {
                PropertyNodes p = getModel().getPropertyMap().get(propName);
                IGetterNode getterNode = p.getter;
                ISetterNode setterNode = p.setter;
                String baseName = p.name;
                if (getModel().isExterns)
                {
                	IAccessorNode node = (getterNode != null) ? getterNode : setterNode;
                    writeNewline();
                    writeNewline();
                    writeNewline();
                	writeNewline("/**");
                    if (emitExports)
                    	writeNewline(" * @export");
                    if (p.type != null)
                    	writeNewline(" * @type {"+ JSGoogDocEmitter.convertASTypeToJSType(p.type.getBaseName(), p.type.getPackageName()) + "}");
                    writeNewline(" */");
                    write(getEmitter().formatQualifiedName(qname));
                    write(ASEmitterTokens.MEMBER_ACCESS);
                    write(JSEmitterTokens.PROTOTYPE);
                    if (p.uri != null)
                    {
            			INamespaceDecorationNode ns = ((FunctionNode)node).getActualNamespaceNode();
            			INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
            			fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names
            			write(JSRoyaleEmitter.formatNamespacedProperty(p.uri, baseName, true));
                    }
                    else
                    {
                        write(ASEmitterTokens.MEMBER_ACCESS);
                    	write(baseName);
                    }
                    write(ASEmitterTokens.SEMICOLON);
                }
                else
                {
                    IAccessorNode accessorNode = (getterNode != null) ? getterNode : setterNode;
                    if(!accessorNode.getDefinition().isOverride())
                    {
                        // start by writing out the instance accessors as regular variables
                        // because Closure Compiler doesn't properly analyze calls to
                        // defineProperties() alone.
                        // since there's no analysis, Closure assumes that getters/setters
                        // have no side effects, which results in important get/set calls
                        // being removed as dead code.
                        // defining the accessors as variables first convinces Closure to
                        // handle them more intelligently while not preventing them from
                        // being real accessors.
                        // Source: https://developers.google.com/closure/compiler/docs/limitations
                        writeNewline();
                        writeNewline();
                        writeNewline();
                        writeNewline("/**");
                        if (p.preventRename)
                            writeNewline(" * @nocollapse");
                        if (p.resolvedExport && !p.suppressExport)
                            writeNewline(" * @export");
                        if (p.type != null)
                            writeNewline(" * @type {" + JSGoogDocEmitter.convertASTypeToJSType(p.type.getBaseName(), p.type.getPackageName()) + "}"); 
                        writeNewline(" */");
                        write(getEmitter().formatQualifiedName(qname));
                        write(ASEmitterTokens.MEMBER_ACCESS);
                        write(JSEmitterTokens.PROTOTYPE);
                        write(ASEmitterTokens.MEMBER_ACCESS);
                        if (p.uri != null)
                        {
                            INamespaceDecorationNode ns = ((FunctionNode) accessorNode).getActualNamespaceNode();
                            INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
                            fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names
                            write(JSRoyaleEmitter.formatNamespacedProperty(p.uri, baseName, false));
                        }
                        else
                            write(baseName);
                        write(ASEmitterTokens.SEMICOLON);
                    }

                    if (getterNode != null)
	                {
	                    writeNewline();
	                    writeNewline();
	                    writeNewline();
	                    write(getEmitter().formatQualifiedName(qname));
	                    write(ASEmitterTokens.MEMBER_ACCESS);
	                    write(JSEmitterTokens.PROTOTYPE);
	                    if (p.uri != null)
	                    {
	            			INamespaceDecorationNode ns = ((FunctionNode)getterNode).getActualNamespaceNode();
	            			INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
	            			fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names
	            			write(JSRoyaleEmitter.formatNamespacedProperty(p.uri, fjs.formatGetter(baseName), true));
	                    }
	                    else
	                    {
	                        write(ASEmitterTokens.MEMBER_ACCESS);
                            write(fjs.formatGetter(baseName));
	                    }
	                    write(ASEmitterTokens.SPACE);
	                    write(ASEmitterTokens.EQUAL);
	                    write(ASEmitterTokens.SPACE);
	                    write(ASEmitterTokens.FUNCTION);
	                    fjs.emitParameters(getterNode.getParametersContainerNode());
	
	                    fjs.emitDefinePropertyFunction(getterNode);
	                                        
	                    write(ASEmitterTokens.SEMICOLON);
	                }
	                if (setterNode != null)
	                {
						boolean isClassBindable = BindableHelper.isClassCodeGenBindable(definition);

	                	boolean isBindable = false;                
	                	IAccessorDefinition setterDef = (IAccessorDefinition)setterNode.getDefinition();
	                	IAccessorDefinition getterDef = null;
	                	if (getterNode != null)
	                		getterDef = (IAccessorDefinition)getterNode.getDefinition();
	                	if ((getterDef != null && (setterDef.isBindable() || getterDef.isBindable())))
	                	{
							boolean foundExplicitBindableTag = false;
	                		if (setterDef.isBindable())
	                		{

								isBindable = BindableHelper.isCodeGenBindableMember(setterDef, isClassBindable);
								foundExplicitBindableTag = BindableHelper.hasExplicitBindable(setterDef);
	                		}
	                		if (getterDef.isBindable())
	                		{

								isBindable = isBindable || BindableHelper.isCodeGenBindableMember(getterDef, isClassBindable);
								foundExplicitBindableTag = foundExplicitBindableTag || BindableHelper.hasExplicitBindable(getterDef);

	                		}

							if (isClassBindable) {
								//if we 'foundExplicitBindableTag' such as [Bindable(event='someEvent')], then nothing else matters, even another [Bindable] tag is ignored (Flex)
								isBindable = !foundExplicitBindableTag;
							}
	                	}
	                    writeNewline();
	                    writeNewline();
	                    writeNewline();
	                    write(getEmitter().formatQualifiedName(qname));
	                    write(ASEmitterTokens.MEMBER_ACCESS);
	                    write(JSEmitterTokens.PROTOTYPE);
	                    if (p.uri != null)
	                    {
	            			INamespaceDecorationNode ns = ((FunctionNode)setterNode).getActualNamespaceNode();
	            			INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
	            			fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names
	            			write(JSRoyaleEmitter.formatNamespacedProperty(p.uri, fjs.formatSetter(baseName), true));
	                    }
	                    else
	                    {
	                        write(ASEmitterTokens.MEMBER_ACCESS);
	                        if (isBindable) {
								write(JSRoyaleEmitterTokens.BINDABLE_PREFIX);
                                write(fjs.formatSetter(fjs.formatPrivateName(definition.getQualifiedName(), baseName, true)));
							} else {
                                write(fjs.formatSetter(baseName));
							}
	                    }
	                    write(ASEmitterTokens.SPACE);
	                    write(ASEmitterTokens.EQUAL);
	                    write(ASEmitterTokens.SPACE);
	                    write(ASEmitterTokens.FUNCTION);
	                    fjs.emitParameters(setterNode.getParametersContainerNode());
	
	                    fjs.emitDefinePropertyFunction(setterNode);
	                    
	                    write(ASEmitterTokens.SEMICOLON);
	                    
	                    if (isBindable)
	                    {
	                    	writeNewline();
	                    	writeNewline();
	                    	writeNewline();
	                        write(getEmitter().formatQualifiedName(qname));
	                        write(ASEmitterTokens.MEMBER_ACCESS);
	                        write(JSEmitterTokens.PROTOTYPE);
	                        write(ASEmitterTokens.MEMBER_ACCESS);
                            write(fjs.formatSetter(baseName));
	                        write(ASEmitterTokens.SPACE);
	                        write(ASEmitterTokens.EQUAL);
	                        write(ASEmitterTokens.SPACE);
	                        write(ASEmitterTokens.FUNCTION);
	                        write(ASEmitterTokens.PAREN_OPEN);
	                        write("value");
	                        write(ASEmitterTokens.PAREN_CLOSE);
	                        write(ASEmitterTokens.SPACE);
	                        writeNewline(ASEmitterTokens.BLOCK_OPEN);
	                        write(ASEmitterTokens.VAR);
	                        write(ASEmitterTokens.SPACE);
	                        write("oldValue");
	                        write(ASEmitterTokens.SPACE);
	                        write(ASEmitterTokens.EQUAL);
	                        write(ASEmitterTokens.SPACE);
	                        write(ASEmitterTokens.THIS);
	                        write(ASEmitterTokens.MEMBER_ACCESS);
	                        write(fjs.formatGetter(baseName));
	                        write(ASEmitterTokens.PAREN_OPEN);
	                        write(ASEmitterTokens.PAREN_CLOSE);
	                        writeNewline(ASEmitterTokens.SEMICOLON);
	                        write(ASEmitterTokens.IF);
	                        write(ASEmitterTokens.SPACE);
	                        write(ASEmitterTokens.PAREN_OPEN);
	                        write("oldValue != value");
	                        write(ASEmitterTokens.PAREN_CLOSE);
	                        write(ASEmitterTokens.SPACE);
	                        writeNewline(ASEmitterTokens.BLOCK_OPEN);
	                        write(ASEmitterTokens.THIS);
	                        write(ASEmitterTokens.MEMBER_ACCESS);
	                        write(JSRoyaleEmitterTokens.BINDABLE_PREFIX);
                            write(fjs.formatSetter(fjs.formatPrivateName(definition.getQualifiedName(), baseName, true)));
	                        write(ASEmitterTokens.PAREN_OPEN);
	                        write("value");
	                        write(ASEmitterTokens.PAREN_CLOSE);
	                        writeNewline(ASEmitterTokens.SEMICOLON);
	                        writeNewline("    this.dispatchEvent("+fjs.formatQualifiedName(BindableEmitter.VALUECHANGE_EVENT_QNAME)+".createUpdateEvent(");
	                        writeNewline("         this, \"" + p.originalName + "\", oldValue, value));");
	                        writeNewline(ASEmitterTokens.BLOCK_CLOSE);
	                        write(ASEmitterTokens.BLOCK_CLOSE);
	                        write(ASEmitterTokens.SEMICOLON);                        
	                        
	                    }
	                }
                }
            }
        }
        if (!getModel().getPropertyMap().isEmpty() && !getModel().isExterns)
        {
            writeNewline();
            writeNewline();
            writeNewline();
            write(JSGoogEmitterTokens.OBJECT);
            write(ASEmitterTokens.MEMBER_ACCESS);
            write(JSEmitterTokens.DEFINE_PROPERTIES);
            write(ASEmitterTokens.PAREN_OPEN);
            String qname = definition.getQualifiedName();
            write(getEmitter().formatQualifiedName(qname));
            write(ASEmitterTokens.MEMBER_ACCESS);
            write(JSEmitterTokens.PROTOTYPE);
            write(ASEmitterTokens.COMMA);
            write(ASEmitterTokens.SPACE);
            write("/** @lends {" + getEmitter().formatQualifiedName(qname)
                    + ".prototype} */ ");
            writeNewline(ASEmitterTokens.BLOCK_OPEN);

            Set<String> propertyNames = getModel().getPropertyMap().keySet();
            boolean firstTime = true;
            for (String propName : propertyNames)
            {
                if (firstTime)
                    firstTime = false;
                else
                    writeNewline(ASEmitterTokens.COMMA);

                boolean wroteGetter = false;
                PropertyNodes p = getModel().getPropertyMap().get(propName);
                String baseName = p.name;
                IGetterNode getterNode = p.getter;
                ISetterNode setterNode = p.setter;
                writeNewline("/**");
                if (p.type != null)
                {
                	String typeName = p.type.getBaseName();
                	if (getModel().isInternalClass(typeName))
    					typeName = getModel().getInternalClasses().get(typeName);
					writeNewline(" * @type {" + JSGoogDocEmitter.convertASTypeToJSType(typeName, p.type.getPackageName()) + "}");
                }
                writeNewline(" */");
                FunctionNode fnNode = getterNode != null ? (FunctionNode) getterNode : (FunctionNode) setterNode;
                if (p.uri != null)
                {
        			INamespaceDecorationNode ns = fnNode.getActualNamespaceNode();
        			INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
        			fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names 
        			//String s = nsDef.getURI();
        			write(JSRoyaleEmitter.formatNamespacedProperty(p.uri, baseName, false));
                }
                else
                	write(baseName);
                write(ASEmitterTokens.COLON);
                write(ASEmitterTokens.SPACE);
                write(ASEmitterTokens.BLOCK_OPEN);
                writeNewline();
                if (getterNode != null)
                {
                    write(ASEmitterTokens.GET);
                    write(ASEmitterTokens.COLON);
                    write(ASEmitterTokens.SPACE);
                    write(getEmitter().formatQualifiedName(qname));
                    write(ASEmitterTokens.MEMBER_ACCESS);
                    write(JSEmitterTokens.PROTOTYPE);
                    if (p.uri != null)
                    {
            			INamespaceDecorationNode ns = ((FunctionNode)getterNode).getActualNamespaceNode();
            			INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
            			fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names 
            			//String s = nsDef.getURI();
            			write(JSRoyaleEmitter.formatNamespacedProperty(p.uri, fjs.formatGetter(baseName), true));
                    }
                    else
                    {
                        write(ASEmitterTokens.MEMBER_ACCESS);
                        write(fjs.formatGetter(baseName));
                    }
                    wroteGetter = true;
                }
                else if (setterNode != null /* && setterNode.getDefinition().isOverride()*/)
                {
                	// see if there is a getter on a base class.  If so, we have to 
                	// generate a call to the super from this class because 
                	// Object.defineProperty doesn't allow overriding just the setter.
                	// If there is no getter defineProp'd the property will seen as
                	// write-only.
                	IAccessorDefinition other = (IAccessorDefinition)SemanticUtils.resolveCorrespondingAccessor(p.setter.getDefinition(), getProject());
                	if (other != null)
                	{
                        write(ASEmitterTokens.GET);
                        write(ASEmitterTokens.COLON);
                        write(ASEmitterTokens.SPACE);
                        
                        write(getEmitter().formatQualifiedName(other.getParent().getQualifiedName()));
                        write(ASEmitterTokens.MEMBER_ACCESS);
                        write(JSEmitterTokens.PROTOTYPE);
                        if (p.uri != null)
                        {
                			INamespaceDecorationNode ns = ((FunctionNode)setterNode).getActualNamespaceNode();
                			INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
                			fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names 
                			//String s = nsDef.getURI();
                			write(JSRoyaleEmitter.formatNamespacedProperty(p.uri, fjs.formatGetter(baseName), true));
                        }
                        else
                        {
                            write(ASEmitterTokens.MEMBER_ACCESS);
                            write(fjs.formatGetter(baseName));
                        }
                        wroteGetter = true;
                	}
                }
                if (setterNode != null)
                {
                    if (wroteGetter)
                        writeNewline(ASEmitterTokens.COMMA);

                    write(ASEmitterTokens.SET);
                    write(ASEmitterTokens.COLON);
                    write(ASEmitterTokens.SPACE);
                    write(getEmitter().formatQualifiedName(qname));
                    write(ASEmitterTokens.MEMBER_ACCESS);
                    write(JSEmitterTokens.PROTOTYPE);
                    if (p.uri != null)
                    {
            			INamespaceDecorationNode ns = ((FunctionNode)setterNode).getActualNamespaceNode();
            			INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
            			fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names 
            			//String s = nsDef.getURI();
            			write(JSRoyaleEmitter.formatNamespacedProperty(p.uri, fjs.formatSetter(baseName), true));
                    }
                    else
                    {
                        write(ASEmitterTokens.MEMBER_ACCESS);
                        write(fjs.formatSetter(baseName));
                    }
                }
                else if (getterNode != null/* && getterNode.getDefinition().isOverride()*/)
                {
                	// see if there is a getter on a base class.  If so, we have to 
                	// generate a call to the super from this class because 
                	// Object.defineProperty doesn't allow overriding just the getter.
                	// If there is no setter defineProp'd the property will seen as
                	// read-only.
                	IAccessorDefinition other = (IAccessorDefinition)SemanticUtils.resolveCorrespondingAccessor(p.getter.getDefinition(), getProject());
                	if (other != null)
                	{
                        if (wroteGetter)
                            writeNewline(ASEmitterTokens.COMMA);

                        write(ASEmitterTokens.SET);
                        write(ASEmitterTokens.COLON);
                        write(ASEmitterTokens.SPACE);
                        write(getEmitter().formatQualifiedName(other.getParent().getQualifiedName()));
                        write(ASEmitterTokens.MEMBER_ACCESS);
                        write(JSEmitterTokens.PROTOTYPE);
                        if (p.uri != null)
                        {
                			INamespaceDecorationNode ns = ((FunctionNode)getterNode).getActualNamespaceNode();
                			INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
                			fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names 
                			//String s = nsDef.getURI();
                			write(JSRoyaleEmitter.formatNamespacedProperty(p.uri, fjs.formatSetter(baseName), true));
                        }
                        else
                        {
                            write(ASEmitterTokens.MEMBER_ACCESS);
                            write(fjs.formatSetter(baseName));
                        }
                	}
                }
                write(ASEmitterTokens.BLOCK_CLOSE);
            }
            writeNewline(ASEmitterTokens.BLOCK_CLOSE);
            write(ASEmitterTokens.PAREN_CLOSE);
            write(ASEmitterTokens.SEMICOLON);
        }
        if (!getModel().getStaticPropertyMap().isEmpty())
        {
            String qname = definition.getQualifiedName();
            Set<String> propertyNames = getModel().getStaticPropertyMap().keySet();
            for (String propName : propertyNames)
            {
                PropertyNodes p = getModel().getStaticPropertyMap().get(propName);
                IGetterNode getterNode = p.getter;
                ISetterNode setterNode = p.setter;
                String baseName = p.name;
                if (getModel().isExterns)
                {
                	IAccessorNode node = (getterNode != null) ? getterNode : setterNode;
                    writeNewline();
                    writeNewline();
                    writeNewline();
                    writeNewline("/**");
                    if (emitExports)
                    	writeNewline(" * @export");
                    if (p.type != null)
                    	writeNewline(" * @type {" + JSGoogDocEmitter.convertASTypeToJSType(p.type.getBaseName(), p.type.getPackageName()) + "}");
                    writeNewline(" */");
                    write(getEmitter().formatQualifiedName(qname));
                    if (p.uri != null)
                    {
            			INamespaceDecorationNode ns = ((FunctionNode)node).getActualNamespaceNode();
            			INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
            			fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names 
            			String s = nsDef.getURI();
            			write(JSRoyaleEmitter.formatNamespacedProperty(p.uri, baseName, true));
                    }
                    else
                    {
                        write(ASEmitterTokens.MEMBER_ACCESS);
                    	write(baseName);
                    }
                    write(ASEmitterTokens.SEMICOLON);                	
                }
                else
                {
                    // start by writing out the static accessors as regular variables
                    // because Closure Compiler doesn't properly analyze calls to
                    // defineProperties() alone.
                    // since there's no analysis, Closure assumes that getters/setters
                    // have no side effects, which results in important get/set calls
                    // being removed as dead code.
                    // defining the accessors as variables first convinces Closure to
                    // handle them more intelligently while not preventing them from
                    // being real accessors.
                    // Source: https://developers.google.com/closure/compiler/docs/limitations
                    writeNewline();
                    writeNewline();
                    writeNewline();
                    writeNewline("/**");
                    // like instance accessors, we should have if (p.preventRename)
                    // here, but while Closure compiler seems to properly handle
                    // renaming of instance accessors, it fails when we try the same
                    // trick with static accessors, unless there's a nocollapse.
                    // when we allow renaming, we don't want to break anything that
                    // isn't dynamic access, so we always need nocollapse here.
                    writeNewline(" * @nocollapse");
                    if (p.resolvedExport && !p.suppressExport)
                        writeNewline(" * @export");
                    if (p.type != null)
                        writeNewline(" * @type {" + JSGoogDocEmitter.convertASTypeToJSType(p.type.getBaseName(), p.type.getPackageName()) + "}"); 
                    writeNewline(" */");
                    write(getEmitter().formatQualifiedName(qname));
                    write(ASEmitterTokens.MEMBER_ACCESS);
                    if (p.uri != null)
                    {
                        IAccessorNode node = (getterNode != null) ? getterNode : setterNode;
                        INamespaceDecorationNode ns = ((FunctionNode)node).getActualNamespaceNode();
                        INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
                        fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names
                        write(JSRoyaleEmitter.formatNamespacedProperty(p.uri, baseName, false));
                    }
                    else
                        write(baseName);
                    write(ASEmitterTokens.SEMICOLON);

                    if (getterNode != null)
	                {
	                    writeNewline();
	                    writeNewline();
	                    writeNewline();
	                    write(getEmitter().formatQualifiedName(qname));
	                    if (p.uri != null)
	                    {
	            			INamespaceDecorationNode ns = ((FunctionNode)getterNode).getActualNamespaceNode();
	            			INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
	            			fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names 
	            			//String s = nsDef.getURI();
	            			write(JSRoyaleEmitter.formatNamespacedProperty(p.uri , fjs.formatGetter(baseName), true));
	                    }
	                    else
	                    {
	                        write(ASEmitterTokens.MEMBER_ACCESS);
	                        write(fjs.formatGetter(baseName));
	                    }
	                    write(ASEmitterTokens.SPACE);
	                    write(ASEmitterTokens.EQUAL);
	                    write(ASEmitterTokens.SPACE);
	                    write(ASEmitterTokens.FUNCTION);
	                    fjs.emitParameters(getterNode.getParametersContainerNode());
	
	                    fjs.emitDefinePropertyFunction(getterNode);
	                    
	                    write(ASEmitterTokens.SEMICOLON);
	                }
	                if (setterNode != null)
	                {
	                    writeNewline();
	                    writeNewline();
	                    writeNewline();
	                    write(getEmitter().formatQualifiedName(qname));
	                    if (p.uri != null)
	                    {
	            			INamespaceDecorationNode ns = ((FunctionNode)setterNode).getActualNamespaceNode();
	            			INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
	            			fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names 
	            			//String s = nsDef.getURI();
	            			write(JSRoyaleEmitter.formatNamespacedProperty(p.uri, fjs.formatSetter(baseName), true));
	                    }
	                    else
	                    {
	                        write(ASEmitterTokens.MEMBER_ACCESS);
                            write(fjs.formatSetter(baseName));
	                    }
	                    write(ASEmitterTokens.SPACE);
	                    write(ASEmitterTokens.EQUAL);
	                    write(ASEmitterTokens.SPACE);
	                    write(ASEmitterTokens.FUNCTION);
	                    fjs.emitParameters(setterNode.getParametersContainerNode());
	
	                    fjs.emitDefinePropertyFunction(setterNode);
	                    
	                    write(ASEmitterTokens.SEMICOLON);
	                }
                }
            }
        }
        if (!getModel().getStaticPropertyMap().isEmpty() && !getModel().isExterns)
        {
            writeNewline();
            writeNewline();
            writeNewline();
            write(JSGoogEmitterTokens.OBJECT);
            write(ASEmitterTokens.MEMBER_ACCESS);
            write(JSEmitterTokens.DEFINE_PROPERTIES);
            write(ASEmitterTokens.PAREN_OPEN);
            String qname = definition.getQualifiedName();
            write(getEmitter().formatQualifiedName(qname));
            write(ASEmitterTokens.COMMA);
            write(ASEmitterTokens.SPACE);
            write("/** @lends {" + getEmitter().formatQualifiedName(qname)
                    + "} */ ");
            writeNewline(ASEmitterTokens.BLOCK_OPEN);

            Set<String> propertyNames = getModel().getStaticPropertyMap()
                    .keySet();
            boolean firstTime = true;
            for (String propName : propertyNames)
            {
                if (firstTime)
                    firstTime = false;
                else
                    writeNewline(ASEmitterTokens.COMMA);

                PropertyNodes p = getModel().getStaticPropertyMap().get(
                        propName);
                IGetterNode getterNode = p.getter;
                ISetterNode setterNode = p.setter;
                String baseName = p.name;
            	writeNewline("/**");
                if (p.type != null)
                	writeNewline(" * @type {" + JSGoogDocEmitter.convertASTypeToJSType(p.type.getBaseName(), p.type.getPackageName()) + "}");
                writeNewline(" */");
				FunctionNode fnNode = getterNode != null ? (FunctionNode) getterNode : (FunctionNode) setterNode;
				if (p.uri != null)
				{
					INamespaceDecorationNode ns = fnNode.getActualNamespaceNode();
					INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
					fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names
					//String s = nsDef.getURI();
					write(JSRoyaleEmitter.formatNamespacedProperty(p.uri, baseName, false));
				}
				else
					write(baseName);
                write(ASEmitterTokens.COLON);
                write(ASEmitterTokens.SPACE);
                write(ASEmitterTokens.BLOCK_OPEN);
                writeNewline();
                if (getterNode != null)
                {
                    write(ASEmitterTokens.GET);
                    write(ASEmitterTokens.COLON);
                    write(ASEmitterTokens.SPACE);
                    write(getEmitter().formatQualifiedName(qname));
                    if (p.uri != null)
                    {
            			INamespaceDecorationNode ns = ((FunctionNode)getterNode).getActualNamespaceNode();
            			INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
            			fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names 
            			//String s = nsDef.getURI();
            			write(JSRoyaleEmitter.formatNamespacedProperty(p.uri, fjs.formatGetter(baseName), true));
                    }
                    else
                    {
                        write(ASEmitterTokens.MEMBER_ACCESS);
                        write(fjs.formatGetter(baseName));
                    }
                }
                if (setterNode != null)
                {
                    if (p.getter != null)
                        writeNewline(ASEmitterTokens.COMMA);

                    write(ASEmitterTokens.SET);
                    write(ASEmitterTokens.COLON);
                    write(ASEmitterTokens.SPACE);
                    write(getEmitter().formatQualifiedName(qname));
                    if (p.uri != null)
                    {
            			INamespaceDecorationNode ns = ((FunctionNode)setterNode).getActualNamespaceNode();
            			INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project);
            			fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names 
            			//String s = nsDef.getURI();
            			write(JSRoyaleEmitter.formatNamespacedProperty(p.uri, fjs.formatSetter(baseName), true));
                    }
                    else
                    {
                        write(ASEmitterTokens.MEMBER_ACCESS);
                        write(fjs.formatSetter(baseName));
                    }
                }
                write(ASEmitterTokens.BLOCK_CLOSE);
            }
            writeNewline(ASEmitterTokens.BLOCK_CLOSE);
            write(ASEmitterTokens.PAREN_CLOSE);
            write(ASEmitterTokens.SEMICOLON);
        }
    }