You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by ft...@apache.org on 2015/06/02 14:42:36 UTC

[29/35] git commit: [flex-falcon] [refs/heads/IDEA-FLEX_JS_COMPILER] - - Refactored define property function into emitter. - Refactored object define property into emitter.

- Refactored define property function into emitter.
- Refactored object define property into emitter.


Project: http://git-wip-us.apache.org/repos/asf/flex-falcon/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-falcon/commit/0ca46d2a
Tree: http://git-wip-us.apache.org/repos/asf/flex-falcon/tree/0ca46d2a
Diff: http://git-wip-us.apache.org/repos/asf/flex-falcon/diff/0ca46d2a

Branch: refs/heads/IDEA-FLEX_JS_COMPILER
Commit: 0ca46d2aac7fe728c455e3cd1ee561cbd71d18af
Parents: e11ef01
Author: Michael Schmalle <ms...@apache.org>
Authored: Sun May 31 15:29:52 2015 -0400
Committer: Frédéric THOMAS <we...@gmail.com>
Committed: Tue Jun 2 13:41:28 2015 +0100

----------------------------------------------------------------------
 .../codegen/js/flexjs/JSFlexJSEmitter.java      | 138 ++-------------
 .../internal/codegen/js/goog/JSGoogEmitter.java |   2 +
 .../js/jx/DefinePropertyFunctionEmitter.java    | 120 ++++++++++++++
 .../js/jx/ObjectDefinePropertyEmitter.java      | 166 +++++++++++++++++++
 4 files changed, 299 insertions(+), 127 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/0ca46d2a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
index 66a5731..78f1f0b 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
@@ -23,13 +23,8 @@ import java.io.FilterWriter;
 
 import org.apache.flex.compiler.codegen.js.flexjs.IJSFlexJSEmitter;
 import org.apache.flex.compiler.codegen.js.goog.IJSGoogDocEmitter;
-import org.apache.flex.compiler.common.ASModifier;
-import org.apache.flex.compiler.common.IMetaInfo;
-import org.apache.flex.compiler.definitions.IFunctionDefinition;
 import org.apache.flex.compiler.definitions.IPackageDefinition;
-import org.apache.flex.compiler.definitions.ITypeDefinition;
 import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
-import org.apache.flex.compiler.internal.codegen.js.JSEmitterTokens;
 import org.apache.flex.compiler.internal.codegen.js.goog.JSGoogEmitter;
 import org.apache.flex.compiler.internal.codegen.js.goog.JSGoogEmitterTokens;
 import org.apache.flex.compiler.internal.codegen.js.jx.AccessorEmitter;
@@ -37,6 +32,7 @@ import org.apache.flex.compiler.internal.codegen.js.jx.AsIsEmitter;
 import org.apache.flex.compiler.internal.codegen.js.jx.BinaryOperatorEmitter;
 import org.apache.flex.compiler.internal.codegen.js.jx.BindableEmitter;
 import org.apache.flex.compiler.internal.codegen.js.jx.ClassEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.DefinePropertyFunctionEmitter;
 import org.apache.flex.compiler.internal.codegen.js.jx.FieldEmitter;
 import org.apache.flex.compiler.internal.codegen.js.jx.ForEachEmitter;
 import org.apache.flex.compiler.internal.codegen.js.jx.FunctionCallEmitter;
@@ -44,13 +40,12 @@ import org.apache.flex.compiler.internal.codegen.js.jx.IdentifierEmitter;
 import org.apache.flex.compiler.internal.codegen.js.jx.InterfaceEmitter;
 import org.apache.flex.compiler.internal.codegen.js.jx.MemberAccessEmitter;
 import org.apache.flex.compiler.internal.codegen.js.jx.MethodEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.ObjectDefinePropertyEmitter;
 import org.apache.flex.compiler.internal.codegen.js.jx.PackageFooterEmitter;
 import org.apache.flex.compiler.internal.codegen.js.jx.PackageHeaderEmitter;
 import org.apache.flex.compiler.internal.codegen.js.jx.SuperCallEmitter;
 import org.apache.flex.compiler.internal.codegen.js.jx.VarDeclarationEmitter;
-import org.apache.flex.compiler.internal.tree.as.FunctionNode;
 import org.apache.flex.compiler.internal.tree.as.RegExpLiteralNode;
-import org.apache.flex.compiler.internal.tree.as.SetterNode;
 import org.apache.flex.compiler.tree.ASTNodeID;
 import org.apache.flex.compiler.tree.as.IASNode;
 import org.apache.flex.compiler.tree.as.IAccessorNode;
@@ -67,7 +62,6 @@ import org.apache.flex.compiler.tree.as.IInterfaceNode;
 import org.apache.flex.compiler.tree.as.ILiteralNode;
 import org.apache.flex.compiler.tree.as.ILiteralNode.LiteralType;
 import org.apache.flex.compiler.tree.as.IMemberAccessExpressionNode;
-import org.apache.flex.compiler.tree.as.IParameterNode;
 import org.apache.flex.compiler.tree.as.ISetterNode;
 import org.apache.flex.compiler.tree.as.ITypedExpressionNode;
 import org.apache.flex.compiler.tree.as.IVariableNode;
@@ -100,10 +94,13 @@ public class JSFlexJSEmitter extends JSGoogEmitter implements IJSFlexJSEmitter
     private SuperCallEmitter superCallEmitter;
     private ForEachEmitter forEachEmitter;
     private MemberAccessEmitter memberAccessEmitter;
-    private AsIsEmitter asIsEmitter;
     private BinaryOperatorEmitter binaryOperatorEmitter;
     private IdentifierEmitter identifierEmitter;
 
+    private AsIsEmitter asIsEmitter;
+    private ObjectDefinePropertyEmitter objectDefinePropertyEmitter;
+    private DefinePropertyFunctionEmitter definePropertyFunctionEmitter;
+
     public BindableEmitter getBindableEmitter()
     {
         return bindableEmitter;
@@ -152,6 +149,9 @@ public class JSFlexJSEmitter extends JSGoogEmitter implements IJSFlexJSEmitter
         asIsEmitter = new AsIsEmitter(this);
         binaryOperatorEmitter = new BinaryOperatorEmitter(this);
         identifierEmitter = new IdentifierEmitter(this);
+
+        objectDefinePropertyEmitter = new ObjectDefinePropertyEmitter(this);
+        definePropertyFunctionEmitter = new DefinePropertyFunctionEmitter(this);
     }
 
     @Override
@@ -384,128 +384,12 @@ public class JSFlexJSEmitter extends JSGoogEmitter implements IJSFlexJSEmitter
     @Override
     protected void emitObjectDefineProperty(IAccessorNode node)
     {
-        //TODO: ajh  is this method needed anymore?
-
-        FunctionNode fn = (FunctionNode) node;
-        fn.parseFunctionBody(getProblems());
-
-        IFunctionDefinition definition = node.getDefinition();
-        ITypeDefinition type = (ITypeDefinition) definition.getParent();
-
-        // ToDo (erikdebruin): add VF2JS conditional -> only use check during full SDK compilation
-        if (type == null)
-            return;
-
-        boolean isBindableSetter = false;
-        if (node instanceof SetterNode)
-        {
-            IMetaInfo[] metaInfos = null;
-            metaInfos = node.getMetaInfos();
-            for (IMetaInfo metaInfo : metaInfos)
-            {
-                String name = metaInfo.getTagName();
-                if (name.equals("Bindable")
-                        && metaInfo.getAllAttributes().length == 0)
-                {
-                    isBindableSetter = true;
-                    break;
-                }
-            }
-        }
-        if (isBindableSetter)
-        {
-            getDocEmitter().emitMethodDoc(fn, getWalker().getProject());
-            write(formatQualifiedName(type.getQualifiedName()));
-            if (!node.hasModifier(ASModifier.STATIC))
-            {
-                write(ASEmitterTokens.MEMBER_ACCESS);
-                write(JSEmitterTokens.PROTOTYPE);
-            }
-
-            write(ASEmitterTokens.MEMBER_ACCESS);
-            write("__bindingWrappedSetter__");
-            writeToken(node.getName());
-            writeToken(ASEmitterTokens.EQUAL);
-            write(ASEmitterTokens.FUNCTION);
-            emitParameters(node.getParameterNodes());
-            //writeNewline();
-            emitMethodScope(node.getScopedNode());
-        }
-        super.emitObjectDefineProperty(node);
+        objectDefinePropertyEmitter.emit(node);
     }
 
     @Override
     public void emitDefinePropertyFunction(IAccessorNode node)
     {
-        boolean isBindableSetter = false;
-        if (node instanceof SetterNode)
-        {
-            IMetaInfo[] metaInfos = null;
-            metaInfos = node.getMetaInfos();
-            for (IMetaInfo metaInfo : metaInfos)
-            {
-                String name = metaInfo.getTagName();
-                if (name.equals("Bindable")
-                        && metaInfo.getAllAttributes().length == 0)
-                {
-                    isBindableSetter = true;
-                    break;
-                }
-            }
-        }
-        if (isBindableSetter)
-        {
-            //write(ASEmitterTokens.FUNCTION);
-            //emitParameters(node.getParameterNodes());
-            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(node.getName());
-            //write(ASEmitterTokens.PAREN_OPEN);
-            //write(ASEmitterTokens.PAREN_CLOSE);
-            writeNewline(ASEmitterTokens.SEMICOLON);
-
-            // add change check
-            write(ASEmitterTokens.IF);
-            write(ASEmitterTokens.SPACE);
-            write(ASEmitterTokens.PAREN_OPEN);
-            write("oldValue");
-            write(ASEmitterTokens.SPACE);
-            write(ASEmitterTokens.STRICT_EQUAL);
-            write(ASEmitterTokens.SPACE);
-            IParameterNode[] params = node.getParameterNodes();
-            write(params[0].getName());
-            write(ASEmitterTokens.PAREN_CLOSE);
-            write(ASEmitterTokens.SPACE);
-            write(ASEmitterTokens.RETURN);
-            writeNewline(ASEmitterTokens.SEMICOLON);
-
-            write(ASEmitterTokens.THIS);
-            write(ASEmitterTokens.MEMBER_ACCESS);
-            write("__bindingWrappedSetter__" + node.getName());
-            write(ASEmitterTokens.PAREN_OPEN);
-            write(params[0].getName());
-            write(ASEmitterTokens.PAREN_CLOSE);
-            writeNewline(ASEmitterTokens.SEMICOLON);
-
-            // add dispatch of change event
-            writeNewline("    this.dispatchEvent(org_apache_flex_events_ValueChangeEvent.createUpdateEvent(");
-            writeNewline("         this, \"" + node.getName()
-                    + "\", oldValue, " + params[0].getName() + "));");
-            write(ASEmitterTokens.BLOCK_CLOSE);
-            //writeNewline(ASEmitterTokens.SEMICOLON);
-            writeNewline();
-            writeNewline();
-        }
-        else
-            super.emitDefinePropertyFunction(node);
+        definePropertyFunctionEmitter.emit(node);
     }
 }

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/0ca46d2a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogEmitter.java
index df64740..12bfb7e 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogEmitter.java
@@ -912,6 +912,7 @@ public class JSGoogEmitter extends JSEmitter implements IJSGoogEmitter
         super(out);
     }
 
+    // XXX Dead
     protected void emitObjectDefineProperty(IAccessorNode node)
     {
         /*
@@ -972,6 +973,7 @@ public class JSGoogEmitter extends JSEmitter implements IJSGoogEmitter
         write(ASEmitterTokens.PAREN_CLOSE);
     }
 
+    // XXX Dead
     protected void emitDefinePropertyFunction(IAccessorNode node)
     {
         emitMethodScope(node.getScopedNode());

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/0ca46d2a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/DefinePropertyFunctionEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/DefinePropertyFunctionEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/DefinePropertyFunctionEmitter.java
new file mode 100644
index 0000000..2d61ed8
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/DefinePropertyFunctionEmitter.java
@@ -0,0 +1,120 @@
+/*
+ *
+ *  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.js.jx;
+
+import org.apache.flex.compiler.codegen.ISubEmitter;
+import org.apache.flex.compiler.codegen.js.IJSEmitter;
+import org.apache.flex.compiler.common.IMetaInfo;
+import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
+import org.apache.flex.compiler.internal.codegen.js.JSSubEmitter;
+import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSEmitter;
+import org.apache.flex.compiler.internal.tree.as.SetterNode;
+import org.apache.flex.compiler.tree.as.IAccessorNode;
+import org.apache.flex.compiler.tree.as.IParameterNode;
+
+public class DefinePropertyFunctionEmitter extends JSSubEmitter implements
+        ISubEmitter<IAccessorNode>
+{
+
+    public DefinePropertyFunctionEmitter(IJSEmitter emitter)
+    {
+        super(emitter);
+    }
+
+    @Override
+    public void emit(IAccessorNode node)
+    {
+        // TODO (mschmalle) will remove this cast as more things get abstracted
+        JSFlexJSEmitter fjs = (JSFlexJSEmitter) getEmitter();
+
+        boolean isBindableSetter = false;
+        if (node instanceof SetterNode)
+        {
+            IMetaInfo[] metaInfos = null;
+            metaInfos = node.getMetaInfos();
+            for (IMetaInfo metaInfo : metaInfos)
+            {
+                String name = metaInfo.getTagName();
+                if (name.equals("Bindable")
+                        && metaInfo.getAllAttributes().length == 0)
+                {
+                    isBindableSetter = true;
+                    break;
+                }
+            }
+        }
+        if (isBindableSetter)
+        {
+            //write(ASEmitterTokens.FUNCTION);
+            //emitParameters(node.getParameterNodes());
+            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(node.getName());
+            //write(ASEmitterTokens.PAREN_OPEN);
+            //write(ASEmitterTokens.PAREN_CLOSE);
+            writeNewline(ASEmitterTokens.SEMICOLON);
+
+            // add change check
+            write(ASEmitterTokens.IF);
+            write(ASEmitterTokens.SPACE);
+            write(ASEmitterTokens.PAREN_OPEN);
+            write("oldValue");
+            write(ASEmitterTokens.SPACE);
+            write(ASEmitterTokens.STRICT_EQUAL);
+            write(ASEmitterTokens.SPACE);
+            IParameterNode[] params = node.getParameterNodes();
+            write(params[0].getName());
+            write(ASEmitterTokens.PAREN_CLOSE);
+            write(ASEmitterTokens.SPACE);
+            write(ASEmitterTokens.RETURN);
+            writeNewline(ASEmitterTokens.SEMICOLON);
+
+            write(ASEmitterTokens.THIS);
+            write(ASEmitterTokens.MEMBER_ACCESS);
+            write("__bindingWrappedSetter__" + node.getName());
+            write(ASEmitterTokens.PAREN_OPEN);
+            write(params[0].getName());
+            write(ASEmitterTokens.PAREN_CLOSE);
+            writeNewline(ASEmitterTokens.SEMICOLON);
+
+            // add dispatch of change event
+            writeNewline("    this.dispatchEvent(org_apache_flex_events_ValueChangeEvent.createUpdateEvent(");
+            writeNewline("         this, \"" + node.getName()
+                    + "\", oldValue, " + params[0].getName() + "));");
+            write(ASEmitterTokens.BLOCK_CLOSE);
+            //writeNewline(ASEmitterTokens.SEMICOLON);
+            writeNewline();
+            writeNewline();
+        }
+        else
+        {
+            fjs.emitMethodScope(node.getScopedNode());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/0ca46d2a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/ObjectDefinePropertyEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/ObjectDefinePropertyEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/ObjectDefinePropertyEmitter.java
new file mode 100644
index 0000000..2a20f6a
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/ObjectDefinePropertyEmitter.java
@@ -0,0 +1,166 @@
+/*
+ *
+ *  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.js.jx;
+
+import org.apache.flex.compiler.codegen.ISubEmitter;
+import org.apache.flex.compiler.codegen.js.IJSEmitter;
+import org.apache.flex.compiler.common.ASModifier;
+import org.apache.flex.compiler.common.IMetaInfo;
+import org.apache.flex.compiler.definitions.IFunctionDefinition;
+import org.apache.flex.compiler.definitions.ITypeDefinition;
+import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
+import org.apache.flex.compiler.internal.codegen.js.JSEmitterTokens;
+import org.apache.flex.compiler.internal.codegen.js.JSSubEmitter;
+import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSEmitter;
+import org.apache.flex.compiler.internal.codegen.js.goog.JSGoogEmitterTokens;
+import org.apache.flex.compiler.internal.tree.as.FunctionNode;
+import org.apache.flex.compiler.internal.tree.as.SetterNode;
+import org.apache.flex.compiler.tree.ASTNodeID;
+import org.apache.flex.compiler.tree.as.IAccessorNode;
+
+public class ObjectDefinePropertyEmitter extends JSSubEmitter implements
+        ISubEmitter<IAccessorNode>
+{
+
+    public ObjectDefinePropertyEmitter(IJSEmitter emitter)
+    {
+        super(emitter);
+    }
+
+    @Override
+    public void emit(IAccessorNode node)
+    {
+        // TODO (mschmalle) will remove this cast as more things get abstracted
+        JSFlexJSEmitter fjs = (JSFlexJSEmitter) getEmitter();
+
+        //TODO: ajh  is this method needed anymore?
+
+        FunctionNode fn = (FunctionNode) node;
+        fn.parseFunctionBody(fjs.getProblems());
+
+        IFunctionDefinition definition = node.getDefinition();
+        ITypeDefinition type = (ITypeDefinition) definition.getParent();
+
+        // ToDo (erikdebruin): add VF2JS conditional -> only use check during full SDK compilation
+        if (type == null)
+            return;
+
+        boolean isBindableSetter = false;
+        if (node instanceof SetterNode)
+        {
+            IMetaInfo[] metaInfos = null;
+            metaInfos = node.getMetaInfos();
+            for (IMetaInfo metaInfo : metaInfos)
+            {
+                String name = metaInfo.getTagName();
+                if (name.equals("Bindable")
+                        && metaInfo.getAllAttributes().length == 0)
+                {
+                    isBindableSetter = true;
+                    break;
+                }
+            }
+        }
+        if (isBindableSetter)
+        {
+            fjs.getDocEmitter().emitMethodDoc(fn, getWalker().getProject());
+            write(fjs.formatQualifiedName(type.getQualifiedName()));
+            if (!node.hasModifier(ASModifier.STATIC))
+            {
+                write(ASEmitterTokens.MEMBER_ACCESS);
+                write(JSEmitterTokens.PROTOTYPE);
+            }
+
+            write(ASEmitterTokens.MEMBER_ACCESS);
+            write("__bindingWrappedSetter__");
+            writeToken(node.getName());
+            writeToken(ASEmitterTokens.EQUAL);
+            write(ASEmitterTokens.FUNCTION);
+            fjs.emitParameters(node.getParameterNodes());
+            //writeNewline();
+            fjs.emitMethodScope(node.getScopedNode());
+        }
+
+        super_emitObjectDefineProperty(node);
+    }
+
+    protected void super_emitObjectDefineProperty(IAccessorNode node)
+    {
+        // TODO (mschmalle) will remove this cast as more things get abstracted
+        JSFlexJSEmitter fjs = (JSFlexJSEmitter) getEmitter();
+
+        /*
+        Object.defineProperty(
+            A.prototype, 
+            'foo', 
+            {get: function() {return -1;}, 
+            configurable: true}
+         );
+        */
+
+        FunctionNode fn = (FunctionNode) node;
+        fn.parseFunctionBody(fjs.getProblems());
+
+        // head
+        write(JSGoogEmitterTokens.OBJECT);
+        write(ASEmitterTokens.MEMBER_ACCESS);
+        write(JSEmitterTokens.DEFINE_PROPERTY);
+        fjs.writeNewline(ASEmitterTokens.PAREN_OPEN, true);
+
+        // Type
+        IFunctionDefinition definition = node.getDefinition();
+        ITypeDefinition type = (ITypeDefinition) definition.getParent();
+        write(type.getQualifiedName());
+        if (!node.hasModifier(ASModifier.STATIC))
+        {
+            write(ASEmitterTokens.MEMBER_ACCESS);
+            write(JSEmitterTokens.PROTOTYPE);
+        }
+        writeToken(ASEmitterTokens.COMMA);
+        writeNewline();
+
+        // name
+        write(ASEmitterTokens.SINGLE_QUOTE);
+        write(definition.getBaseName());
+        write(ASEmitterTokens.SINGLE_QUOTE);
+        writeToken(ASEmitterTokens.COMMA);
+        writeNewline();
+
+        // info object
+        // declaration
+        write(ASEmitterTokens.BLOCK_OPEN);
+        write(node.getNodeID() == ASTNodeID.GetterID ? ASEmitterTokens.GET
+                : ASEmitterTokens.SET);
+        write(ASEmitterTokens.COLON);
+        write(ASEmitterTokens.FUNCTION);
+        fjs.emitParameters(node.getParameterNodes());
+
+        fjs.emitDefinePropertyFunction(node);
+
+        writeToken(ASEmitterTokens.COMMA);
+        write(JSEmitterTokens.CONFIGURABLE);
+        write(ASEmitterTokens.COLON);
+        write(ASEmitterTokens.TRUE);
+        fjs.writeNewline(ASEmitterTokens.BLOCK_CLOSE, false);
+
+        // tail, no colon; parent container will add it
+        write(ASEmitterTokens.PAREN_CLOSE);
+    }
+}