* @param className the name of the class containing the member being parsed
* @return the class member that was parsed, or {@code null} if what was found was not a valid
* class member
*/
protected ClassMember parseClassMember(String className) {
CommentAndMetadata commentAndMetadata = parseCommentAndMetadata();
Modifiers modifiers = parseModifiers();
if (matchesKeyword(Keyword.VOID)) {
TypeName returnType = parseReturnType();
if (matchesKeyword(Keyword.GET) && tokenMatchesIdentifier(peek())) {
validateModifiersForGetterOrSetterOrMethod(modifiers);
return parseGetter(
commentAndMetadata,
modifiers.getExternalKeyword(),
modifiers.getStaticKeyword(),
returnType);
} else if (matchesKeyword(Keyword.SET) && tokenMatchesIdentifier(peek())) {
validateModifiersForGetterOrSetterOrMethod(modifiers);
return parseSetter(
commentAndMetadata,
modifiers.getExternalKeyword(),
modifiers.getStaticKeyword(),
returnType);
} else if (matchesKeyword(Keyword.OPERATOR) && isOperator(peek())) {
validateModifiersForOperator(modifiers);
return parseOperator(commentAndMetadata, modifiers.getExternalKeyword(), returnType);
} else if (matchesIdentifier()
&& peek().matchesAny(
TokenType.OPEN_PAREN,
TokenType.OPEN_CURLY_BRACKET,
TokenType.FUNCTION)) {
validateModifiersForGetterOrSetterOrMethod(modifiers);
return parseMethodDeclarationAfterReturnType(
commentAndMetadata,
modifiers.getExternalKeyword(),
modifiers.getStaticKeyword(),
returnType);
} else {
//
// We have found an error of some kind. Try to recover.
//
if (matchesIdentifier()) {
if (peek().matchesAny(TokenType.EQ, TokenType.COMMA, TokenType.SEMICOLON)) {
//
// We appear to have a variable declaration with a type of "void".
//
reportErrorForNode(ParserErrorCode.VOID_VARIABLE, returnType);
return parseInitializedIdentifierList(
commentAndMetadata,
modifiers.getStaticKeyword(),
validateModifiersForField(modifiers),
returnType);
}
}
if (isOperator(currentToken)) {
//
// We appear to have found an operator declaration without the 'operator' keyword.
//
validateModifiersForOperator(modifiers);
return parseOperator(commentAndMetadata, modifiers.getExternalKeyword(), returnType);
}
reportErrorForToken(ParserErrorCode.EXPECTED_EXECUTABLE, currentToken);
return null;
}
} else if (matchesKeyword(Keyword.GET) && tokenMatchesIdentifier(peek())) {
validateModifiersForGetterOrSetterOrMethod(modifiers);
return parseGetter(
commentAndMetadata,
modifiers.getExternalKeyword(),
modifiers.getStaticKeyword(),
null);
} else if (matchesKeyword(Keyword.SET) && tokenMatchesIdentifier(peek())) {
validateModifiersForGetterOrSetterOrMethod(modifiers);
return parseSetter(
commentAndMetadata,
modifiers.getExternalKeyword(),
modifiers.getStaticKeyword(),
null);
} else if (matchesKeyword(Keyword.OPERATOR) && isOperator(peek())) {
validateModifiersForOperator(modifiers);
return parseOperator(commentAndMetadata, modifiers.getExternalKeyword(), null);
} else if (!matchesIdentifier()) {
if (isOperator(currentToken)) {
//
// We appear to have found an operator declaration without the 'operator' keyword.
//
validateModifiersForOperator(modifiers);
return parseOperator(commentAndMetadata, modifiers.getExternalKeyword(), null);
}
Token keyword = modifiers.getVarKeyword();
if (keyword == null) {
keyword = modifiers.getFinalKeyword();
}
if (keyword == null) {
keyword = modifiers.getConstKeyword();
}
if (keyword != null) {
//
// We appear to have found an incomplete field declaration.
//
reportErrorForCurrentToken(ParserErrorCode.MISSING_IDENTIFIER);
ArrayList<VariableDeclaration> variables = new ArrayList<VariableDeclaration>();
variables.add(new VariableDeclaration(null, null, createSyntheticIdentifier(), null, null));
return new FieldDeclaration(
commentAndMetadata.getComment(),
commentAndMetadata.getMetadata(),
null,
new VariableDeclarationList(null, null, keyword, null, variables),
expectSemicolon());
}
reportErrorForToken(ParserErrorCode.EXPECTED_CLASS_MEMBER, currentToken);
if (commentAndMetadata.getComment() != null || !commentAndMetadata.getMetadata().isEmpty()) {
//
// We appear to have found an incomplete declaration at the end of the class. At this point
// it consists of a metadata, which we don't want to loose, so we'll treat it as a method
// declaration with a missing name, parameters and empty body.
//
return new MethodDeclaration(
commentAndMetadata.getComment(),
commentAndMetadata.getMetadata(),
null,
null,
null,
null,
null,