SymbolUtils { public static Optional<FunctionSymbol> getOverriddenMethod(FunctionSymbol functionSymbol) { Symbol owner = ((FunctionSymbolImpl) functionSymbol).owner(); if (owner == null || owner.kind() != CLASS) { return Optional.empty(); } ClassSymbol classSymbol = (ClassSymbol) owner; if (classSymbol.superClasses().isEmpty()) { return Optional.empty(); } for (Symbol superClass : classSymbol.superClasses()) { if (superClass.kind() == CLASS) { Optional<FunctionSymbol> overriddenSymbol = ((ClassSymbol) superClass).resolveMember(functionSymbol.name()) .filter(symbol -> symbol.kind() == FUNCTION) .map(FunctionSymbol.class::cast); if (overriddenSymbol.isPresent()) { return overriddenSymbol; } } } return Optional.empty(); } private  SymbolUtils(); static String getModuleFileName(String fileName); static String fullyQualifiedModuleName(String packageName, String fileName); static List<Expression> assignmentsLhs(AssignmentStatement assignmentStatement); static String pythonPackageName(File file, File projectBaseDir); @CheckForNull static Path pathOf(PythonFile pythonFile); static boolean isTypeShedFile(PythonFile pythonFile); static int firstParameterOffset(FunctionSymbol functionSymbol, boolean isStaticCall); static Optional<FunctionSymbol> getOverriddenMethod(FunctionSymbol functionSymbol);  }
@Test public void get_overridden_method() { FileInput file = PythonTestUtils.parse( new SymbolTableBuilder("my_package", pythonFile("my_module.py")), "def foo(): pass", "def foo2():", " def foo3(): pass", "class A:", " def foo4(): pass", "class B:", " def foo5(): pass", " foo_int: int", "class C(B):", " def foo5(): pass", " def foo6(): pass", " def foo_int(): pass", "class D(object):", " def foo7(): pass", "class E(foo2):", " def foo8(): pass" ); FunctionSymbol foo = (FunctionSymbol) descendantFunction(file, "foo").name().symbol(); FunctionSymbol foo2 = (FunctionSymbol) descendantFunction(file, "foo2").name().symbol(); FunctionSymbol foo3 = (FunctionSymbol) descendantFunction(file, "foo3").name().symbol(); FunctionSymbol foo4 = (FunctionSymbol) descendantFunction(file, "foo4").name().symbol(); FunctionSymbol foo5 = (FunctionSymbol) descendantFunction(file, "foo5").name().symbol(); FunctionSymbol foo5_override = (FunctionSymbol) ((FunctionDef) ((ClassDefImpl)file.statements().statements().get(4)).body().statements().get(0)).name().symbol(); FunctionSymbol foo6 = (FunctionSymbol) descendantFunction(file, "foo6").name().symbol(); FunctionSymbol foo7 = (FunctionSymbol) descendantFunction(file, "foo7").name().symbol(); FunctionSymbol foo8 = (FunctionSymbol) descendantFunction(file, "foo8").name().symbol(); FunctionSymbol foo_int = (FunctionSymbol) descendantFunction(file, "foo_int").name().symbol(); assertThat(SymbolUtils.getOverriddenMethod(foo)).isEmpty(); assertThat(SymbolUtils.getOverriddenMethod(foo2)).isEmpty(); assertThat(SymbolUtils.getOverriddenMethod(foo3)).isEmpty(); assertThat(SymbolUtils.getOverriddenMethod(foo4)).isEmpty(); assertThat(SymbolUtils.getOverriddenMethod(foo5)).isEmpty(); assertThat(SymbolUtils.getOverriddenMethod(foo5_override).get()).isEqualTo(foo5); assertThat(SymbolUtils.getOverriddenMethod(foo6)).isEmpty(); assertThat(SymbolUtils.getOverriddenMethod(foo7)).isEmpty(); assertThat(SymbolUtils.getOverriddenMethod(foo8)).isEmpty(); assertThat(SymbolUtils.getOverriddenMethod(foo_int)).isEmpty(); }