Beispiel #1
0
/// When we see an expression in a TopLevelCodeDecl in the REPL, process it,
/// adding the proper decls back to the top level of the file.
void REPLChecker::processREPLTopLevelExpr(Expr *E) {
  CanType T = E->getType()->getCanonicalType();

  // Don't try to print invalid expressions, module exprs, or void expressions.
  if (T->hasError() || isa<ModuleType>(T) || T->isVoid())
    return;

  // Okay, we need to print this expression.  We generally do this by creating a
  // REPL metavariable (e.g. r4) to hold the result, so it can be referred to
  // in the future.  However, if this is a direct reference to a decl (e.g. "x")
  // then don't create a repl metavariable.
  if (VarDecl *d = getObviousDeclFromExpr(E)) {
    generatePrintOfExpression(d->getName().str(), E);
    return;
  }

  // Remove the expression from being in the list of decls to execute, we're
  // going to reparent it.
  auto TLCD = cast<TopLevelCodeDecl>(SF.Decls.back());

  E = TC.coerceToRValue(E);

  // Create the meta-variable, let the typechecker name it.
  Identifier name = TC.getNextResponseVariableName(SF.getParentModule());
  VarDecl *vd = new (Context) VarDecl(/*IsStatic*/false,
                                      VarDecl::Specifier::Let,
                                      /*IsCaptureList*/false, E->getStartLoc(),
                                      name, E->getType(), &SF);
  vd->setInterfaceType(E->getType());
  SF.Decls.push_back(vd);

  // Create a PatternBindingDecl to bind the expression into the decl.
  Pattern *metavarPat = new (Context) NamedPattern(vd);
  metavarPat->setType(E->getType());

  PatternBindingDecl *metavarBinding = PatternBindingDecl::create(
      Context, /*StaticLoc*/ SourceLoc(), StaticSpellingKind::None,
      /*VarLoc*/ E->getStartLoc(), metavarPat, /*EqualLoc*/ SourceLoc(), E,
      TLCD);

  // Overwrite the body of the existing TopLevelCodeDecl.
  TLCD->setBody(BraceStmt::create(Context,
                                  metavarBinding->getStartLoc(),
                                  ASTNode(metavarBinding),
                                  metavarBinding->getEndLoc(),
                                  /*implicit*/true));

  // Finally, print the variable's value.
  E = TC.buildCheckedRefExpr(vd, &SF, DeclNameLoc(E->getStartLoc()),
                             /*Implicit=*/true);
  generatePrintOfExpression(vd->getName().str(), E);
}
static bool isVoidLike(CanType type) {
  return (type->isVoid() ||
          (isa<TupleType>(type) &&
           cast<TupleType>(type)->getNumElements() == 1 &&
           cast<TupleType>(type).getElementType(0)->isVoid()));
}