IDS_CLASSLOAD_CONSTRAINT_MISMATCH_ON_INTERFACE_METHOD_IMPL "Method '%3' on type '%1' from assembly '%2' tried to explicitly implement an interface method with weaker type parameter constraints."
IDS_CLASSLOAD_EXPLICIT_GENERIC "Could not load type '%1' from assembly '%2' because generic types cannot have explicit layout."
- IDS_EE_COM_INVISIBLE_PARENT "This type has a ComVisible(false) parent in its hierarchy, therefore QueryInterface calls for IDispatch or class interfaces are disallowed."
+ IDS_EE_COM_INVISIBLE_PARENT "Type '%1' has a ComVisible(false) parent '%2' in its hierarchy, therefore QueryInterface calls for IDispatch or class interfaces are disallowed."
IDS_EE_COMIMPORT_METHOD_NO_INTERFACE "Method '%1' in ComImport class '%2' must implement an interface method."
IDS_EE_ATTEMPT_TO_CREATE_GENERIC_CCW "Generic types cannot be marshaled to COM interface pointers."
// Throw an exception to report the error.
if (!CheckParentComVisibilityNoThrow(fForIDispatch))
- COMPlusThrow(kInvalidOperationException, IDS_EE_COM_INVISIBLE_PARENT);
+ {
+ ComCallWrapperTemplate *invisParent = FindInvisibleParent();
+ _ASSERTE(invisParent != NULL);
+
+ SString thisType;
+ SString invisParentType;
+ TypeString::AppendType(thisType, m_thClass);
+ TypeString::AppendType(invisParentType, invisParent->m_thClass);
+ COMPlusThrow(kInvalidOperationException, IDS_EE_COM_INVISIBLE_PARENT, thisType.GetUnicode(), invisParentType.GetUnicode());
+ }
}
BOOL ComCallWrapperTemplate::CheckParentComVisibilityNoThrow(BOOL fForIDispatch)
m_flags &= (~enum_InvisibleParent);
- // If there are no parents...leave it as false.
if (m_pParent == NULL)
return;
- // If our parent has an invisible parent
- if (m_pParent->HasInvisibleParent())
+ // Check if the parent has an invisible parent
+ // or if the parent itself is invisible.
+ if (m_pParent->HasInvisibleParent()
+ || !IsTypeVisibleFromCom(m_pParent->m_thClass))
{
+ _ASSERTE(NULL != FindInvisibleParent());
m_flags |= enum_InvisibleParent;
}
- // If our parent is invisible
- else if (!IsTypeVisibleFromCom(m_pParent->m_thClass))
+}
+
+ComCallWrapperTemplate* ComCallWrapperTemplate::FindInvisibleParent()
+{
+ ComCallWrapperTemplate* invisParentMaybe = m_pParent;
+
+ // Walk up the CCW parent classes and try to find
+ // if one is invisible to COM.
+ while (invisParentMaybe != NULL)
{
- m_flags |= enum_InvisibleParent;
+ // If our parent is invisible, return it.
+ if (!IsTypeVisibleFromCom(invisParentMaybe->m_thClass))
+ return invisParentMaybe;
+
+ invisParentMaybe = invisParentMaybe->m_pParent;
}
+
+ // All classes in hierarchy are COM visible
+ return NULL;
}
//--------------------------------------------------------------------------