//===--- ParseDecl.cpp - Swift Language Parser for #if directives -- ------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// Conditional Compilation Block Parsing and AST Building
//
//===----------------------------------------------------------------------===//

#include "swift/Parse/Parser.h"
#include "swift/Basic/Defer.h"
#include "swift/Basic/LangOptions.h"
#include "swift/Basic/Version.h"
#include "swift/Parse/Lexer.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/SaveAndRestore.h"

using namespace swift;

/// Parse and populate a list of #if/#elseif/#else/#endif clauses.
/// Delegate callback function to parse elements in the blocks.
template <typename ElemTy, unsigned N>
static ParserStatus parseIfConfig(
    Parser &P, SmallVectorImpl<IfConfigClause<ElemTy>> &Clauses,
    SourceLoc &EndLoc, bool HadMissingEnd,
    llvm::function_ref<void(SmallVectorImpl<ElemTy> &, bool)> parseElements) {
  Parser::StructureMarkerRAII ParsingDecl(
      P, P.Tok.getLoc(), Parser::StructureMarkerKind::IfConfig);

  bool foundActive = false;
  ConditionalCompilationExprState ConfigState;
  while (1) {
    bool isElse = P.Tok.is(tok::pound_else);
    SourceLoc ClauseLoc = P.consumeToken();
    Expr *Condition = nullptr;

    // Parse and evaluate the directive.
    if (isElse) {
      ConfigState.setConditionActive(!foundActive);
    } else {
      llvm::SaveAndRestore<bool> S(P.InPoundIfEnvironment, true);
      ParserResult<Expr> Result = P.parseExprSequence(diag::expected_expr,
                                                      /*isBasic*/true,
                                                      /*isForDirective*/true);
      if (Result.isNull())
        return makeParserError();

      Condition = Result.get();

      // Evaluate the condition, to validate it.
      ConfigState = P.classifyConditionalCompilationExpr(Condition, P.Context,
                                                         P.Diags);
      if (foundActive)
        ConfigState.setConditionActive(false);
    }

    foundActive |= ConfigState.isConditionActive();

    if (!P.Tok.isAtStartOfLine() && P.Tok.isNot(tok::eof)) {
      P.diagnose(P.Tok.getLoc(),
                 diag::extra_tokens_conditional_compilation_directive);
    }

    // Parse elements
    SmallVector<ElemTy, N> Elements;
    if (ConfigState.shouldParse()) {
      parseElements(Elements, ConfigState.isConditionActive());
    } else {
      DiagnosticTransaction DT(P.Diags);
      P.skipUntilConditionalBlockClose();
      DT.abort();
    }

    Clauses.push_back(IfConfigClause<ElemTy>(ClauseLoc, Condition,
                                             P.Context.AllocateCopy(Elements),
                                             ConfigState.isConditionActive()));

    if (P.Tok.isNot(tok::pound_elseif, tok::pound_else))
      break;

    if (isElse)
      P.diagnose(P.Tok, diag::expected_close_after_else_directive);
  }

  HadMissingEnd = P.parseEndIfDirective(EndLoc);
  return makeParserSuccess();
}

ParserResult<IfConfigDecl> Parser::parseDeclIfConfig(ParseDeclOptions Flags) {
  SmallVector<IfConfigClause<Decl *>, 4> Clauses;
  SourceLoc EndLoc;
  bool HadMissingEnd = false;
  auto Status = parseIfConfig<Decl *, 8>(
      *this, Clauses, EndLoc, HadMissingEnd,
      [&](SmallVectorImpl<Decl *> &Decls, bool IsActive) {
    Optional<Scope> scope;
    if (!IsActive)
      scope.emplace(this, getScopeInfo().getCurrentScope()->getKind(),
                    /*inactiveConfigBlock=*/true);

    ParserStatus Status;
    bool PreviousHadSemi = true;
    while (Tok.isNot(tok::pound_else, tok::pound_endif, tok::pound_elseif,
                      tok::eof)) {
      if (Tok.is(tok::r_brace)) {
        diagnose(Tok.getLoc(),
                  diag::unexpected_rbrace_in_conditional_compilation_block);
        // If we see '}', following declarations don't look like belong to
        // the current decl context; skip them.
        skipUntilConditionalBlockClose();
        break;
      }
      Status |= parseDeclItem(PreviousHadSemi, Flags,
                              [&](Decl *D) {Decls.push_back(D);});
    }
  });
  if (Status.isError())
    return makeParserErrorResult<IfConfigDecl>();

  IfConfigDecl *ICD = new (Context) IfConfigDecl(CurDeclContext,
                                                 Context.AllocateCopy(Clauses),
                                                 EndLoc, HadMissingEnd);
  return makeParserResult(ICD);
}

ParserResult<Stmt> Parser::parseStmtIfConfig(BraceItemListKind Kind) {
  SmallVector<IfConfigClause<ASTNode>, 4> Clauses;
  SourceLoc EndLoc;
  bool HadMissingEnd = false;
  auto Status = parseIfConfig<ASTNode, 16>(
      *this, Clauses, EndLoc, HadMissingEnd,
      [&](SmallVectorImpl<ASTNode> &Elements, bool IsActive) {
    parseBraceItems(Elements, Kind, IsActive
                      ? BraceItemListKind::ActiveConditionalBlock
                      : BraceItemListKind::InactiveConditionalBlock);
  });
  if (Status.isError())
    return makeParserErrorResult<Stmt>();

  auto *ICS = new (Context) IfConfigStmt(Context.AllocateCopy(Clauses),
                                         EndLoc, HadMissingEnd);
  return makeParserResult(ICS);
}

// Evaluate a subset of expression types suitable for build configuration
// conditional expressions.  The accepted expression types are:
//  - The magic constants "true" and "false".
//  - Named decl ref expressions ("FOO")
//  - Parenthesized expressions ("(FOO)")
//  - Binary "&&" or "||" operations applied to other build configuration
//    conditional expressions
//  - Unary "!" expressions applied to other build configuration conditional
//    expressions
//  - Single-argument call expressions, where the function being invoked is a
//    supported target configuration (currently "os", "arch", and
//    "_compiler_version"), and whose argument is a named decl ref expression
ConditionalCompilationExprState
Parser::classifyConditionalCompilationExpr(Expr *condition,
                                           ASTContext &Context,
                                           DiagnosticEngine &D) {
  assert(condition && "Cannot classify a NULL condition expression!");

  // Evaluate a ParenExpr.
  if (auto *PE = dyn_cast<ParenExpr>(condition))
    return classifyConditionalCompilationExpr(PE->getSubExpr(), Context, D);

  // Evaluate a "&&" or "||" expression.
  if (auto *SE = dyn_cast<SequenceExpr>(condition)) {
    // Check for '&&' or '||' as the expression type.
    if (SE->getNumElements() < 3) {
      D.diagnose(SE->getLoc(),
                 diag::unsupported_conditional_compilation_binary_expression);
      return ConditionalCompilationExprState::error();
    }
    // Before type checking, chains of binary expressions will not be fully
    // parsed, so associativity has not yet been encoded in the subtree.
    auto elements = SE->getElements();
    auto numElements = SE->getNumElements();
    size_t iOperator = 1;
    size_t iOperand = 2;

    auto result = classifyConditionalCompilationExpr(elements[0], Context, D);

    while (iOperand < numElements) {

      if (auto *UDREOp = dyn_cast<UnresolvedDeclRefExpr>(elements[iOperator])) {
        auto name = UDREOp->getName().getBaseName().str();

        if (name.equals("||") || name.equals("&&")) {
          auto rhs = classifyConditionalCompilationExpr(elements[iOperand],
                                                        Context, D);

          if (name.equals("||")) {
            result = result || rhs;
            if (result.isConditionActive())
              break;
          }

          if (name.equals("&&")) {
            result = result && rhs;
            if (!result.isConditionActive())
              break;
          }
        } else {
          D.diagnose(
              SE->getLoc(),
              diag::unsupported_conditional_compilation_binary_expression);
          return ConditionalCompilationExprState::error();
        }
      } else {
        // Swift3 didn't have this branch. the operator and the RHS are
        // silently ignored.
        if (!Context.isSwiftVersion3()) {
          D.diagnose(
              elements[iOperator]->getLoc(),
              diag::unsupported_conditional_compilation_expression_type);
          return ConditionalCompilationExprState::error();
        } else {
          SourceRange ignoredRange(elements[iOperator]->getLoc(),
                                   elements[iOperand]->getEndLoc());
          D.diagnose(
              elements[iOperator]->getLoc(),
              diag::swift3_unsupported_conditional_compilation_expression_type)
            .highlight(ignoredRange);
        }
      }

      iOperator += 2;
      iOperand += 2;
    }

    return result;
  }

  // Evaluate a named reference expression.
  if (auto *UDRE = dyn_cast<UnresolvedDeclRefExpr>(condition)) {
    auto name = UDRE->getName().getBaseName().str();
    return {Context.LangOpts.isCustomConditionalCompilationFlagSet(name),
      ConditionalCompilationExprKind::DeclRef};
  }

  // Evaluate a Boolean literal.
  if (auto *boolLit = dyn_cast<BooleanLiteralExpr>(condition)) {
    return {boolLit->getValue(), ConditionalCompilationExprKind::Boolean};
  }

  // Evaluate a negation (unary "!") expression.
  if (auto *PUE = dyn_cast<PrefixUnaryExpr>(condition)) {
    // If the PUE is not a negation expression, return false
    auto name =
    cast<UnresolvedDeclRefExpr>(PUE->getFn())->getName().getBaseName().str();
    if (name != "!") {
      D.diagnose(PUE->getLoc(),
                 diag::unsupported_conditional_compilation_unary_expression);
      return ConditionalCompilationExprState::error();
    }

    return !classifyConditionalCompilationExpr(PUE->getArg(), Context, D);
  }

  // Evaluate a target config call expression.
  if (auto *CE = dyn_cast<CallExpr>(condition)) {
    // look up target config, and compare value
    auto fnNameExpr = dyn_cast<UnresolvedDeclRefExpr>(CE->getFn());

    // Get the arg, which should be in a paren expression.
    if (!fnNameExpr) {
      D.diagnose(CE->getLoc(), diag::unsupported_platform_condition_expression);
      return ConditionalCompilationExprState::error();
    }

    auto fnName = fnNameExpr->getName().getBaseName().str();

    auto *PE = dyn_cast<ParenExpr>(CE->getArg());
    if (!PE) {
      auto diag = D.diagnose(CE->getLoc(),
                             diag::platform_condition_expected_one_argument);
      return ConditionalCompilationExprState::error();
    }

    if (!fnName.equals("arch") && !fnName.equals("os") &&
        !fnName.equals("_endian") &&
        !fnName.equals("_runtime") &&
        !fnName.equals("swift") &&
        !fnName.equals("_compiler_version")) {
      D.diagnose(CE->getLoc(), diag::unsupported_platform_condition_expression);
      return ConditionalCompilationExprState::error();
    }

    if (fnName.equals("_compiler_version")) {
      if (auto SLE = dyn_cast<StringLiteralExpr>(PE->getSubExpr())) {
        if (SLE->getValue().empty()) {
          D.diagnose(CE->getLoc(), diag::empty_version_string);
          return ConditionalCompilationExprState::error();
        }
        auto versionRequirement =
        version::Version::parseCompilerVersionString(SLE->getValue(),
                                                     SLE->getLoc(),
                                                     &D);
        auto thisVersion = version::Version::getCurrentCompilerVersion();
        auto VersionNewEnough = thisVersion >= versionRequirement;
        return {VersionNewEnough,
          ConditionalCompilationExprKind::CompilerVersion};
      } else {
        D.diagnose(CE->getLoc(), diag::unsupported_platform_condition_argument,
                 "string literal");
        return ConditionalCompilationExprState::error();
      }
    } else if (fnName.equals("swift")) {
      auto PUE = dyn_cast<PrefixUnaryExpr>(PE->getSubExpr());
      if (!PUE) {
        D.diagnose(PE->getSubExpr()->getLoc(),
                   diag::unsupported_platform_condition_argument,
                   "a unary comparison, such as '>=2.2'");
        return ConditionalCompilationExprState::error();
      }

      auto prefix = dyn_cast<UnresolvedDeclRefExpr>(PUE->getFn());
      auto versionArg = PUE->getArg();
      auto versionStartLoc = versionArg->getStartLoc();
      auto endLoc = Lexer::getLocForEndOfToken(Context.SourceMgr,
                                               versionArg->getSourceRange().End);
      CharSourceRange versionCharRange(Context.SourceMgr, versionStartLoc,
                                       endLoc);
      auto versionString = Context.SourceMgr.extractText(versionCharRange);

      auto versionRequirement =
        version::Version::parseVersionString(versionString,
                                             versionStartLoc,
                                             &D);

      if (!versionRequirement.hasValue())
        return ConditionalCompilationExprState::error();

      auto thisVersion = Context.LangOpts.EffectiveLanguageVersion;

      if (!prefix->getName().getBaseName().str().equals(">=")) {
        D.diagnose(PUE->getFn()->getLoc(),
                   diag::unexpected_version_comparison_operator)
          .fixItReplace(PUE->getFn()->getLoc(), ">=");
        return ConditionalCompilationExprState::error();
      }

      auto VersionNewEnough = thisVersion >= versionRequirement.getValue();
      return {VersionNewEnough,
        ConditionalCompilationExprKind::LanguageVersion};
    } else {
      if (auto UDRE = dyn_cast<UnresolvedDeclRefExpr>(PE->getSubExpr())) {
        // The sub expression should be an UnresolvedDeclRefExpr (we won't
        // tolerate extra parens).
        auto argumentIdent = UDRE->getName().getBaseName();
        auto argument = argumentIdent.str();
        PlatformConditionKind Kind =
          llvm::StringSwitch<PlatformConditionKind>(fnName)
          .Case("os", PlatformConditionKind::OS)
          .Case("arch", PlatformConditionKind::Arch)
          .Case("_endian", PlatformConditionKind::Endianness)
          .Case("_runtime", PlatformConditionKind::Runtime);

        // FIXME: Perform the replacement macOS -> OSX elsewhere.
        if (Kind == PlatformConditionKind::OS && argument == "macOS")
          argument = "OSX";

        std::vector<StringRef> suggestions;
        if (!LangOptions::checkPlatformConditionSupported(Kind, argument,
                                                          suggestions)) {
          if (Kind == PlatformConditionKind::Runtime) {
            // Error for _runtime()
            D.diagnose(UDRE->getLoc(),
                       diag::unsupported_platform_runtime_condition_argument);
            return ConditionalCompilationExprState::error();
          }
          StringRef DiagName;
          switch (Kind) {
          case PlatformConditionKind::OS:
            DiagName = "operating system"; break;
          case PlatformConditionKind::Arch:
            DiagName = "architecture"; break;
          case PlatformConditionKind::Endianness:
            DiagName = "endianness"; break;
          case PlatformConditionKind::Runtime:
            llvm_unreachable("handled above");
          }
          D.diagnose(UDRE->getLoc(), diag::unknown_platform_condition_argument,
                     DiagName, fnName);
          for (const StringRef &suggestion : suggestions) {
            D.diagnose(UDRE->getLoc(), diag::note_typo_candidate, suggestion)
              .fixItReplace(UDRE->getSourceRange(), suggestion);
          }
        }

        auto target = Context.LangOpts.getPlatformConditionValue(Kind);
        return {target == argument, ConditionalCompilationExprKind::DeclRef};
      } else {
        D.diagnose(CE->getLoc(), diag::unsupported_platform_condition_argument,
                   "identifier");
        return ConditionalCompilationExprState::error();
      }
    }
  }

  // "#if 0" isn't valid, but it is common, so recognize it and handle it
  // with a fixit elegantly.
  if (auto *IL = dyn_cast<IntegerLiteralExpr>(condition))
    if (IL->getDigitsText() == "0" || IL->getDigitsText() == "1") {
      StringRef replacement = IL->getDigitsText() == "0" ? "false" :"true";
      D.diagnose(IL->getLoc(), diag::unsupported_conditional_compilation_integer,
                 IL->getDigitsText(), replacement)
       .fixItReplace(IL->getLoc(), replacement);
      return {IL->getDigitsText() == "1",
        ConditionalCompilationExprKind::Integer};
    }


  // If we've gotten here, it's an unsupported expression type.
  D.diagnose(condition->getLoc(),
             diag::unsupported_conditional_compilation_expression_type);
  return ConditionalCompilationExprState::error();
}
