TreeUtils { @CheckForNull public static FunctionSymbol getFunctionSymbolFromDef(@Nullable FunctionDef functionDef) { if (functionDef == null) { return null; } Symbol functionNameSymbol = functionDef.name().symbol(); if (functionNameSymbol == null) { throw new IllegalStateException("A FunctionDef should always have a non-null symbol!"); } if (functionNameSymbol.kind() == Symbol.Kind.FUNCTION) { return ((FunctionSymbol) functionNameSymbol); } return null; } private  TreeUtils(); @CheckForNull static Tree firstAncestor(Tree tree, Predicate<Tree> predicate); @CheckForNull static Tree firstAncestorOfKind(Tree tree, Kind... kinds); static List<Token> tokens(Tree tree); static List<Token> nonWhitespaceTokens(Tree tree); static boolean hasDescendant(Tree tree, Predicate<Tree> predicate); static Stream<Expression> flattenTuples(Expression expression); static Optional<Symbol> getSymbolFromTree(@Nullable Tree tree); @CheckForNull static ClassSymbol getClassSymbolFromDef(@Nullable ClassDef classDef); @CheckForNull static FunctionSymbol getFunctionSymbolFromDef(@Nullable FunctionDef functionDef); static List<Parameter> nonTupleParameters(FunctionDef functionDef); static List<Parameter> positionalParameters(FunctionDef functionDef); static List<FunctionDef> topLevelFunctionDefs(ClassDef classDef); @CheckForNull static RegularArgument argumentByKeyword(String keyword, List<Argument> arguments); @CheckForNull static RegularArgument nthArgumentOrKeyword(int argPosition, String keyword, List<Argument> arguments); static boolean isBooleanLiteral(Tree tree); static String nameFromExpression(Expression expression); @CheckForNull static LocationInFile locationInFile(Tree tree, @Nullable String fileId);  }
@Test public void getFunctionSymbolFromDef() { FileInput fileInput = PythonTestUtils.parse("def foo(): pass"); FunctionDef functionDef = PythonTestUtils.getLastDescendant(fileInput, t -> t.is(Kind.FUNCDEF)); Symbol symbolFoo = functionDef.name().symbol(); assertThat(TreeUtils.getFunctionSymbolFromDef(functionDef)).isEqualTo(symbolFoo); assertThat(TreeUtils.getFunctionSymbolFromDef(null)).isNull(); fileInput = PythonTestUtils.parse( "def foo():", " pass", "foo = 42" ); functionDef = PythonTestUtils.getLastDescendant(fileInput, t -> t.is(Kind.FUNCDEF)); assertThat(TreeUtils.getFunctionSymbolFromDef(functionDef)).isNull(); }
@Test(expected = IllegalStateException.class) public void getFunctionSymbolFromDef_illegalSymbol() { FileInput fileInput = PythonTestUtils.parseWithoutSymbols("def foo(): pass"); FunctionDef functionDef = PythonTestUtils.getLastDescendant(fileInput, t -> t.is(Kind.FUNCDEF)); TreeUtils.getFunctionSymbolFromDef(functionDef); }