예제 #1
0
파일: Main.cpp 프로젝트: bholl/zeroc-ice
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;
}