Example #1
0
ObjectInfoPtr ConfigObjectLoader::getObjectInfo( expr_cref expr, str_cref name ) const
{
	if( !name.empty() )
	{
		ObjectInfoPtr obj;

		// already found.
		if( Utility::mapLookup( m_objects, name, obj ) )
		{
			return obj;
		}
	}

	if( expr.type() == EObject ) // it's an object expression
	{
		std::string className = expr.value();
		ClassInfoPtr classInfo = getClassInfo( className );
		BuilderPtr builder = classInfo->createBuilder( name, expr );
        ObjectInfoPtr obj( new ObjectInfo( name, expr, *classInfo, builder ) );

        // It needs to be in the map before we bind its parameters so a circular reference can be detected
        m_objects[name] = obj;
        builder->bindParams( *this );
		return obj;
	}
	else if( expr.type() == EVariable )
	{
		// this could recurse indefinitely with circular reference..

		// NOTE: if anything throws here, let ParamBinderBase manage the context of the error.

		std::string objName;
		expr_cref expr2 = underlying( expr, &objName );
		return getObjectInfo( expr2, objName );
	}
	else // this isn't a class. It might be a map or list or whatever but isn't an object
	{
		std::ostringstream oss;
		oss << expr.value() << " is not an object";

		// Do not throw TypeError here. If it isn't an object it can't be a proxy either
		throw std::invalid_argument( oss.str() );
	}

}