<commit_before>//===--- ParseExpr.cpp - Swift Language Parser for Expressions ------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// Expression Parsing and AST Building
//
//===----------------------------------------------------------------------===//

#include "swift/Parse/Parser.h"
#include "swift/AST/Diagnostics.h"
#include "swift/Parse/CodeCompletionCallbacks.h"
#include "swift/Parse/Lexer.h"
#include "llvm/ADT/Twine.h"
#include "swift/Basic/Fallthrough.h"
#include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/raw_ostream.h"

using namespace swift;

/// \brief Create an argument with a trailing closure, with (optionally)
/// the elements, names, and parentheses locations from an existing argument.
static Expr *createArgWithTrailingClosure(ASTContext &context,
                                          SourceLoc leftParen,
                                          ArrayRef<Expr *> elementsIn,
                                          Identifier *namesIn,
                                          SourceLoc rightParen,
                                          Expr *closure) {
  // If there are no elements, just build a parenthesized expression around
  // the cosure.
  if (elementsIn.empty()) {
    return new (context) ParenExpr(leftParen, closure, rightParen,
                                   /*hasTrailingClosure=*/true);
  }

  // Create the list of elements, and add the trailing closure to the end.
  SmallVector<Expr *, 4> elements(elementsIn.begin(), elementsIn.end());
  elements.push_back(closure);

  Identifier *names = nullptr;
  if (namesIn) {
    names = context.Allocate<Identifier>(elements.size());
    std::copy(namesIn, namesIn + elements.size() - 1, names);
    new (namesIn + elements.size() - 1) Identifier();
  }

  // Form a full tuple expression.
  return new (context) TupleExpr(leftParen, context.AllocateCopy(elements),
                                 names, rightParen,
                                 /*hasTrailingClosure=*/true,
                                 /*Implicit=*/false);
}

/// \brief Add the given trailing closure argument to the call argument.
static Expr *addTrailingClosureToArgument(ASTContext &context,
                                          Expr *arg, Expr *closure) {
  // Deconstruct the call argument to find its elements, element names,
  // and the locations of the left and right parentheses.
  if (auto tuple = dyn_cast<TupleExpr>(arg)) {
    // Deconstruct a tuple expression.
    return createArgWithTrailingClosure(context,
                                        tuple->getLParenLoc(),
                                        tuple->getElements(),
                                        tuple->getElementNames(),
                                        tuple->getRParenLoc(),
                                        closure);
  }

  // Deconstruct a parenthesized expression.
  auto paren = dyn_cast<ParenExpr>(arg);
  return createArgWithTrailingClosure(context,
                                      paren->getLParenLoc(),
                                      paren->getSubExpr(),
                                      nullptr,
                                      paren->getRParenLoc(), closure);
}

/// \brief Determine whether the given expression is an expr-postfix.
///
/// This routine inspects the form of an expression AST to determine whether it
/// was produced by parsing an expr-postfix, e.g., a call, member access, or
/// primary expression such as a parenthesized expression or tuple.
static bool isExprPostfix(Expr *expr) {
  switch (expr->getKind()) {
  // Not postfix expressions.
  case ExprKind::AddressOf:
  case ExprKind::PostfixUnary:
  case ExprKind::PrefixUnary:
  case ExprKind::Sequence:
  case ExprKind::Isa:
  case ExprKind::ConditionalCheckedCast:
  case ExprKind::UnconditionalCheckedCast:
  case ExprKind::Assign:
  case ExprKind::UnresolvedPattern:
  case ExprKind::BindOptional:
  case ExprKind::OptionalEvaluation:
    return false;

  // Postfix expressions.
  case ExprKind::Array:
  case ExprKind::Call:
  case ExprKind::CharacterLiteral:
  case ExprKind::DeclRef:
  case ExprKind::Dictionary:
  case ExprKind::DynamicMemberRef:
  case ExprKind::FloatLiteral:
  case ExprKind::MemberRef:
  case ExprKind::Metatype:
  case ExprKind::Module:
  case ExprKind::NewArray:
  case ExprKind::OverloadedDeclRef:
  case ExprKind::Paren:
  case ExprKind::Closure:
  case ExprKind::RebindSelfInConstructor:
  case ExprKind::IntegerLiteral:
  case ExprKind::StringLiteral:
  case ExprKind::MagicIdentifierLiteral:
  case ExprKind::InterpolatedStringLiteral:
  case ExprKind::Subscript:
  case ExprKind::SuperRef:
  case ExprKind::Tuple:
  case ExprKind::UnresolvedConstructor:
  case ExprKind::UnresolvedDeclRef:
  case ExprKind::UnresolvedDot:
  case ExprKind::UnresolvedMember:
  case ExprKind::UnresolvedSpecialize:
    return true;

  // Can't occur in the parser.
  case ExprKind::ArchetypeToSuper:
  case ExprKind::ArchetypeMemberRef:
  case ExprKind::ArchetypeSubscript:
  case ExprKind::Binary:
  case ExprKind::InjectIntoOptional:
  case ExprKind::BridgeToBlock:
  case ExprKind::ConstructorRefCall:
  case ExprKind::DefaultValue:
  case ExprKind::DerivedToBase:
  case ExprKind::DotSyntaxBaseIgnored:
  case ExprKind::DotSyntaxCall:
  case ExprKind::DynamicSubscript:
  case ExprKind::Erasure:
  case ExprKind::ExistentialMemberRef:
  case ExprKind::ExistentialSubscript:
  case ExprKind::FunctionConversion:
  case ExprKind::If:
  case ExprKind::AutoClosure:
  case ExprKind::Load:
  case ExprKind::Materialize:
  case ExprKind::MetatypeConversion:
  case ExprKind::OpaqueValue:
  case ExprKind::OtherConstructorDeclRef:
  case ExprKind::OverloadedMemberRef:
  case ExprKind::Requalify:
  case ExprKind::ScalarToTuple:
  case ExprKind::Specialize:
  case ExprKind::TupleElement:
  case ExprKind::TupleShuffle:
  case ExprKind::ZeroValue:
    llvm_unreachable("Not a parsed expression");

  // Treat error cases as postfix expressions.
  case ExprKind::Error:
    return true;
  }
}

/// parseExpr
///
///   expr:
///     expr-sequence(basic | trailing-closure)
///
/// \param isExprBasic Whether we're only parsing an expr-basic.
ParserResult<Expr> Parser::parseExpr(Diag<> Message, bool isExprBasic) {
  // If we see a pattern in expr position, parse it to an UnresolvedPatternExpr.
  // Name binding will resolve whether it's in a valid pattern position.
  if (isOnlyStartOfMatchingPattern()) {
    ParserResult<Pattern> pattern = parseMatchingPattern();
    if (pattern.hasCodeCompletion())
      return makeParserCodeCompletionResult<Expr>();
    if (pattern.isNull())
      return nullptr;
    return makeParserResult(new (Context) UnresolvedPatternExpr(pattern.get()));
  }
  
  ParserResult<Expr> expr = parseExprSequence(Message, isExprBasic);
  if (expr.hasCodeCompletion())
    return makeParserCodeCompletionResult<Expr>();
  if (expr.isNull())
    return nullptr;
  
  // If we got a bare identifier inside a 'var' pattern, it forms a variable
  // binding pattern. Raise an error if the identifier shadows an existing
  // binding.
  //<commit_msg>Remove unused function.<commit_after>//===--- ParseExpr.cpp - Swift Language Parser for Expressions ------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// Expression Parsing and AST Building
//
//===----------------------------------------------------------------------===//

#include "swift/Parse/Parser.h"
#include "swift/AST/Diagnostics.h"
#include "swift/Parse/CodeCompletionCallbacks.h"
#include "swift/Parse/Lexer.h"
#include "llvm/ADT/Twine.h"
#include "swift/Basic/Fallthrough.h"
#include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/raw_ostream.h"

using namespace swift;

/// \brief Create an argument with a trailing closure, with (optionally)
/// the elements, names, and parentheses locations from an existing argument.
static Expr *createArgWithTrailingClosure(ASTContext &context,
                                          SourceLoc leftParen,
                                          ArrayRef<Expr *> elementsIn,
                                          Identifier *namesIn,
                                          SourceLoc rightParen,
                                          Expr *closure) {
  // If there are no elements, just build a parenthesized expression around
  // the cosure.
  if (elementsIn.empty()) {
    return new (context) ParenExpr(leftParen, closure, rightParen,
                                   /*hasTrailingClosure=*/true);
  }

  // Create the list of elements, and add the trailing closure to the end.
  SmallVector<Expr *, 4> elements(elementsIn.begin(), elementsIn.end());
  elements.push_back(closure);

  Identifier *names = nullptr;
  if (namesIn) {
    names = context.Allocate<Identifier>(elements.size());
    std::copy(namesIn, namesIn + elements.size() - 1, names);
    new (namesIn + elements.size() - 1) Identifier();
  }

  // Form a full tuple expression.
  return new (context) TupleExpr(leftParen, context.AllocateCopy(elements),
                                 names, rightParen,
                                 /*hasTrailingClosure=*/true,
                                 /*Implicit=*/false);
}

/// \brief Add the given trailing closure argument to the call argument.
static Expr *addTrailingClosureToArgument(ASTContext &context,
                                          Expr *arg, Expr *closure) {
  // Deconstruct the call argument to find its elements, element names,
  // and the locations of the left and right parentheses.
  if (auto tuple = dyn_cast<TupleExpr>(arg)) {
    // Deconstruct a tuple expression.
    return createArgWithTrailingClosure(context,
                                        tuple->getLParenLoc(),
                                        tuple->getElements(),
                                        tuple->getElementNames(),
                                        tuple->getRParenLoc(),
                                        closure);
  }

  // Deconstruct a parenthesized expression.
  auto paren = dyn_cast<ParenExpr>(arg);
  return createArgWithTrailingClosure(context,
                                      paren->getLParenLoc(),
                                      paren->getSubExpr(),
                                      nullptr,
                                      paren->getRParenLoc(), closure);
}

/// parseExpr
///
///   expr:
///     expr-sequence(basic | trailing-closure)
///
/// \param isExprBasic Whether we're only parsing an expr-basic.
ParserResult<Expr> Parser::parseExpr(Diag<> Message, bool isExprBasic) {
  // If we see a pattern in expr position, parse it to an UnresolvedPatternExpr.
  // Name binding will resolve whether it's in a valid pattern position.
  if (isOnlyStartOfMatchingPattern()) {
    ParserResult<Pattern> pattern = parseMatchingPattern();
    if (pattern.hasCodeCompletion())
      return makeParserCodeCompletionResult<Expr>();
    if (pattern.isNull())
      return nullptr;
    return makeParserResult(new (Context) UnresolvedPatternExpr(pattern.get()));
  }
  
  ParserResult<Expr> expr = parseExprSequence(Message, isExprBasic);
  if (expr.hasCodeCompletion())
    return makeParserCodeCompletionResult<Expr>();
  if (expr.isNull())
    return nullptr;
  
  // If we got a bare identifier inside a 'var' pattern, it forms a variable
  // binding pattern. Raise an error if the identifier shadows an existing
  // binding.
  //
{'fraction_non_alphanumeric': 0.12518433557266917, 'fraction_numerical': 0.002130099950843847, 'mean_word_length': 2.3180212014134276, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 40, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 50, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1271586', 'n_tokens_mistral': 3260, 'n_tokens_neox': 3155, 'n_words': 903}