anchor.diff:      Token previousToken = token;
       token = token.next;
       if (!optional('{', token)) {
  -      token = recoverFromMissingClassBody(previousToken);
  +      token = ensureBlock(previousToken, fasta.templateExpectedClassBody);
       }
       Token closeBrace = closeBraceTokenFor(token);
       if (closeBrace == null ||
  
positive.code:   }
  
    Token skipBlock(Token token) {
      token = ensureBlock(token);
      Token closeBrace = closeBraceTokenFor(token);
      if (closeBrace == null ||
          !identical(closeBrace.kind, $CLOSE_CURLY_BRACKET)) {
  
negative.code:     return token;
    }
  
    /// If the next token is an opening curly brace, return it. Otherwise, use the
    /// given [template] to report an error, insert an opening and a closing curly
    /// brace, and return the newly inserted opening curly brace. If the
    /// [template] is `null`, use a default error message instead.
    Token ensureBlock(
        Token token, Template<Message Function(Token token)> template) {
      Token next = token.next;
      if (optional('{', next)) return next;
      Message message = template == null
          ? fasta.templateExpectedButGot.withArguments('{')
          : template.withArguments(token);
      reportRecoverableError(next, message);
      Token replacement = link(
          new SyntheticBeginToken(TokenType.OPEN_CURLY_BRACKET, next.offset),
          new SyntheticToken(TokenType.CLOSE_CURLY_BRACKET, next.offset));
  