bool CodeVisitor::visitClassDefStart(const ClassDefPtr& p) { string scoped = p->scoped(); string name = getName(p); string type = getTypeVar(p); string abs = getAbsolute(p, _ns); string prxName = getName(p, "Prx"); string prxType = getTypeVar(p, "Prx"); string prxAbs = getAbsolute(p, _ns, "", "Prx"); ClassList bases = p->bases(); ClassDefPtr base; OperationList ops = p->operations(); OperationList::iterator oli; DataMemberList members = p->dataMembers(); bool isInterface = p->isInterface(); bool isAbstract = isInterface || p->allOperations().size() > 0; // Don't use isAbstract() - see bug 3739 startNamespace(p); // // Define the class. // if(isInterface) { _out << sp << nl << "if(!interface_exists('" << escapeName(abs) << "'))"; _out << sb; _out << nl << "interface " << name; if(!bases.empty()) { _out << " extends "; for(ClassList::const_iterator q = bases.begin(); q != bases.end(); ++q) { if(q != bases.begin()) { _out << ", "; } _out << getAbsolute(*q, _ns); } } _out << sb; for(oli = ops.begin(); oli != ops.end(); ++oli) { _out << nl << "public function " << fixIdent((*oli)->name()) << '('; ParamDeclList params = (*oli)->parameters(); for(ParamDeclList::iterator q = params.begin(); q != params.end(); ++q) { if(q != params.begin()) { _out << ", "; } _out << '$' << fixIdent((*q)->name()); } _out << ");"; } _out << eb; } else { _out << sp << nl << "if(!class_exists('" << escapeName(abs) << "'))"; _out << sb; _out << nl; if(isAbstract) { _out << "abstract "; } _out << "class " << name; if(!bases.empty() && !bases.front()->isInterface()) { base = bases.front(); bases.pop_front(); } if(base) { _out << " extends " << getAbsolute(base, _ns); } else { if(!p->isLocal()) { _out << " extends " << scopedToName("::Ice::ObjectImpl", _ns); } } if(!bases.empty()) { _out << " implements "; for(ClassList::const_iterator q = bases.begin(); q != bases.end(); ++q) { if(q != bases.begin()) { _out << ", "; } _out << getAbsolute(*q, _ns); } } _out << sb; // // __construct // _out << nl << "public function __construct("; MemberInfoList allMembers; collectClassMembers(p, allMembers, false); writeConstructorParams(allMembers); _out << ")"; _out << sb; if(base) { _out << nl << "parent::__construct("; int count = 0; for(MemberInfoList::iterator q = allMembers.begin(); q != allMembers.end(); ++q) { if(q->inherited) { if(count) { _out << ", "; } _out << '$' << q->fixedName; ++count; } } _out << ");"; } { for(MemberInfoList::iterator q = allMembers.begin(); q != allMembers.end(); ++q) { if(!q->inherited) { writeAssign(*q); } } } _out << eb; if(!ops.empty()) { _out << sp; for(oli = ops.begin(); oli != ops.end(); ++oli) { _out << nl << "abstract public function " << fixIdent((*oli)->name()) << '('; ParamDeclList params = (*oli)->parameters(); for(ParamDeclList::iterator q = params.begin(); q != params.end(); ++q) { if(q != params.begin()) { _out << ", "; } _out << '$' << fixIdent((*q)->name()); } _out << ");"; } } if(!p->isLocal()) { // // ice_staticId // _out << sp << nl << "public static function ice_staticId()"; _out << sb; _out << nl << "return '" << scoped << "';"; _out << eb; } // // __toString // _out << sp << nl << "public function __toString()"; _out << sb; _out << nl << "global " << type << ';'; _out << nl << "return IcePHP_stringify($this, " << type << ");"; _out << eb; if(!members.empty()) { _out << sp; bool isProtected = p->hasMetaData("protected"); for(DataMemberList::iterator q = members.begin(); q != members.end(); ++q) { _out << nl; if(isProtected || (*q)->hasMetaData("protected")) { _out << "protected "; } else { _out << "public "; } _out << "$" << fixIdent((*q)->name()) << ";"; } } _out << eb; // End of class. } // // Define the proxy class. // if(!p->isLocal()) { _out << sp << nl << "class " << prxName << "Helper"; _out << sb; _out << sp << nl << "public static function checkedCast($proxy, $facetOrCtx=null, $ctx=null)"; _out << sb; _out << nl << "return $proxy->ice_checkedCast('" << scoped << "', $facetOrCtx, $ctx);"; _out << eb; _out << sp << nl << "public static function uncheckedCast($proxy, $facet=null)"; _out << sb; _out << nl << "return $proxy->ice_uncheckedCast('" << scoped << "', $facet);"; _out << eb; _out << eb; } if(_classHistory.count(scoped) == 0 && p->canBeCyclic()) { // // Emit a forward declaration for the class in case a data member refers to this type. // _out << sp << nl << type << " = IcePHP_declareClass('" << scoped << "');"; } // // Emit the type information. // _out << sp << nl << type << " = IcePHP_defineClass('" << scoped << "', '" << escapeName(abs) << "', " << (isAbstract ? "true" : "false") << ", "; if(!base) { _out << "$Ice__t_Object"; } else { _out << getTypeVar(base); } _out << ", "; // // Interfaces // if(!bases.empty()) { _out << "array("; for(ClassList::const_iterator q = bases.begin(); q != bases.end(); ++q) { if(q != bases.begin()) { _out << ", "; } _out << getTypeVar(*q); } _out << ')'; } else { _out << "null"; } _out << ", "; // // Members // // Data members are represented as an array: // // ('MemberName', MemberType) // // where MemberType is either a primitive type constant (T_INT, etc.) or the id of a constructed type. // if(!members.empty()) { _out << "array("; for(DataMemberList::iterator q = members.begin(); q != members.end(); ++q) { if(q != members.begin()) { _out << ',' << nl; } _out.inc(); _out << nl << "array('" << fixIdent((*q)->name()) << "', "; writeType((*q)->type()); _out << ')'; _out.dec(); } _out << ')'; } else { _out << "null"; } _out << ");"; if(!p->isLocal()) { _out << sp << nl << prxType << " = IcePHP_defineProxy(" << type << ");"; // // Define each operation. The arguments to IcePHP_defineOperation are: // // $ClassType, 'opName', Mode, SendMode, (InParams), (OutParams), ReturnType, (Exceptions) // // where InParams and OutParams are arrays of type descriptions, and Exceptions // is an array of exception type ids. // if(!ops.empty()) { _out << sp; for(oli = ops.begin(); oli != ops.end(); ++oli) { ParamDeclList params = (*oli)->parameters(); ParamDeclList::iterator t; int count; _out << nl << "IcePHP_defineOperation(" << type << ", '" << (*oli)->name() << "', " << getOperationMode((*oli)->mode(), _ns) << ", " << getOperationMode((*oli)->sendMode(), _ns) << ", "; for(t = params.begin(), count = 0; t != params.end(); ++t) { if(!(*t)->isOutParam()) { if(count == 0) { _out << "array("; } else if(count > 0) { _out << ", "; } writeType((*t)->type()); ++count; } } if(count > 0) { _out << ')'; } else { _out << "null"; } _out << ", "; for(t = params.begin(), count = 0; t != params.end(); ++t) { if((*t)->isOutParam()) { if(count == 0) { _out << "array("; } else if(count > 0) { _out << ", "; } writeType((*t)->type()); ++count; } } if(count > 0) { _out << ')'; } else { _out << "null"; } _out << ", "; TypePtr returnType = (*oli)->returnType(); if(returnType) { writeType(returnType); } else { _out << "null"; } _out << ", "; ExceptionList exceptions = (*oli)->throws(); if(!exceptions.empty()) { _out << "array("; for(ExceptionList::iterator u = exceptions.begin(); u != exceptions.end(); ++u) { if(u != exceptions.begin()) { _out << ", "; } _out << getTypeVar(*u); } _out << ')'; } else { _out << "null"; } _out << ");"; } } } _out << eb; endNamespace(); if(_classHistory.count(scoped) == 0) { _classHistory.insert(scoped); // Avoid redundant declarations. } return false; }