Kaydet (Commit) eb0cfb3b authored tarafından Michael Stahl's avatar Michael Stahl

cppumaker: do write exception specifications on --enable-dbgutil

Exception specifications are useless for production code, but make
for useful assertions in dbgutil builds (on platforms where they
are enforced at runtime).

Because we do not have API tests that exhaustively trigger all
documented error conditions, much less the undocumented or wrongly
handled error conditions that would cause the implementation to violate
its API specification, there is likely some benefit in having these
runtime-checked specifications in debug builds, in the hope that our
various tests which may incidentally call various API methods, or
general soffice usage, uncovers these bugs.

Also, there may be some benefit to making API implementers more
aware of the exception specifications, to quote Stephan's mail:

 To be able to programmatically react to an exception raised by a UNO
 method (which is the raison d'être of non-runtime UNO exceptions), the
 specification of that method must document the method's behavior with
 respect to raising that exception, and any implementation of the method
 must adhere to that specification.  However, with that part of a UNO
 method's interface moved out of sight of a programmer writing a C++
 implementation of that method, I fear that adherence to specification
 will degrade in practice.  And that negatively affects an area where we
 do not shine anyway: reaction to errors.

This partially reverts commits:
0295bd6b
155cd09b

Change-Id: I9c7664c9f1b238f4f9501aacb065981236949440
üst 1658e4ef
......@@ -1483,6 +1483,7 @@ void InterfaceType::dumpAttributes(FileStream& o)
o << "virtual ";
dumpType(o, fieldType);
o << " SAL_CALL get" << fieldName << "()";
dumpAttributeExceptionSpecification(o, name, RT_MODE_ATTRIBUTE_GET);
o << " = 0;\n";
if ((access & RT_ACCESS_READONLY) == 0)
......@@ -1493,6 +1494,7 @@ void InterfaceType::dumpAttributes(FileStream& o)
o << "virtual void SAL_CALL set" << fieldName << "( ";
dumpType(o, fieldType, byRef, byRef);
o << " _" << fieldName.toAsciiLowerCase() << " )";
dumpAttributeExceptionSpecification(o, name, RT_MODE_ATTRIBUTE_SET);
o << " = 0;\n";
}
}
......@@ -1510,6 +1512,7 @@ void InterfaceType::dumpMethods(FileStream& o)
sal_Bool bRef = sal_False;
sal_Bool bConst = sal_False;
sal_Bool bWithRunTimeExcp = sal_True;
for (sal_uInt16 i=0; i < methodCount; i++)
{
......@@ -1526,6 +1529,11 @@ void InterfaceType::dumpMethods(FileStream& o)
m_reader.getMethodReturnTypeName(i), RTL_TEXTENCODING_UTF8);
paramCount = m_reader.getMethodParameterCount(i);
if ( methodName.equals("acquire") || methodName.equals("release") )
{
bWithRunTimeExcp = sal_False;
}
if (first)
{
first = sal_False;
......@@ -1578,6 +1586,7 @@ void InterfaceType::dumpMethods(FileStream& o)
}
o << " )";
}
dumpExceptionSpecification(o, i, bWithRunTimeExcp);
o << " = 0;\n";
}
}
......@@ -2207,6 +2216,62 @@ void InterfaceType::dumpMethodsCppuDecl(FileStream& o, StringSet* pFinishedTypes
}
}
void InterfaceType::dumpExceptionSpecification(
FileStream & out, sal_uInt32 methodIndex, bool runtimeException)
{
// exception specifications are undesirable in production code, but make
// for useful assertions in debug builds (on platforms where they are
// enforced at runtime)
#ifndef DBG_UTIL
(void) out;
(void) methodIndex;
(void) runtimeException;
#else
out << " throw (";
bool first = true;
if (methodIndex <= SAL_MAX_UINT16) {
sal_uInt16 count = m_reader.getMethodExceptionCount(
static_cast< sal_uInt16 >(methodIndex));
for (sal_uInt16 i = 0; i < count; ++i) {
rtl::OUString name(
m_reader.getMethodExceptionTypeName(
static_cast< sal_uInt16 >(methodIndex), i));
if ( name != "com/sun/star/uno/RuntimeException" )
{
if (!first) {
out << ", ";
}
first = false;
out << scopedCppName(
rtl::OUStringToOString(name, RTL_TEXTENCODING_UTF8));
}
}
}
if (runtimeException) {
if (!first) {
out << ", ";
}
out << "::com::sun::star::uno::RuntimeException";
}
out << ")";
#endif
}
void InterfaceType::dumpAttributeExceptionSpecification(
FileStream & out, rtl::OUString const & name, RTMethodMode sort)
{
sal_uInt16 methodCount = m_reader.getMethodCount();
for (sal_uInt16 i = 0; i < methodCount; ++i) {
if (m_reader.getMethodFlags(i) == sort
&& m_reader.getMethodName(i) == name)
{
dumpExceptionSpecification(out, i, true);
return;
}
}
dumpExceptionSpecification(out, 0xFFFFFFFF, true);
}
void InterfaceType::dumpExceptionTypeName(
FileStream & out, char const * prefix, sal_uInt32 index, rtl::OUString name)
{
......
......@@ -194,6 +194,12 @@ protected:
bool m_isDeprecated;
private:
void dumpExceptionSpecification(
FileStream & out, sal_uInt32 methodIndex, bool runtimeException);
void dumpAttributeExceptionSpecification(
FileStream & out, rtl::OUString const & name, RTMethodMode sort);
void dumpExceptionTypeName(
FileStream & out, char const * prefix, sal_uInt32 index,
rtl::OUString name);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment