/* * * 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.externals.reference; import org.apache.flex.compiler.clients.ExternCConfiguration.ExcludedMember; import org.apache.flex.compiler.internal.codegen.externals.utils.FunctionUtils; import org.apache.flex.compiler.internal.codegen.externals.utils.JSTypeUtils; import com.google.javascript.rhino.JSDocInfo; import com.google.javascript.rhino.JSTypeExpression; import com.google.javascript.rhino.Node; import com.google.javascript.rhino.jstype.JSType; public class FieldReference extends MemberReference { private boolean isStatic; private boolean isConst; private String overrideStringType; private Node constantValueNode; public boolean isStatic() { return isStatic; } public void setStatic(boolean isStatic) { this.isStatic = isStatic; } public boolean isConst() { return isConst; } public void setConst(boolean isConst) { this.isConst = isConst; } public void setOverrideStringType(String overrideStringType) { this.overrideStringType = overrideStringType; } public void setConstantValueNode(Node constantValueNode) { this.constantValueNode = constantValueNode; } public String toTypeAnnotationString() { JSType jsType = null; if (getComment() != null && getComment().getType() != null) { jsType = getModel().evaluate(getComment().getType()); } return jsType != null ? jsType.toAnnotationString() : "Object"; } public FieldReference(ReferenceModel model, ClassReference classReference, Node node, String name, JSDocInfo comment, boolean isStatic) { super(model, classReference, node, name, comment); this.isStatic = isStatic; } @Override public void emit(StringBuilder sb) { // XXX HACK TEMP! if (getComment().isConstructor()) return; // Window has a global var Window that conflicts with the constructor. if (getQualifiedName().equals(getClassReference().getQualifiedName())) return; if (getClassReference().hasSuperField(getQualifiedName())) return; emitComment(sb); ExcludedMember excluded = isExcluded(); if (excluded != null) { excluded.print(sb); return; // XXX (mschmalle) accessors are not treated right, need to exclude get/set } if (!getClassReference().isInterface() && !getComment().isOverride() && !getClassReference().isPropertyInterfaceImplementation(getBaseName())) { emitVar(sb); } else { emitAccessor(sb); } } private void emitAccessor(StringBuilder sb) { boolean isInterface = getClassReference().isInterface(); String staticValue = (isStatic) ? "static " : ""; String isPublic = isInterface ? "" : "public "; String getBody = isInterface ? "" : "{ return null; }"; String setBody = isInterface ? "" : "{}"; String type = toTypeString(); if (type.contains("|") || type.contains("?")) type = "*"; if (outputJS) { sb.append(getClassReference().getPackageName()); sb.append("."); sb.append(getClassReference().getBaseName()); sb.append("."); if (!isStatic) sb.append("prototype."); sb.append(getBaseName()); sb.append(";\n"); return; } // getter sb.append(indent); sb.append(isPublic); sb.append(staticValue); sb.append("function get "); sb.append(getBaseName()); sb.append("():"); sb.append(type); sb.append(getBody); sb.append(";\n"); // setter sb.append(indent); sb.append(isPublic); sb.append(staticValue); sb.append("function set "); sb.append(getBaseName()); sb.append("(value:"); sb.append(type); sb.append("):void"); sb.append(setBody); sb.append(";\n"); } private void emitVar(StringBuilder sb) { String staticValue = (isStatic) ? "static " : ""; String constVarValue = (isConst) ? "const " : "var "; String type = toTypeString(); if (type.contains("|") || type.contains("?")) type = "*"; if (outputJS) { sb.append(getClassReference().getPackageName()); sb.append("."); sb.append(getClassReference().getBaseName()); sb.append("."); if (!isStatic) sb.append("prototype."); sb.append(getBaseName()); sb.append(";\n"); return; } sb.append(indent); sb.append("public "); sb.append(staticValue); sb.append(constVarValue); sb.append(getQualifiedName()); sb.append(":"); sb.append(type); if (isConst) { emitConstValue(sb); } sb.append(";\n"); } private void emitConstValue(StringBuilder sb) { sb.append(" = "); sb.append(toConstValue(constantValueNode)); } private String toConstValue(Node node) { if (toTypeString().equals("Number")) return Integer.toString(getClassReference().getEnumConstant()); if (node.isString()) return "'" + node.getString() + "'"; return "undefined /* TODO type not set */"; } public String toTypeString() { if (overrideStringType != null) return overrideStringType; String typeString = JSTypeUtils.toFieldTypeString(this); if (FunctionUtils.hasTemplate(this) && FunctionUtils.containsTemplate(this, typeString)) { return "Object"; } return typeString; } @Override protected void emitCommentBody(StringBuilder sb) { emitBlockDescription(sb); emitType(sb); emitSee(sb); emitSeeSourceFileName(sb); } private void emitType(StringBuilder sb) { JSTypeExpression type = getComment().getType(); if (type != null) { if (outputJS) { sb.append(indent); sb.append(" * @type "); sb.append("{"); sb.append(mapBackToJS(getModel().evaluate(type).toAnnotationString(), false)); sb.append("} "); sb.append("\n"); } else { sb.append(indent); sb.append(" * @see JSType - "); sb.append("["); sb.append(getModel().evaluate(type).toAnnotationString()); sb.append("] "); String description = getComment().getReturnDescription(); if (description != null) sb.append(description); sb.append("\n"); } } } }