/* * * 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(); 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.getParametersContainerNode()); //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.getParametersContainerNode()); 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); } }