void (@NotNull PsiBuilder builder) { parseImportList(builder, b -> IMPORT_PARSING_STOP_LIST.contains(b.getTokenType())); final PsiBuilder.Marker rootClass = builder.mark(); try { while (!builder.eof()) { PsiBuilder.Marker wrapper = builder.mark(); IElementType wrapperType = null; PsiBuilder.Marker marker = parseImportStatement(builder); if (isParsed(marker, builder, IMPORT_PARSED_CONDITION)) { wrapperType = JShellElementType.IMPORT_HOLDER; } else { revert(marker); marker = getExpressionParser().parse(builder); // in case of reference expression try other options and only if they fail, parse as expression again if (isParsed(marker, builder, EXPRESSION_PARSED_CONDITION) && !((PsiBuilderImpl)builder).hasErrorsAfter(marker)) { // ensure that it is error-free expression to avoid parsing Iterable<?> as condition wrapperType = JShellElementType.STATEMENTS_HOLDER; } else { revert(marker); marker = getStatementParser().parseStatement(builder); if (isParsed(marker, builder, STATEMENTS_PARSED_CONDITION)) { wrapperType = JShellElementType.STATEMENTS_HOLDER; } else { revert(marker); marker = getDeclarationParser().parse(builder, DeclarationParser.Context.CLASS); if (isParsed(marker, builder, DECLARATION_PARSED_CONDITION)) { wrapper.drop(); // don't need wrapper for top-level declaration wrapper = null; } else { revert(marker); marker = getExpressionParser().parse(builder); wrapperType = marker != null? JShellElementType.STATEMENTS_HOLDER : null; } } } } if (marker == null) { wrapper.drop(); break; } if (wrapper != null) { wrapper.done(wrapperType); } } if (!builder.eof()) { builder.mark().error(JavaPsiBundle.message("unexpected.token")); while (!builder.eof()) { builder.advanceLexer(); } } } finally { rootClass.done(JShellElementType.ROOT_CLASS); } }