PythonTreeMaker { public Expression expression(AstNode astNode) { if (astNode.is(PythonGrammar.ATOM) && astNode.getFirstChild().is(PythonPunctuator.LBRACKET)) { return listLiteral(astNode); } if (astNode.is(PythonGrammar.ATOM) && astNode.getFirstChild().is(PythonPunctuator.LPARENTHESIS)) { return parenthesized(astNode); } if (astNode.is(PythonGrammar.ATOM) && astNode.getFirstChild().is(PythonPunctuator.LCURLYBRACE)) { return dictOrSetLiteral(astNode); } if (astNode.is(PythonGrammar.ATOM) && astNode.getFirstChild().is(PythonPunctuator.BACKTICK)) { return repr(astNode); } if (astNode.is(PythonGrammar.ATOM) && astNode.getFirstChild().is(PythonTokenType.STRING)) { return stringLiteral(astNode); } if (astNode.is(PythonGrammar.ATOM) && astNode.getChildren().size() == 1) { return expression(astNode.getFirstChild()); } if (astNode.is(PythonGrammar.TEST) && astNode.hasDirectChildren(PythonKeyword.IF)) { return conditionalExpression(astNode); } if (astNode.is(PythonTokenType.NUMBER)) { return numericLiteral(astNode); } if (astNode.is(PythonGrammar.YIELD_EXPR)) { return yieldExpression(astNode); } if (astNode.is(PythonGrammar.NAME)) { return name(astNode); } if (astNode.is(PythonGrammar.NAMED_EXPR_TEST) && astNode.hasDirectChildren(PythonPunctuator.WALRUS_OPERATOR)) { return assignmentExpression(astNode); } if (astNode.is(PythonGrammar.EXPR, PythonGrammar.NAMED_EXPR_TEST, PythonGrammar.TEST, PythonGrammar.TEST_NOCOND)) { if (astNode.getChildren().size() == 1) { return expression(astNode.getFirstChild()); } else { return binaryExpression(astNode); } } if (astNode.is( PythonGrammar.A_EXPR, PythonGrammar.M_EXPR, PythonGrammar.SHIFT_EXPR, PythonGrammar.AND_EXPR, PythonGrammar.OR_EXPR, PythonGrammar.XOR_EXPR, PythonGrammar.AND_TEST, PythonGrammar.OR_TEST, PythonGrammar.COMPARISON)) { return binaryExpression(astNode); } if (astNode.is(PythonGrammar.POWER)) { return powerExpression(astNode); } if (astNode.is(PythonGrammar.LAMBDEF, PythonGrammar.LAMBDEF_NOCOND)) { return lambdaExpression(astNode); } if (astNode.is(PythonGrammar.FACTOR, PythonGrammar.NOT_TEST)) { return new UnaryExpressionImpl(toPyToken(astNode.getFirstChild().getToken()), expression(astNode.getLastChild())); } if (astNode.is(PythonGrammar.STAR_EXPR)) { return new UnpackingExpressionImpl(toPyToken(astNode.getToken()), expression(astNode.getLastChild())); } if (astNode.is(PythonKeyword.NONE)) { return new NoneExpressionImpl(toPyToken(astNode.getToken())); } if (astNode.is(PythonGrammar.ELLIPSIS)) { return new EllipsisExpressionImpl(toPyToken(astNode.getTokens())); } if (astNode.is(PythonGrammar.TESTLIST_STAR_EXPR)) { return exprListOrTestList(astNode); } throw new IllegalStateException("Expression " + astNode.getType() + " not correctly translated to strongly typed AST"); }  FileInput fileInput(AstNode astNode); void setParents(Tree root); AnnotatedAssignment annotatedAssignment(StatementWithSeparator statementWithSeparator); PrintStatement printStatement(StatementWithSeparator statementWithSeparator); ExecStatement execStatement(StatementWithSeparator statementWithSeparator); AssertStatement assertStatement(StatementWithSeparator statementWithSeparator); PassStatement passStatement(StatementWithSeparator statementWithSeparator); DelStatement delStatement(StatementWithSeparator statementWithSeparator); ReturnStatement returnStatement(StatementWithSeparator statementWithSeparator); YieldStatement yieldStatement(StatementWithSeparator statementWithSeparator); YieldExpression yieldExpression(AstNode astNode); RaiseStatement raiseStatement(StatementWithSeparator statementWithSeparator); BreakStatement breakStatement(StatementWithSeparator statementWithSeparator); ContinueStatement continueStatement(StatementWithSeparator statementWithSeparator); ImportStatement importStatement(StatementWithSeparator statementWithSeparator); GlobalStatement globalStatement(StatementWithSeparator statementWithSeparator); NonlocalStatement nonlocalStatement(StatementWithSeparator statementWithSeparator); IfStatement ifStatement(AstNode astNode); FunctionDef funcDefStatement(AstNode astNode); ClassDef classDefStatement(AstNode astNode); ForStatement forStatement(AstNode astNode); WhileStatementImpl whileStatement(AstNode astNode); ExpressionStatement expressionStatement(StatementWithSeparator statementWithSeparator); AssignmentStatement assignment(StatementWithSeparator statementWithSeparator); CompoundAssignmentStatement compoundAssignment(StatementWithSeparator statementWithSeparator); TryStatement tryStatement(AstNode astNode); WithStatement withStatement(AstNode astNode); Expression expression(AstNode astNode); Argument argument(AstNode astNode); LambdaExpression lambdaExpression(AstNode astNode);  }
@Test public void starred_expression() { setRootRule(PythonGrammar.STAR_EXPR); UnpackingExpression starred = (UnpackingExpression) parse("*a", treeMaker::expression); assertThat(starred.getKind()).isEqualTo(Tree.Kind.UNPACKING_EXPR); assertThat(starred.starToken().value()).isEqualTo("*"); assertThat(starred.expression().getKind()).isEqualTo(Tree.Kind.NAME); assertThat(starred.children()).hasSize(2); }
@Test public void string_interpolation_equal_specifier() { setRootRule(PythonGrammar.ATOM); Expression exp = parse("F'{bar=}'", treeMaker::expression); StringLiteral stringLiteral = (StringLiteral) exp; assertThat(stringLiteral.stringElements()).hasSize(1); StringElement elmt = stringLiteral.stringElements().get(0); assertThat(elmt.isInterpolated()).isTrue(); assertThat(elmt.formattedExpressions()).hasSize(1); FormattedExpression formattedExpression = elmt.formattedExpressions().get(0); assertThat(formattedExpression.expression().is(Kind.NAME)).isTrue(); Token equalToken = formattedExpression.equalToken(); assertThat(equalToken).isNotNull(); assertThat(equalToken.value()).isEqualTo("="); exp = parse("F'{foo=} and {bar}'", treeMaker::expression); stringLiteral = (StringLiteral) exp; assertThat(stringLiteral.stringElements()).hasSize(1); elmt = stringLiteral.stringElements().get(0); assertThat(elmt.isInterpolated()).isTrue(); assertThat(elmt.formattedExpressions()).hasSize(2); FormattedExpression formattedFoo = elmt.formattedExpressions().get(0); assertThat(formattedFoo.expression().is(Kind.NAME)).isTrue(); assertThat(formattedFoo.equalToken()).isNotNull(); FormattedExpression formattedBar = elmt.formattedExpressions().get(1); assertThat(formattedBar.expression().is(Kind.NAME)).isTrue(); assertThat(formattedBar.equalToken()).isNull(); }
@Test public void multiline_string_literal_expression() { setRootRule(PythonGrammar.ATOM); Expression parse = parse("('Hello \\ ' #Noncompliant\n 'world')", treeMaker::expression); assertThat(parse.is(Tree.Kind.PARENTHESIZED)).isTrue(); ParenthesizedExpression parenthesized = (ParenthesizedExpression) parse; assertThat(parenthesized.expression().is(Tree.Kind.STRING_LITERAL)).isTrue(); StringLiteral pyStringLiteralTree = (StringLiteral) parenthesized.expression(); assertThat(pyStringLiteralTree.children()).hasSize(2); assertThat(pyStringLiteralTree.stringElements().size()).isEqualTo(2); assertThat(pyStringLiteralTree.stringElements().get(0).value()).isEqualTo("\'Hello \\ '"); StringElement firstElement = pyStringLiteralTree.stringElements().get(0); StringElement secondElement = pyStringLiteralTree.stringElements().get(1); assertThat(secondElement.value()).isEqualTo("'world'"); assertThat(firstElement.trimmedQuotesValue()).isEqualTo("Hello \\ "); assertThat(secondElement.trimmedQuotesValue()).isEqualTo("world"); }
@Test public void parenthesized_expression() { setRootRule(PythonGrammar.TEST); ParenthesizedExpression parenthesized = (ParenthesizedExpression) parse("(42)", treeMaker::expression); assertThat(parenthesized.getKind()).isEqualTo(Tree.Kind.PARENTHESIZED); assertThat(parenthesized.children()).hasSize(3); assertThat(parenthesized.leftParenthesis().value()).isEqualTo("("); assertThat(parenthesized.rightParenthesis().value()).isEqualTo(")"); assertThat(parenthesized.expression().getKind()).isEqualTo(Tree.Kind.NUMERIC_LITERAL); parenthesized = (ParenthesizedExpression) parse("(yield 42)", treeMaker::expression); assertThat(parenthesized.expression().getKind()).isEqualTo(Tree.Kind.YIELD_EXPR); }
@Test public void generator_expression() { setRootRule(PythonGrammar.TEST); ComprehensionExpression generator = (ComprehensionExpression) parse("(x*x for x in range(10))", treeMaker::expression); assertThat(generator.getKind()).isEqualTo(Tree.Kind.GENERATOR_EXPR); assertThat(generator.children()).hasSize(4); assertThat(generator.children().get(0)).isEqualTo(generator.firstToken()); assertThat(generator.children().get(3)).isEqualTo(generator.lastToken()); assertThat(generator.firstToken().value()).isEqualTo("("); assertThat(generator.lastToken().value()).isEqualTo(")"); assertThat(generator.resultExpression().getKind()).isEqualTo(Tree.Kind.MULTIPLICATION); assertThat(generator.comprehensionFor().iterable().getKind()).isEqualTo(Tree.Kind.CALL_EXPR); CallExpression call = (CallExpression) parse("foo(x*x for x in range(10))", treeMaker::expression); assertThat(call.arguments()).hasSize(1); Expression firstArg = ((RegularArgument) call.arguments().get(0)).expression(); assertThat(firstArg.getKind()).isEqualTo(Tree.Kind.GENERATOR_EXPR); call = (CallExpression) parse("foo((x*x for x in range(10)))", treeMaker::expression); assertThat(call.arguments()).hasSize(1); firstArg = ((RegularArgument) call.arguments().get(0)).expression(); assertThat(firstArg.getKind()).isEqualTo(Tree.Kind.GENERATOR_EXPR); try { parse("foo(1, x*x for x in range(10))", treeMaker::expression); fail("generator expression must be parenthesized unless it's the unique argument in arglist"); } catch (RecognitionException re) { assertThat(re).hasMessage("Parse error at line 1: Generator expression must be parenthesized if not sole argument."); } }
@Test public void not() { setRootRule(PythonGrammar.TEST); Expression exp = parse("not 1", treeMaker::expression); assertThat(exp).isInstanceOf(UnaryExpression.class); assertThat(exp.getKind()).isEqualTo(Tree.Kind.NOT); assertThat(((UnaryExpression) exp).expression().is(Tree.Kind.NUMERIC_LITERAL)).isTrue(); }
@Test public void dictionary_literal() { setRootRule(PythonGrammar.ATOM); DictionaryLiteral tree = (DictionaryLiteral) parse("{'key': 'value'}", treeMaker::expression); assertThat(tree.firstToken().value()).isEqualTo("{"); assertThat(tree.lastToken().value()).isEqualTo("}"); assertThat(tree.getKind()).isEqualTo(Tree.Kind.DICTIONARY_LITERAL); assertThat(tree.elements()).hasSize(1); KeyValuePair keyValuePair = (KeyValuePair) tree.elements().iterator().next(); assertThat(keyValuePair.getKind()).isEqualTo(Tree.Kind.KEY_VALUE_PAIR); assertThat(keyValuePair.key().getKind()).isEqualTo(Tree.Kind.STRING_LITERAL); assertThat(keyValuePair.colon().value()).isEqualTo(":"); assertThat(keyValuePair.value().getKind()).isEqualTo(Tree.Kind.STRING_LITERAL); assertThat(tree.children()).hasSize(3).containsExactly(tree.lCurlyBrace(), tree.elements().get(0), tree.rCurlyBrace()); tree = (DictionaryLiteral) parse("{'key': 'value', 'key2': 'value2'}", treeMaker::expression); assertThat(tree.elements()).hasSize(2); assertThat(tree.children()).hasSize(5).containsExactly(tree.lCurlyBrace(), tree.elements().get(0), tree.commas().get(0), tree.elements().get(1), tree.rCurlyBrace()); tree = (DictionaryLiteral) parse("{** var}", treeMaker::expression); assertThat(tree.elements()).hasSize(1); UnpackingExpression dictUnpacking = (UnpackingExpression) tree.elements().iterator().next(); assertThat(dictUnpacking.expression().getKind()).isEqualTo(Tree.Kind.NAME); assertThat(dictUnpacking.starToken().value()).isEqualTo("**"); tree = (DictionaryLiteral) parse("{** var, key: value}", treeMaker::expression); assertThat(tree.elements()).hasSize(2); }