-
Notifications
You must be signed in to change notification settings - Fork 49
Open
Labels
Description
Consider this grammar:
class MyGrammar extends GrammarDefinition {
@override
Parser start() => ref0(myChars).starString().end();
Parser<String> myChars() => anyOf('abc');
}
The linter will produce a warning to use one of the *String parsers, despite this already being the case:
expect(linter(MyGrammar().build()), isEmpty);
Output:
Expected: empty
Actual: [
LinterIssue:LinterIssue(type: LinterType.warning, title: Character repeater, parser: Instance of 'FlattenParser<List<String>>', description: A flattened repeater (Instance of 'PossessiveRepeatingParser<String>'[0..*]) that delegates to a character parser (Instance of 'SingleCharacterParser'[any of " \t" expected]) can be much more efficiently implemented using `starString`, `plusString`, `timesString`, or `repeatString` that directly returns the underlying String instead of an intermediate List.)
]
I think that the cause is that the class of myChars
is obscured by the wrapping ReferenceParser
so that the type checks in repeatString
fail and we end up on this line:
return self.repeat(min, max).flatten(message); |
This seems like a difficult problem: the class of the referent is not known until build time, but repeatString
needs to be called earlier.
Is the only solution here "don't use a reference"?
(Bigger question: Should references only be used to break cycles? I was under the impression that it was good practice to use them by default.)