/* Function: TryToSkipDecorator * * Tries to move the iterator past a single decorator. Note that there may be more than one decorator in a row, so use <TryToSkipDecorators()> * if you need to move past all of them. * * Supported Modes: * * - <ParseMode.IterateOnly> * - <ParseMode.ParsePrototype> * - Each decorator will create a new prototype section. * - <ParseMode.ParseClassPrototype> * - Will mark the first token with <ClassPrototypeParsingType.StartOfPrePrototypeLine> and the rest with <ClassPrototypeParsingType.PrePrototypeLine>. * - Everything else is treated as <ParseMode.IterateOnly>. */ protected bool TryToSkipDecorator(ref TokenIterator iterator, ParseMode mode = ParseMode.IterateOnly) { if (iterator.Character != '@') { return(false); } TokenIterator lookahead = iterator; lookahead.Next(); if (TryToSkipIdentifier(ref lookahead) == false) { return(false); } TokenIterator decoratorStart = iterator; TokenIterator decoratorEnd = lookahead; if (mode == ParseMode.SyntaxHighlight) { decoratorStart.SetSyntaxHighlightingTypeBetween(decoratorEnd, SyntaxHighlightingType.Metadata); } TryToSkipWhitespace(ref lookahead); if (TryToSkipDecoratorParameters(ref lookahead, mode)) { decoratorEnd = lookahead; } if (mode == ParseMode.ParsePrototype) { decoratorStart.PrototypeParsingType = PrototypeParsingType.StartOfPrototypeSection; decoratorEnd.PrototypeParsingType = PrototypeParsingType.EndOfPrototypeSection; } else if (mode == ParseMode.ParseClassPrototype) { iterator.SetClassPrototypeParsingTypeBetween(lookahead, ClassPrototypeParsingType.PrePrototypeLine); iterator.ClassPrototypeParsingType = ClassPrototypeParsingType.StartOfPrePrototypeLine; } iterator = decoratorEnd; return(true); }
/* Function: TryToSkipClassParent * * Tries to move the iterator past a single class parent declaration. * * Supported Modes: * * - <ParseMode.IterateOnly> * - <ParseMode.ParseClassPrototype> * - Everything else is treated as <ParseMode.IterateOnly>. */ protected bool TryToSkipClassParent(ref TokenIterator iterator, ParseMode mode = ParseMode.IterateOnly) { TokenIterator lookahead = iterator; if (lookahead.MatchesToken("metaclass")) { lookahead.Next(); TryToSkipWhitespace(ref lookahead); if (lookahead.Character == '=') { if (mode == ParseMode.ParseClassPrototype) { iterator.ClassPrototypeParsingType = ClassPrototypeParsingType.Modifier; } lookahead.Next(); TryToSkipWhitespace(ref lookahead); } else { // Nevermind, reset lookahead = iterator; } } TokenIterator startOfIdentifier = lookahead; if (TryToSkipIdentifier(ref lookahead) == false) { ResetTokensBetween(iterator, lookahead, mode); return(false); } if (mode == ParseMode.ParseClassPrototype) { startOfIdentifier.SetClassPrototypeParsingTypeBetween(lookahead, ClassPrototypeParsingType.Name); } iterator = lookahead; return(true); }
/* Function: TryToSkipDecorator * * Tries to move the iterator past a single decorator. Note that there may be more than one decorator in a row, so use <TryToSkipDecorators()> * if you need to move past all of them. * * Supported Modes: * * - <ParseMode.IterateOnly> * - <ParseMode.ParseClassPrototype> * - Will mark the first token with <ClassPrototypeParsingType.StartOfPrePrototypeLine> and the rest with <ClassPrototypeParsingType.PrePrototypeLine>. * - Everything else is treated as <ParseMode.IterateOnly>. */ protected bool TryToSkipDecorator(ref TokenIterator iterator, ParseMode mode = ParseMode.IterateOnly) { if (iterator.Character != '@') { return(false); } TokenIterator lookahead = iterator; lookahead.Next(); if (TryToSkipIdentifier(ref lookahead) == false) { return(false); } TokenIterator endOfIdentifier = lookahead; TryToSkipWhitespace(ref lookahead); if (lookahead.Character == '(') { if (TryToSkipBlock(ref lookahead, false) == false) { return(false); } } if (mode == ParseMode.ParseClassPrototype) { iterator.SetClassPrototypeParsingTypeBetween(lookahead, ClassPrototypeParsingType.PrePrototypeLine); iterator.ClassPrototypeParsingType = ClassPrototypeParsingType.StartOfPrePrototypeLine; } iterator = lookahead; return(true); }
// Group: Parsing Functions // __________________________________________________________________________ /* Function: TryToSkipClassDeclarationLine * * If the iterator is on a class's declaration line, moves it past it and returns true. It does not handle the class body. * * Supported Modes: * * - <ParseMode.IterateOnly> * - <ParseMode.ParseClassPrototype> * - Everything else is treated as <ParseMode.IterateOnly>. */ protected bool TryToSkipClassDeclarationLine(ref TokenIterator iterator, ParseMode mode = ParseMode.IterateOnly) { TokenIterator lookahead = iterator; // Keyword if (lookahead.MatchesToken("class") == false) { return(false); } if (mode == ParseMode.ParseClassPrototype) { lookahead.ClassPrototypeParsingType = ClassPrototypeParsingType.Keyword; } lookahead.Next(); TryToSkipWhitespace(ref lookahead); // Name TokenIterator startOfIdentifier = lookahead; if (TryToSkipUnqualifiedIdentifier(ref lookahead) == false) { ResetTokensBetween(iterator, lookahead, mode); return(false); } if (mode == ParseMode.ParseClassPrototype) { startOfIdentifier.SetClassPrototypeParsingTypeBetween(lookahead, ClassPrototypeParsingType.Name); } TryToSkipWhitespace(ref lookahead); // Base class if (lookahead.Character == '<') { if (mode == ParseMode.ParseClassPrototype) { lookahead.ClassPrototypeParsingType = ClassPrototypeParsingType.StartOfParents; } lookahead.Next(); TryToSkipWhitespace(ref lookahead); TokenIterator startOfParent = lookahead; if (TryToSkipUnqualifiedIdentifier(ref lookahead) == false) { ResetTokensBetween(iterator, lookahead, mode); return(false); } if (mode == ParseMode.ParseClassPrototype) { startOfParent.SetClassPrototypeParsingTypeBetween(lookahead, ClassPrototypeParsingType.Name); } } iterator = lookahead; return(true); }
// Group: Parsing Functions // __________________________________________________________________________ /* Function: TryToSkipClassDeclarationLine * * If the iterator is on a class's declaration line, moves it past it and returns true. It does not handle the class body. * * Supported Modes: * * - <ParseMode.IterateOnly> * - <ParseMode.ParseClassPrototype> * - Everything else is treated as <ParseMode.IterateOnly>. */ protected bool TryToSkipClassDeclarationLine(ref TokenIterator iterator, ParseMode mode = ParseMode.IterateOnly) { TokenIterator lookahead = iterator; // Decorators if (TryToSkipDecorators(ref lookahead, mode)) { TryToSkipWhitespace(ref lookahead); } // Keyword if (lookahead.MatchesToken("class") == false) { ResetTokensBetween(iterator, lookahead, mode); return(false); } if (mode == ParseMode.ParseClassPrototype) { lookahead.ClassPrototypeParsingType = ClassPrototypeParsingType.Keyword; } lookahead.Next(); TryToSkipWhitespace(ref lookahead); // Name TokenIterator startOfIdentifier = lookahead; if (TryToSkipIdentifier(ref lookahead) == false) { ResetTokensBetween(iterator, lookahead, mode); return(false); } if (mode == ParseMode.ParseClassPrototype) { startOfIdentifier.SetClassPrototypeParsingTypeBetween(lookahead, ClassPrototypeParsingType.Name); } TryToSkipWhitespace(ref lookahead); // Base classes if (lookahead.Character == '(') { if (mode == ParseMode.ParseClassPrototype) { lookahead.ClassPrototypeParsingType = ClassPrototypeParsingType.StartOfParents; } lookahead.Next(); TryToSkipWhitespace(ref lookahead); for (;;) { if (lookahead.Character == ')') { if (mode == ParseMode.ParseClassPrototype) { lookahead.ClassPrototypeParsingType = ClassPrototypeParsingType.EndOfParents; } break; } if (TryToSkipClassParent(ref lookahead, mode) == false) { ResetTokensBetween(iterator, lookahead, mode); return(false); } TryToSkipWhitespace(ref lookahead); if (lookahead.Character == ',') { if (mode == ParseMode.ParseClassPrototype) { lookahead.ClassPrototypeParsingType = ClassPrototypeParsingType.ParentSeparator; } lookahead.Next(); TryToSkipWhitespace(ref lookahead); } } } iterator = lookahead; return(true); }