@Override public int parseString(RubyLexer lexer) throws java.io.IOException { ByteList str = null; ByteList eos = nd_lit; int len = nd_lit.length() - 1; boolean indent = (flags & STR_FUNC_INDENT) != 0; int c = lexer.nextc(); if (c == EOF) return error(lexer, len, str, eos); // Found end marker for this heredoc if (lexer.was_bol() && lexer.whole_match_p(nd_lit, indent)) { lexer.heredoc_restore(this); return Tokens.tSTRING_END; } if ((flags & STR_FUNC_EXPAND) == 0) { do { ByteList lbuf = lexer.lex_lastline; int p = 0; int pend = lexer.lex_pend; if (pend > p) { switch (lexer.p(pend - 1)) { case '\n': pend--; if (pend == p || lexer.p(pend - 1) == '\r') { pend++; break; } break; case '\r': pend--; break; } } if (lexer.getHeredocIndent() > 0) { for (long i = 0; p + i < pend && lexer.update_heredoc_indent(lexer.p(p)); i++) {} lexer.setHeredocLineIndent(0); } if (str != null) { str.append(lbuf.makeShared(p, pend - p)); } else { str = new ByteList(lbuf.makeShared(p, pend - p)); } if (pend < lexer.lex_pend) str.append('\n'); lexer.lex_goto_eol(); if (lexer.getHeredocIndent() > 0) { lexer.setValue(str); return Tokens.tSTRING_CONTENT; } // MRI null checks str in this case but it is unconditionally non-null? if (lexer.nextc() == -1) return error(lexer, len, null, eos); } while (!lexer.whole_match_p(eos, indent)); } else { ByteList tok = new ByteList(); tok.setEncoding(lexer.getEncoding()); if (c == '#') { switch (c = lexer.nextc()) { case '$': case '@': lexer.pushback(c); return Tokens.tSTRING_DVAR; case '{': lexer.commandStart = true; return Tokens.tSTRING_DBEG; } tok.append('#'); } // MRI has extra pointer which makes our code look a little bit more strange in comparison do { lexer.pushback(c); Encoding enc[] = new Encoding[1]; enc[0] = lexer.getEncoding(); if ((c = new StringTerm(flags, '\0', '\n').parseStringIntoBuffer(lexer, tok, enc)) == EOF) { if (lexer.eofp) return error(lexer, len, str, eos); return restore(lexer); } if (c != '\n') { lexer.setValue(lexer.createStr(tok, 0)); return Tokens.tSTRING_CONTENT; } tok.append(lexer.nextc()); if (lexer.getHeredocIndent() > 0) { lexer.lex_goto_eol(); lexer.setValue(lexer.createStr(tok, 0)); return Tokens.tSTRING_CONTENT; } if ((c = lexer.nextc()) == EOF) return error(lexer, len, str, eos); } while (!lexer.whole_match_p(eos, indent)); str = tok; } lexer.heredoc_restore(this); lexer.setStrTerm(new StringTerm(-1, '\0', '\0')); lexer.setValue(lexer.createStr(str, 0)); return Tokens.tSTRING_CONTENT; }
protected int restore(RubyLexer lexer) { lexer.heredoc_restore(this); lexer.setStrTerm(null); return EOF; }