fix voice control delete line command does not delete line correctly#24831
Conversation
gaaclarke
left a comment
There was a problem hiding this comment.
Mostly looks good, just 2 comments.
| #pragma mark - FlutterTokenizer | ||
|
|
||
| @implementation FlutterTokenizer { | ||
| FlutterTextInputView* _textInputView; |
There was a problem hiding this comment.
Please use a property so we can know if you intend this to be a strong or a weak reference. Right now this is being treated as a weak reference. I suspect you want a strong reference.
There was a problem hiding this comment.
This should be a weak reference, FlutterTextInputView owns the FlutterTokenizer. I will update
|
|
||
| @interface FlutterTokenizer () | ||
|
|
||
| @property(nonatomic, assign) FlutterTextInputView* textInputView; |
There was a problem hiding this comment.
s/assign/weak for more modern objc and forward compatibility with ARC
There was a problem hiding this comment.
I tried to use weak, but it complains this file is MRC and can't use weak
| return self; | ||
| } | ||
|
|
||
| - (UITextRange*)rangeEnclosingPosition:(UITextPosition*)position |
There was a problem hiding this comment.
If you just pass in the FlutterTextInputView as an argument to this method you wouldn't have to keep an instance variable around. The instance variable is a bit problematic because if the class is used differently it can cause a crash.
There was a problem hiding this comment.
this is an override. https://developer.apple.com/documentation/uikit/uitextinputtokenizer/1614464-rangeenclosingposition?language=objc
I can't change the function signature
There was a problem hiding this comment.
I figured it is quite hard to know whether this is an override or private method for a reviewer. is there a best practice way to annotate an override method?
There was a problem hiding this comment.
You almost never use inheritance in objc. I didn't see this was inheriting UITextInputStringTokenizer. Is there a reason it has to inherit from UITextInputStringTokenizer?
The documentation says this for subclassing UITextInputString:
When you subclass UITextInputStringTokenizer, override all UITextInputTokenizer methods, calling the superclass implementation (super) when method parameters are not affected by layout. For example, the subclass needs a custom implementation of all methods for line granularity. For the left direction, it needs to decide whether left corresponds at a given position to forward or backward, and then call super passing in the storage direction (UITextStorageDirection).
Sounds like it might be a problem if you aren't calling super.
edit: You should probably be implementing UITextInputTokenizer then delegating to an instance of UITextInputStringTokenizer when you need to.
There was a problem hiding this comment.
calling the superclass implementation (super) when method parameters are not affected by layout.
it does not seems to be a hard requirement? a little background on this change.
If you have text = "how are you"
and you call
[UITextInputStringTokenizer rangeEnclosingPosition:<at the end> withGranularity:line inDirection:forward]
it returns NSRange(location =8, length =3) which corresponds to "you". It is same result of Granularity word
The result is completely unusable. That is why i have to complete rewrite the line logic.
There was a problem hiding this comment.
Yea, maybe you are right. I have a hard time understanding if that warning in the documentation is actually applicable. We do have tests I guess.
| @"The FlutterTokenizer can only be used in a FlutterTextInputView"); | ||
| self = [super initWithTextInput:textInput]; | ||
| if (self) { | ||
| _textInputView = (FlutterTextInputView*)textInput; |
There was a problem hiding this comment.
Why cast here? Why not just pass in a FlutterTextInputView? If you want to keep the cast you should have an assert that it a valid cast (isKindOf:).
There was a problem hiding this comment.
yes i have assert it in the beginning, line 392.
This is an override of https://developer.apple.com/documentation/uikit/uitextinputstringtokenizer/1614469-initwithtextinput?language=objc
There was a problem hiding this comment.
I thought i saw it somewhere, thanks.
|
|
||
| - (FlutterTextRange*)getLineRangeFromTokenizer:(id<UITextInputTokenizer>)tokenizer | ||
| atIndex:(NSInteger)index { | ||
| return (FlutterTextRange*)[tokenizer |
There was a problem hiding this comment.
Probably should add an assert here too if you are going to cast.
The
UITextInputStringTokenizerdoes not parse the line correctly, This pr fixes it.fixes flutter/flutter#77274
Pre-launch Checklist
writing and running engine tests.
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.