void (PsiBuilder builder, ListType type) { final boolean lambda = (type == ListType.LAMBDA_TYPED || type == ListType.LAMBDA_UNTYPED); final boolean resources = (type == ListType.RESOURCE); final PsiBuilder.Marker elementList = builder.mark(); final boolean leftParenth = expect(builder, JavaTokenType.LPARENTH); assert lambda || leftParenth : builder.getTokenType(); final IElementType delimiter = resources ? JavaTokenType.SEMICOLON : JavaTokenType.COMMA; final String noDelimiterMsg = resources ? "expected.semicolon" : "expected.comma"; final String noElementMsg = resources ? "expected.resource" : "expected.parameter"; PsiBuilder.Marker invalidElements = null; String errorMessage = null; boolean delimiterExpected = false; boolean noElements = true; while (true) { final IElementType tokenType = builder.getTokenType(); if (tokenType == null || type.getStopperTypes().contains(tokenType)) { final boolean noLastElement = !delimiterExpected && (!noElements && !resources || noElements && resources); if (noLastElement) { final String key = lambda ? "expected.parameter" : "expected.identifier.or.type"; error(builder, JavaPsiBundle.message(key)); } if (tokenType == JavaTokenType.RPARENTH) { if (invalidElements != null) { invalidElements.error(errorMessage); invalidElements = null; } builder.advanceLexer(); } else { if (!noLastElement || resources) { if (invalidElements != null) { invalidElements.error(errorMessage); } invalidElements = null; if (leftParenth) { error(builder, JavaPsiBundle.message("expected.rparen")); } } } break; } if (delimiterExpected) { if (builder.getTokenType() == delimiter) { delimiterExpected = false; if (invalidElements != null) { invalidElements.error(errorMessage); invalidElements = null; } builder.advanceLexer(); continue; } } else { final PsiBuilder.Marker listElement = type == ListType.RECORD_COMPONENTS ? parseParameterOrRecordComponent(builder, true, false, false, false) : resources ? parseResource(builder) : lambda ? parseLambdaParameter(builder, type == ListType.LAMBDA_TYPED) : parseParameter(builder, true, false, false); if (listElement != null) { delimiterExpected = true; if (invalidElements != null) { invalidElements.errorBefore(errorMessage, listElement); invalidElements = null; } noElements = false; continue; } } if (invalidElements == null) { if (builder.getTokenType() == delimiter) { error(builder, JavaPsiBundle.message(noElementMsg)); builder.advanceLexer(); if (noElements && resources) { noElements = false; } continue; } else { invalidElements = builder.mark(); errorMessage = JavaPsiBundle.message(delimiterExpected ? noDelimiterMsg : noElementMsg); } } // adding a reference, not simple tokens allows "Browse .." to work well final PsiBuilder.Marker ref = myParser.getReferenceParser().parseJavaCodeReference(builder, true, true, false, false); if (ref == null && builder.getTokenType() != null) { builder.advanceLexer(); } } if (invalidElements != null) { invalidElements.error(errorMessage); } done(elementList, type.getNodeType(myJavaElementTypeContainer), myWhiteSpaceAndCommentSetHolder); }