package org.fandev.lang.fan.parsing.statements.typeDefinitions.members; import com.intellij.lang.PsiBuilder; import com.intellij.psi.tree.TokenSet; import org.fandev.lang.fan.FanBundle; import org.fandev.lang.fan.FanElementTypes; import static org.fandev.lang.fan.FanElementTypes.CTOR_DEFINITION; import static org.fandev.lang.fan.FanElementTypes.METHOD_BODY; import org.fandev.lang.fan.FanTokenTypes; import static org.fandev.lang.fan.FanTokenTypes.LBRACE; import org.fandev.lang.fan.parsing.auxiliary.facets.Facet; import org.fandev.lang.fan.parsing.auxiliary.modifiers.Modifiers; import org.fandev.lang.fan.parsing.statements.Block; import org.fandev.lang.fan.parsing.statements.declaration.DeclarationType; import org.fandev.lang.fan.parsing.statements.expressions.arguments.Arguments; import org.fandev.lang.fan.parsing.statements.typeDefinitions.ReferenceElement; import org.fandev.lang.fan.parsing.types.TypeParameters; import org.fandev.lang.fan.parsing.util.ParserUtils; /** * Grammar Definition:<ul> * <li><ctorDef> := <facets> <ctorFlags> "new" <id> "(" <params> ")" [ctorChain] <methodBody></li> * <li><ctorFlags> := [<protection>]</li> * <li><ctorChain> := <ctorChainThis> | <ctorChainSuper></li> * <li><ctorChainThis> := "this" "." <id> "(" <args> ")"</li> * <li><ctorChainSuper> := "super" ["." <id>] "(" <args> ")"</li> * </ul> * * @author Dror Bereznitsky * @author Fred Simon * @date Jan 14, 2009 11:51:37 PM */ public class ConstructorDefinition { public static boolean parse(final PsiBuilder builder, final boolean isBuiltInType) { final PsiBuilder.Marker constructorMarker = builder.mark(); Facet.parse(builder); final TokenSet modifiers = Modifiers.parse(builder, DeclarationType.CONSTRUCTOR); if (!FanTokenTypes.NEW_KEYWORD.equals(builder.getTokenType())) { constructorMarker.error("Constructor should have <modifiers> new <id> ()"); return false; } ParserUtils.advanceNoNls(builder); if (!ParserUtils.parseName(builder)) { constructorMarker.drop(); return false; } ParserUtils.removeNls(builder); // parameter list if (FanElementTypes.TYPE_PARAMETER_LIST != TypeParameters.parse(builder)) { builder.error(FanBundle.message("params.expected")); constructorMarker.drop(); return false; } // ctor chain parseCtorChain(builder); ParserUtils.removeNls(builder); if (LBRACE.equals(builder.getTokenType())) { Block.parse(builder, METHOD_BODY); constructorMarker.done(CTOR_DEFINITION); ParserUtils.removeNls(builder); return true; } else if (isBuiltInType) { constructorMarker.done(CTOR_DEFINITION); ParserUtils.removeNls(builder); return true; } else { constructorMarker.error(FanBundle.message("lcurly.expected")); return false; } } /* Constructor related methods <ctorDef> := <facets> <ctorFlags> "new" <id> "(" <params> ")" [ctorChain] <methodBody> <ctorFlags> := [<protection>] <ctorChain> := <ctorChainThis> | <ctorChainSuper> <ctorChainThis> := "this" "." <id> "(" <args> ")" <ctorChainSuper> := "super" ["." <id>] "(" <args> ")" */ private static boolean parseCtorChain(final PsiBuilder builder) { if (FanTokenTypes.COLON == builder.getTokenType()) { final PsiBuilder.Marker ctorChainMarker = builder.mark(); ParserUtils.advanceNoNls(builder); if (FanTokenTypes.SUPER_KEYWORD == builder.getTokenType() || FanTokenTypes.THIS_KEYWORD == builder.getTokenType()) { builder.advanceLexer(); // ["." <id>] if (FanTokenTypes.DOT == builder.getTokenType()) { builder.advanceLexer(); if (!ReferenceElement.parseReferenceElement(builder)) { ctorChainMarker.error(FanBundle.message("identifier.expected")); } } // "(" <args> ")" if (Arguments.parse(builder)) { ctorChainMarker.done(FanElementTypes.CTOR_CHAIN); return true; } else { ctorChainMarker.error(FanBundle.message("argument.expected")); } } else { ctorChainMarker.error(FanBundle.message("super.or.this.expected")); } } return false; } }