Implemented inheritance.

This commit is contained in:
Paul Knopf 2019-04-15 19:30:21 -04:00
parent 87ef7e4874
commit 90f6e74e7c
13 changed files with 314 additions and 43 deletions

View file

@ -2,6 +2,7 @@
#include <QmlNet/qml/NetValue.h> #include <QmlNet/qml/NetValue.h>
#include <QmlNet/qml/NetValueMetaObject.h> #include <QmlNet/qml/NetValueMetaObject.h>
#include <QmlNet/types/NetSignalInfo.h> #include <QmlNet/types/NetSignalInfo.h>
#include <QmlNet/types/NetTypeManager.h>
#include <QmlNet/types/Callbacks.h> #include <QmlNet/types/Callbacks.h>
#include <QDebug> #include <QDebug>
#include <utility> #include <utility>
@ -133,23 +134,32 @@ NetValue::NetValue(const QSharedPointer<NetReference>& instance, QObject *parent
} }
collection->netValues.append(this); collection->netValues.append(this);
// Auto wire up all of our signal handlers that will invoke .NET delegates. QList<QSharedPointer<NetTypeInfo>> types;
for(int index = 0; index <= instance->getTypeInfo()->getSignalCount() - 1; index++)
{
QSharedPointer<NetSignalInfo> signalInfo = instance->getTypeInfo()->getSignal(index);
QString signalSig = signalInfo->getSignature(); auto type = instance->getTypeInfo();
QString slotSig = signalInfo->getSlotSignature();
int signalIndex = valueMeta->indexOfSignal(signalSig.toLatin1().data()); while(type != nullptr) {
int slotIndex = valueMeta->indexOfSlot(slotSig.toLatin1().data()); types.insert(0, type);
type = NetTypeManager::getBaseType(type);
}
QMetaMethod signalMethod = valueMeta->method(signalIndex); for(QSharedPointer<NetTypeInfo> type : types) {
QMetaMethod slotMethod = valueMeta->method(slotIndex); for(int index = 0; index <= type->getSignalCount() - 1; index++) {
QSharedPointer<NetSignalInfo> signalInfo = type->getSignal(index);
QObject::connect(this, signalMethod, QString signalSig = signalInfo->getSignature();
this, slotMethod); QString slotSig = signalInfo->getSlotSignature();
};
int signalIndex = valueMeta->indexOfSignal(signalSig.toLatin1().data());
int slotIndex = valueMeta->indexOfSlot(slotSig.toLatin1().data());
QMetaMethod signalMethod = valueMeta->method(signalIndex);
QMetaMethod slotMethod = valueMeta->method(slotIndex);
QObject::connect(this, signalMethod,
this, slotMethod);
}
}
} }
QMap<uint64_t, NetValue::NetValueCollection*> NetValue::objectIdNetValuesMap = QMap<uint64_t, NetValue::NetValueCollection*>(); QMap<uint64_t, NetValue::NetValueCollection*> NetValue::objectIdNetValuesMap = QMap<uint64_t, NetValue::NetValueCollection*>();

View file

@ -5,6 +5,7 @@
#include <QmlNet/types/NetPropertyInfo.h> #include <QmlNet/types/NetPropertyInfo.h>
#include <QmlNet/types/NetSignalInfo.h> #include <QmlNet/types/NetSignalInfo.h>
#include <QmlNet/types/Callbacks.h> #include <QmlNet/types/Callbacks.h>
#include <QmlNet/types/NetTypeManager.h>
#include <QQmlEngine> #include <QQmlEngine>
#include <QDebug> #include <QDebug>
#include <private/qmetaobjectbuilder_p.h> #include <private/qmetaobjectbuilder_p.h>
@ -18,10 +19,17 @@ QMetaObject *metaObjectFor(const QSharedPointer<NetTypeInfo>& typeInfo)
typeInfo->ensureLoaded(); typeInfo->ensureLoaded();
QMetaObjectBuilder mob; QMetaObjectBuilder mob;
mob.setSuperClass(&QObject::staticMetaObject);
mob.setClassName(typeInfo->getClassName().toLatin1()); mob.setClassName(typeInfo->getClassName().toLatin1());
mob.setFlags(QMetaObjectBuilder::DynamicMetaObject); mob.setFlags(QMetaObjectBuilder::DynamicMetaObject);
QString baseType = typeInfo->getBaseType();
if(baseType.isNull() || baseType.isEmpty()) {
mob.setSuperClass(&QObject::staticMetaObject);
} else {
auto baseTypeInfo = NetTypeManager::getTypeInfo(baseType);
mob.setSuperClass(metaObjectFor(baseTypeInfo));
}
// register all the signals for the type // register all the signals for the type
for(int index = 0; index <= typeInfo->getSignalCount() - 1; index++) for(int index = 0; index <= typeInfo->getSignalCount() - 1; index++)
{ {
@ -99,16 +107,49 @@ NetValueMetaObject::NetValueMetaObject(QObject *value,
} }
int NetValueMetaObject::metaCall(QMetaObject::Call c, int idx, void **a) int NetValueMetaObject::metaCall(QMetaObject::Call c, int idx, void **a)
{
#ifdef QMLNET_TRACE
switch(c) {
case ReadProperty:
{
auto prop = property(idx);
qDebug() << this->className() << ": reading property: " << idx << ": " << prop.name();
}
break;
case WriteProperty:
{
auto prop = property(idx);
qDebug() << this->className() << ": writing property: " << idx << ": " << prop.name();
}
break;
case InvokeMetaMethod:
{
auto meth = method(idx);
qDebug() << this->className() << ": invoking method: " << idx << ": " << meth.name();
}
break;
default:
break; // Unhandled.
}
#endif
return metaCallRecursive(c, idx, idx, a, instance->getTypeInfo());
}
int NetValueMetaObject::metaCallRecursive(QMetaObject::Call c, int originalIdx, int idx, void **a, QSharedPointer<NetTypeInfo> typeInfo)
{ {
switch(c) { switch(c) {
case ReadProperty: case ReadProperty:
{ {
int offset = propertyOffset(); int offset = propertyOffset();
if (idx < offset) { if (idx < offset) {
auto baseType = NetTypeManager::getBaseType(typeInfo);
if(baseType != nullptr) {
return metaCallRecursive(c, originalIdx, idx, a, baseType);
}
return value->qt_metacall(c, idx, a); return value->qt_metacall(c, idx, a);
} }
QSharedPointer<NetPropertyInfo> propertyInfo = instance->getTypeInfo()->getProperty(idx - offset); QSharedPointer<NetPropertyInfo> propertyInfo = typeInfo->getProperty(idx - offset);
QSharedPointer<NetTypeInfo> propertyType = propertyInfo->getReturnType(); QSharedPointer<NetTypeInfo> propertyType = propertyInfo->getReturnType();
QSharedPointer<NetVariant> result = QSharedPointer<NetVariant>(new NetVariant()); QSharedPointer<NetVariant> result = QSharedPointer<NetVariant>(new NetVariant());
@ -133,10 +174,14 @@ int NetValueMetaObject::metaCall(QMetaObject::Call c, int idx, void **a)
{ {
int offset = propertyOffset(); int offset = propertyOffset();
if (idx < offset) { if (idx < offset) {
auto baseType = NetTypeManager::getBaseType(typeInfo);
if(baseType != nullptr) {
return metaCallRecursive(c, originalIdx, idx, a, baseType);
}
return value->qt_metacall(c, idx, a); return value->qt_metacall(c, idx, a);
} }
QSharedPointer<NetPropertyInfo> propertyInfo = instance->getTypeInfo()->getProperty(idx - offset); QSharedPointer<NetPropertyInfo> propertyInfo = typeInfo->getProperty(idx - offset);
QSharedPointer<NetTypeInfo> propertyType = propertyInfo->getReturnType(); QSharedPointer<NetTypeInfo> propertyType = propertyInfo->getReturnType();
QSharedPointer<NetVariant> newValue = QSharedPointer<NetVariant>(new NetVariant()); QSharedPointer<NetVariant> newValue = QSharedPointer<NetVariant>(new NetVariant());
@ -149,22 +194,26 @@ int NetValueMetaObject::metaCall(QMetaObject::Call c, int idx, void **a)
{ {
int offset = methodOffset(); int offset = methodOffset();
if (idx < offset) { if (idx < offset) {
auto baseType = NetTypeManager::getBaseType(typeInfo);
if(baseType != nullptr) {
return metaCallRecursive(c, originalIdx, idx + ((baseType->getSignalCount() * 2) + baseType->getLocalMethodCount()), a, baseType);
}
return value->qt_metacall(c, idx, a); return value->qt_metacall(c, idx, a);
} }
idx -= offset; idx -= offset;
if(idx < instance->getTypeInfo()->getSignalCount()) { if(idx < typeInfo->getSignalCount()) {
// This is a signal call, activate it! // This is a signal call, activate it!
activate(value, idx + offset, a); activate(value, originalIdx, a);
return -1; return -1;
} }
idx -= instance->getTypeInfo()->getSignalCount(); idx -= typeInfo->getSignalCount();
if(idx < instance->getTypeInfo()->getLocalMethodCount()) { if(idx < typeInfo->getLocalMethodCount()) {
// This is a method call! // This is a method call!
QSharedPointer<NetMethodInfo> methodInfo = instance->getTypeInfo()->getLocalMethodInfo(idx); QSharedPointer<NetMethodInfo> methodInfo = typeInfo->getLocalMethodInfo(idx);
QSharedPointer<NetVariantList> parameters = QSharedPointer<NetVariantList>(new NetVariantList()); QSharedPointer<NetVariantList> parameters = QSharedPointer<NetVariantList>(new NetVariantList());
for(int index = 0; index <= methodInfo->getParameterCount() - 1; index++) for(int index = 0; index <= methodInfo->getParameterCount() - 1; index++)
@ -204,12 +253,12 @@ int NetValueMetaObject::metaCall(QMetaObject::Call c, int idx, void **a)
return -1; return -1;
} }
idx -= instance->getTypeInfo()->getLocalMethodCount(); idx -= typeInfo->getLocalMethodCount();
{ {
// This is a slot invocation, likely the built-in handlers that are used // This is a slot invocation, likely the built-in handlers that are used
// to trigger NET delegates for any signals. // to trigger NET delegates for any signals.
QSharedPointer<NetSignalInfo> signalInfo = instance->getTypeInfo()->getSignal(idx); QSharedPointer<NetSignalInfo> signalInfo = typeInfo->getSignal(idx);
QSharedPointer<NetVariantList> parameters; QSharedPointer<NetVariantList> parameters;
if(signalInfo->getParameterCount() > 0) { if(signalInfo->getParameterCount() > 0) {

View file

@ -17,6 +17,8 @@ protected:
int metaCall(QMetaObject::Call c, int id, void **a); int metaCall(QMetaObject::Call c, int id, void **a);
private: private:
int metaCallRecursive(QMetaObject::Call c, int originalIdx, int idx, void **a, QSharedPointer<NetTypeInfo> typeInfo);
QObject *value; QObject *value;
QSharedPointer<NetReference> instance; QSharedPointer<NetReference> instance;
}; };

View file

@ -191,6 +191,7 @@ Q_DECL_EXPORT int qqmlapplicationengine_registerType(NetTypeInfoContainer* typeC
NETVALUETYPE_CASE(114) NETVALUETYPE_CASE(114)
NETVALUETYPE_CASE(115) NETVALUETYPE_CASE(115)
NETVALUETYPE_CASE(116) NETVALUETYPE_CASE(116)
NETVALUETYPE_CASE(117)
NETVALUETYPE_CASE(118) NETVALUETYPE_CASE(118)
NETVALUETYPE_CASE(119) NETVALUETYPE_CASE(119)
NETVALUETYPE_CASE(120) NETVALUETYPE_CASE(120)
@ -199,8 +200,33 @@ Q_DECL_EXPORT int qqmlapplicationengine_registerType(NetTypeInfoContainer* typeC
NETVALUETYPE_CASE(123) NETVALUETYPE_CASE(123)
NETVALUETYPE_CASE(124) NETVALUETYPE_CASE(124)
NETVALUETYPE_CASE(125) NETVALUETYPE_CASE(125)
NETVALUETYPE_CASE(126)
NETVALUETYPE_CASE(127)
NETVALUETYPE_CASE(128)
NETVALUETYPE_CASE(129)
NETVALUETYPE_CASE(130)
NETVALUETYPE_CASE(131)
NETVALUETYPE_CASE(132)
NETVALUETYPE_CASE(133)
NETVALUETYPE_CASE(134)
NETVALUETYPE_CASE(135)
NETVALUETYPE_CASE(136)
NETVALUETYPE_CASE(137)
NETVALUETYPE_CASE(138)
NETVALUETYPE_CASE(139)
NETVALUETYPE_CASE(140)
NETVALUETYPE_CASE(141)
NETVALUETYPE_CASE(142)
NETVALUETYPE_CASE(143)
NETVALUETYPE_CASE(144)
NETVALUETYPE_CASE(145)
NETVALUETYPE_CASE(146)
NETVALUETYPE_CASE(147)
NETVALUETYPE_CASE(148)
NETVALUETYPE_CASE(149)
NETVALUETYPE_CASE(150)
} }
qFatal("Too many registered types"); qFatal("Too many registered types: %d", netValueTypeNumber);
return -1; return -1;
} }
@ -335,6 +361,7 @@ Q_DECL_EXPORT int qqmlapplicationengine_registerSingletonTypeNet(NetTypeInfoCont
NETVALUETYPESINGLETON_CASE(114) NETVALUETYPESINGLETON_CASE(114)
NETVALUETYPESINGLETON_CASE(115) NETVALUETYPESINGLETON_CASE(115)
NETVALUETYPESINGLETON_CASE(116) NETVALUETYPESINGLETON_CASE(116)
NETVALUETYPESINGLETON_CASE(117)
NETVALUETYPESINGLETON_CASE(118) NETVALUETYPESINGLETON_CASE(118)
NETVALUETYPESINGLETON_CASE(119) NETVALUETYPESINGLETON_CASE(119)
NETVALUETYPESINGLETON_CASE(120) NETVALUETYPESINGLETON_CASE(120)
@ -343,8 +370,33 @@ Q_DECL_EXPORT int qqmlapplicationengine_registerSingletonTypeNet(NetTypeInfoCont
NETVALUETYPESINGLETON_CASE(123) NETVALUETYPESINGLETON_CASE(123)
NETVALUETYPESINGLETON_CASE(124) NETVALUETYPESINGLETON_CASE(124)
NETVALUETYPESINGLETON_CASE(125) NETVALUETYPESINGLETON_CASE(125)
NETVALUETYPESINGLETON_CASE(126)
NETVALUETYPESINGLETON_CASE(127)
NETVALUETYPESINGLETON_CASE(128)
NETVALUETYPESINGLETON_CASE(129)
NETVALUETYPESINGLETON_CASE(130)
NETVALUETYPESINGLETON_CASE(131)
NETVALUETYPESINGLETON_CASE(132)
NETVALUETYPESINGLETON_CASE(133)
NETVALUETYPESINGLETON_CASE(134)
NETVALUETYPESINGLETON_CASE(135)
NETVALUETYPESINGLETON_CASE(136)
NETVALUETYPESINGLETON_CASE(137)
NETVALUETYPESINGLETON_CASE(138)
NETVALUETYPESINGLETON_CASE(139)
NETVALUETYPESINGLETON_CASE(140)
NETVALUETYPESINGLETON_CASE(141)
NETVALUETYPESINGLETON_CASE(142)
NETVALUETYPESINGLETON_CASE(143)
NETVALUETYPESINGLETON_CASE(144)
NETVALUETYPESINGLETON_CASE(145)
NETVALUETYPESINGLETON_CASE(146)
NETVALUETYPESINGLETON_CASE(147)
NETVALUETYPESINGLETON_CASE(148)
NETVALUETYPESINGLETON_CASE(149)
NETVALUETYPESINGLETON_CASE(150)
} }
qFatal("Too many registered types"); qFatal("Too many registered types: %d", netValueTypeNumber);
return -1; return -1;
} }

View file

@ -26,6 +26,15 @@ QSharedPointer<NetTypeInfo> NetTypeManager::getTypeInfo(const QString& typeName)
return typeInfo; return typeInfo;
} }
QSharedPointer<NetTypeInfo> NetTypeManager::getBaseType(QSharedPointer<NetTypeInfo> typeInfo)
{
auto baseType = typeInfo->getBaseType();
if(baseType.isNull() || baseType.isEmpty()) {
return nullptr;
}
return NetTypeManager::getTypeInfo(baseType);
}
extern "C" { extern "C" {
Q_DECL_EXPORT NetTypeInfoContainer* type_manager_getTypeInfo(LPWSTR fullTypeName) { Q_DECL_EXPORT NetTypeInfoContainer* type_manager_getTypeInfo(LPWSTR fullTypeName) {

View file

@ -10,6 +10,7 @@ class NetTypeManager {
public: public:
NetTypeManager(); NetTypeManager();
static QSharedPointer<NetTypeInfo> getTypeInfo(const QString& typeName); static QSharedPointer<NetTypeInfo> getTypeInfo(const QString& typeName);
static QSharedPointer<NetTypeInfo> getBaseType(QSharedPointer<NetTypeInfo> typeInfo);
private: private:
static QMap<QString, QSharedPointer<NetTypeInfo>> types; static QMap<QString, QSharedPointer<NetTypeInfo>> types;
}; };

View file

@ -33,7 +33,6 @@ namespace Qml.Net.Sandbox
{ {
public void Dispose() public void Dispose()
{ {
} }
public bool OnMessageWithTypes(IMessageSinkMessage message, HashSet<string> messageTypes) public bool OnMessageWithTypes(IMessageSinkMessage message, HashSet<string> messageTypes)

View file

@ -10,12 +10,12 @@
<ProjectReference Include="..\Qml.Net.Tests\Qml.Net.Tests.csproj" /> <ProjectReference Include="..\Qml.Net.Tests\Qml.Net.Tests.csproj" />
<ProjectReference Include="..\Qml.Net\Qml.Net.csproj" /> <ProjectReference Include="..\Qml.Net\Qml.Net.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Compile Remove="Program.Tests.cs" />
<None Include="Program.Tests.cs" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="xunit.core" Version="2.4.1" /> <PackageReference Include="xunit.core" Version="2.4.1" />
<PackageReference Include="xunit.runner.utility" Version="2.4.1" /> <PackageReference Include="xunit.runner.utility" Version="2.4.1" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Compile Remove="Program.UI.cs" />
<None Include="Program.UI.cs" />
</ItemGroup>
</Project> </Project>

View file

@ -35,7 +35,7 @@ namespace Qml.Net.Tests.Qml
public string SomeStringProperty public string SomeStringProperty
{ {
get => _someStringPropertyValue; get => _someStringPropertyValue;
set set
{ {
if (_someStringPropertyValue == value) if (_someStringPropertyValue == value)
return; return;
@ -50,7 +50,7 @@ namespace Qml.Net.Tests.Qml
public int SomeIntProperty public int SomeIntProperty
{ {
get => _someIntPropertyValue; get => _someIntPropertyValue;
set set
{ {
if (_someIntPropertyValue == value) if (_someIntPropertyValue == value)
return; return;
@ -63,14 +63,14 @@ namespace Qml.Net.Tests.Qml
public bool SomeBoolProperty public bool SomeBoolProperty
{ {
get get
{
return _someBoolPropertyValue;
}
set
{ {
if (_someBoolPropertyValue == value) return _someBoolPropertyValue;
}
set
{
if (_someBoolPropertyValue == value)
return; return;
_someBoolPropertyValue = value; _someBoolPropertyValue = value;
this.ActivateNotifySignal(); this.ActivateNotifySignal();
@ -91,6 +91,11 @@ namespace Qml.Net.Tests.Qml
{ {
} }
[Signal("derivedSignal")]
public class SignalObjectDerived : SignalObject
{
}
[Fact] [Fact]
public void Can_raise_signal_from_qml() public void Can_raise_signal_from_qml()
{ {
@ -372,5 +377,97 @@ namespace Qml.Net.Tests.Qml
paramResult.Should().NotBeNull(); paramResult.Should().NotBeNull();
paramResult.SomeStringProperty.Should().NotBeNull(param.SomeStringProperty); paramResult.SomeStringProperty.Should().NotBeNull(param.SomeStringProperty);
} }
[Fact]
public void Can_raise_base_signal_from_net_on_base_object_from_derived_object()
{
var o = new SignalObjectDerived();
Mock.Setup(x => x.SignalRaised).Returns(false);
Mock.Setup(x => x.GetSignalObject()).Returns(o);
Mock.Setup(x => x.TestMethod()).Callback(() =>
{
o.ActivateSignal("testSignal");
});
RunQmlTest(
"test",
@"
var instance = test.getSignalObject()
instance.testSignal.connect(function() {
test.signalRaised = true
})
test.testMethod()
");
Mock.VerifySet(x => x.SignalRaised = true, Times.Once);
}
[Fact]
public void Can_raise_derived_signal_from_net_on_base_object_from_derived_object()
{
var o = new SignalObjectDerived();
Mock.Setup(x => x.SignalRaised).Returns(false);
Mock.Setup(x => x.GetSignalObject()).Returns(o);
Mock.Setup(x => x.TestMethod()).Callback(() =>
{
o.ActivateSignal("derivedSignal");
});
RunQmlTest(
"test",
@"
var instance = test.getSignalObject()
instance.derivedSignal.connect(function() {
test.signalRaised = true
})
test.testMethod()
");
Mock.VerifySet(x => x.SignalRaised = true, Times.Once);
}
[Fact]
public void Can_raise_base_signal_from_qml_on_base_object_from_derived_object()
{
var o = new SignalObjectDerived();
Mock.Setup(x => x.SignalRaised).Returns(false);
Mock.Setup(x => x.GetSignalObject()).Returns(o);
Mock.Setup(x => x.TestMethod()).Callback(() =>
{
o.ActivateSignal("testSignal");
});
RunQmlTest(
"test",
@"
var instance = test.getSignalObject()
instance.testSignal.connect(function() {
test.signalRaised = true
})
test.testMethod()
");
Mock.VerifySet(x => x.SignalRaised = true, Times.Once);
}
[Fact]
public void Can_raise_derived_signal_from_qml_on_base_object_from_derived_object()
{
var o = new SignalObjectDerived();
Mock.Setup(x => x.SignalRaised).Returns(false);
Mock.Setup(x => x.GetSignalObject()).Returns(o);
Mock.Setup(x => x.TestMethod()).Callback(() =>
{
o.ActivateSignal("derivedSignal");
});
RunQmlTest(
"test",
@"
var instance = test.getSignalObject()
instance.derivedSignal.connect(function() {
test.signalRaised = true
})
test.testMethod()
");
Mock.VerifySet(x => x.SignalRaised = true, Times.Once);
}
} }
} }

View file

@ -471,5 +471,56 @@ namespace Qml.Net.Tests.Types
type.HasObjectDestroyed.Should().BeTrue(); type.HasObjectDestroyed.Should().BeTrue();
type.HasComponentCompleted.Should().BeFalse(); type.HasComponentCompleted.Should().BeFalse();
} }
public class TestType21
{
public void Method1()
{
}
}
public class TestType22 : TestType21
{
public void Method2()
{
}
}
[Fact]
public void Only_methods_on_class_are_returned()
{
var type1 = NetTypeManager.GetTypeInfo<TestType21>();
type1.EnsureLoaded();
type1.MethodCount.Should().Be(1);
type1.GetMethod(0).MethodName.Should().Be("Method1");
var type2 = NetTypeManager.GetTypeInfo<TestType22>();
type2.EnsureLoaded();
type2.MethodCount.Should().Be(1);
type2.GetMethod(0).MethodName.Should().Be("Method2");
}
[Signal("firstSignal")]
public class TestType23
{
}
[Signal("secondSignal")]
public class TestType24 : TestType23
{
}
[Fact]
public void Can_ignore_inherited_signals()
{
var type1 = NetTypeManager.GetTypeInfo<TestType23>();
type1.EnsureLoaded();
type1.SignalCount.Should().Be(1);
type1.GetSignal(0).Name.Should().Be("firstSignal");
var type2 = NetTypeManager.GetTypeInfo<TestType24>();
type2.EnsureLoaded();
type2.SignalCount.Should().Be(1);
type2.GetSignal(0).Name.Should().Be("secondSignal");
}
} }
} }

View file

@ -94,7 +94,7 @@ namespace Qml.Net.Internal
type.HasObjectDestroyed = true; type.HasObjectDestroyed = true;
} }
foreach (var methodInfo in typeInfo.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)) foreach (var methodInfo in typeInfo.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly))
{ {
if (methodInfo.IsGenericMethod) continue; // No generics supported. if (methodInfo.IsGenericMethod) continue; // No generics supported.
if (Helpers.IsPrimitive(methodInfo.DeclaringType)) continue; if (Helpers.IsPrimitive(methodInfo.DeclaringType)) continue;
@ -121,7 +121,7 @@ namespace Qml.Net.Internal
var signals = new Dictionary<string, NetSignalInfo>(); var signals = new Dictionary<string, NetSignalInfo>();
foreach (var signalAttribute in typeInfo.GetCustomAttributes().OfType<SignalAttribute>()) foreach (var signalAttribute in typeInfo.GetCustomAttributes(false).OfType<SignalAttribute>())
{ {
if (string.IsNullOrEmpty(signalAttribute.Name)) if (string.IsNullOrEmpty(signalAttribute.Name))
{ {

View file

@ -256,12 +256,12 @@ namespace Qml.Net
public static void SetAttribute(ApplicationAttribute attribute, bool on) public static void SetAttribute(ApplicationAttribute attribute, bool on)
{ {
Interop.QCoreApplication.SetAttribute((int) attribute, on); Interop.QCoreApplication.SetAttribute((int)attribute, on);
} }
public static bool TestAttribute(ApplicationAttribute attribute) public static bool TestAttribute(ApplicationAttribute attribute)
{ {
return Interop.QCoreApplication.TestAttribute((int) attribute) == 1; return Interop.QCoreApplication.TestAttribute((int)attribute) == 1;
} }
protected override void DisposeUnmanaged(IntPtr ptr) protected override void DisposeUnmanaged(IntPtr ptr)

View file

@ -65,6 +65,7 @@
<Rule Id="CA2242" Action="Warning" /> <Rule Id="CA2242" Action="Warning" />
</Rules> </Rules>
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers"> <Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers">
<Rule Id="SA1028" Action="None" />
<Rule Id="SA1008" Action="None" /> <Rule Id="SA1008" Action="None" />
<Rule Id="SA1009" Action="None" /> <Rule Id="SA1009" Action="None" />
<Rule Id="SA1101" Action="None" /> <Rule Id="SA1101" Action="None" />