diff --git a/src/pipes/type_inferrer.cpp b/src/pipes/type_inferrer.cpp index dd715e3..8b17855 100644 --- a/src/pipes/type_inferrer.cpp +++ b/src/pipes/type_inferrer.cpp @@ -734,11 +734,14 @@ namespace X::Pipes { } auto methodTypeIt = methodTypesIt->second.find(methodName); - // second condition is for case when we call non-static method from static context - if (methodTypeIt == methodTypesIt->second.cend() || (!methodTypeIt->second.isStatic && isStatic)) { + if (methodTypeIt == methodTypesIt->second.cend()) { throw TypeInferrerException(fmt::format("method {}::{} not found", className, methodName)); } + if (methodTypeIt->second.isStatic != isStatic) { + throw TypeInferrerException(fmt::format("wrong method call {}::{}", className, methodName)); + } + return methodTypeIt->second; } @@ -751,11 +754,14 @@ namespace X::Pipes { } auto propTypeIt = classPropsIt->second.find(propName); - // second condition is for case when we get non-static prop from static context - if (propTypeIt == classPropsIt->second.cend() || (!propTypeIt->second.isStatic && isStatic)) { + if (propTypeIt == classPropsIt->second.cend()) { throw TypeInferrerException(fmt::format("prop {}::{} not found", klassName, propName)); } + if (propTypeIt->second.isStatic != isStatic) { + throw TypeInferrerException(fmt::format("wrong prop access {}::{}", klassName, propName)); + } + return propTypeIt->second.type; } diff --git a/tests/type_inferrer_test.cpp b/tests/type_inferrer_test.cpp index 25571f5..79281ef 100644 --- a/tests/type_inferrer_test.cpp +++ b/tests/type_inferrer_test.cpp @@ -271,5 +271,57 @@ fn main() void { fn foo() self { } )code", - "invalid type") + "invalid type"), + // call non-static method as static + std::make_pair( + R"code( +class Foo { + public fn a() void {} +} + +fn main() void { + Foo::a() +} +)code", + "wrong method call Foo::a"), + // call static method as non-static + std::make_pair( + R"code( +class Foo { + public static fn a() void {} +} + +fn main() void { + Foo foo = new Foo() + + foo.a() +} +)code", + "wrong method call Foo::a"), + // fetch non-static prop as static + std::make_pair( + R"code( +class Foo { + public int a +} + +fn main() void { + println(Foo::a) +} +)code", + "wrong prop access Foo::a"), + // fetch static prop as non-static + std::make_pair( + R"code( +class Foo { + public static int a +} + +fn main() void { + Foo foo = new Foo() + + println(foo.a) +} +)code", + "wrong prop access Foo::a") ));