Skip to content

feat(developer): ldml fix all remaining TODOs around markers and variables 🙀 #9688

Merged
srl295 merged 7 commits intomasterfrom
feat/core/9121-more-vars-epic-ldml
Oct 8, 2023
Merged

feat(developer): ldml fix all remaining TODOs around markers and variables 🙀 #9688
srl295 merged 7 commits intomasterfrom
feat/core/9121-more-vars-epic-ldml

Conversation

@srl295
Copy link
Copy Markdown
Member

@srl295 srl295 commented Oct 5, 2023

  • finish all of the developer LDML-TODOs around markers and variables

For: #9121
For: #9119

@keymanapp-test-bot skip

srl295 added 2 commits October 4, 2023 18:54
- add and re-enable some tests

For: #9121
For: #9119
- finish all of the developer LDML-TODOs around markers and variables

For: #9121
For: #9119
@srl295 srl295 added this to the A17S23 milestone Oct 5, 2023
@srl295 srl295 self-assigned this Oct 5, 2023
@srl295 srl295 changed the title Feat/core/9121-more-vars-epic-ldml feat(developer): ldml fix all remaining TODOs around markers and variables 🙀 Oct 5, 2023
Copy link
Copy Markdown
Member

@mcdurdin mcdurdin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM but would be good to refactor away the potentially gnarly string replacement snippet

Comment on lines +519 to +521
if(s === undefined || s === null) {
s = '';
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if(s === undefined || s === null) {
s = '';
}
s = s ?? '';

Seems shorter 😁

Ref https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing

Comment on lines +522 to +527
return this.allocList(sections.strs, s.split(' ').map(s => {
s = sections.vars.substituteStrings(s, sections);
s = sections.vars.substituteMarkerString(s);
s = unescapeString(s);
return s;
}));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return this.allocList(sections.strs, s.split(' ').map(s => {
s = sections.vars.substituteStrings(s, sections);
s = sections.vars.substituteMarkerString(s);
s = unescapeString(s);
return s;
}));
return this.allocList(sections.strs, s.split(' ').map(t => {
t = sections.vars.substituteStrings(t, sections);
t = sections.vars.substituteMarkerString(t);
t = unescapeString(t);
return t;
}));

Reusing s on inner scope is not ideal for readability

Comment on lines +135 to +137
cookedTo = sections.vars.substituteStrings(cookedTo, sections);
cookedTo = sections.vars.substituteMarkerString(cookedTo);
const to = sections.strs.allocAndUnescapeString(cookedTo, true);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pattern is repeated, refactor? It is also similar in disp.ts but written nested for added confusions!

Comment on lines +179 to +181
cookedLongPressDefault = sections.vars.substituteStrings(cookedLongPressDefault, sections);
cookedLongPressDefault = sections.vars.substituteMarkerString(cookedLongPressDefault)
const longPressDefault = sections.strs.allocAndUnescapeString(cookedLongPressDefault);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's the dup

Comment on lines +64 to +66
to: sections.strs.allocAndUnescapeString(
sections.vars.substituteMarkerString(
sections.vars.substituteStrings(display.to, sections))),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is similar to the code in keys.ts

Comment on lines +68 to +69
display: sections.strs.allocAndUnescapeString(
sections.vars.substituteStrings(display.display, sections)),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is nearly similar

Comment on lines 189 to 191
let toCooked = sections.vars.substituteStrings(toRaw, sections);
toCooked = sections.vars.substituteMarkerString(toCooked);
const to = sections.strs.allocAndUnescapeString(toCooked, true);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And dupity dup dup again

@srl295
Copy link
Copy Markdown
Member Author

srl295 commented Oct 5, 2023

@mcdurdin trying to DRY this out a little bit…

      const id = sections.strs.allocString(key.id);
      const longPress: ListItem = sections.list.allocListFromSpaces(
        key.longPress, {
          substituteStrs: true,
          markers: true,
          unescape: true,
        },
        sections);

      const longPressDefault = sections.strs.allocString(key.longPressDefault,
        {
          stringVariables: true,
          markers: true,
          unescape: true,
        },
        sections);

- refactor string preprocessing pipeline into an options bag
@github-actions github-actions bot added the feat label Oct 5, 2023
@srl295
Copy link
Copy Markdown
Member Author

srl295 commented Oct 5, 2023

Work in progress. tests fail.

@mcdurdin
Copy link
Copy Markdown
Member

mcdurdin commented Oct 6, 2023

... {
          substituteStrs: true,
          markers: true,
          unescape: true,
        }, ...

I like. These objects then lend themselves to being constants defined as part of the structural definitions, which is then easy to compare against the spec.

- workaround for debugger/test issue

For: #9121
For: #9119
@srl295
Copy link
Copy Markdown
Member Author

srl295 commented Oct 6, 2023

VERY strange

  1) vars
       markers
         should compile: sections/vars/markers-maximal.xml:
     TypeError: source is not iterable
      at new ListItem (file:///Users/srl295/src/keymanapp/keyman/common/web/types/src/kmx/string-list.ts:39:23)
      at ListItem.map (<anonymous>)
      at ListItem.toStringArray (file:///Users/srl295/src/keymanapp/keyman/common/web/types/src/kmx/string-list.ts:88:17)
      at Object.callback (file:///Users/srl295/src/keymanapp/keyman/developer/src/kmc-ldml/test/test-vars.ts:206:54)
      at Context.<anonymous> (file:///Users/srl295/src/keymanapp/keyman/developer/src/kmc-ldml/test/helpers/index.ts:230:18)

basically this /* ListItem */ .map(v => v.toString()) seemed to end up allocating a new ListItem (see stack!), but allocated it with a number such as 2, 3, 4. Not iterable. This code was working before. Anyway ListItem.toString() is only used for tests/debugging, so I just changed it into a for loop which worked fine.

Base automatically changed from feat/core/9119-more-markers-epic-ldml to master October 6, 2023 23:27
@srl295
Copy link
Copy Markdown
Member Author

srl295 commented Oct 7, 2023

export class ListItem extends Array<ListIndex> implements OrderedStringList {

 

but yet, inside of ListItem.toStringArray():

> this.map(q => q);
Uncaught TypeError TypeError: source is not iterable
    at ListItem (/Users/srl295/src/keymanapp/keyman/common/web/types/src/kmx/string-list.ts:41:23)
    at eval (repl:1:6)

If I'm in a member function, why is it allocating a ListItem? is it looking for a copy constructor?

this works, though

> Array.from(this.values())
(3) [ListIndex, ListIndex, ListIndex]
Array.from(this.values())[0]
á
Array.from(this.values())[1]
é
Array.from(this.values()).map(q => q)
(3) [ListIndex, ListIndex, ListIndex]
Array.from(this.values()).map(q => q.toString())
(3) ['á', 'é', 'í']

so somehow TypeScript's Array does something different when calling map

- odd, but seems to work this way

For: #9121
For: #9119
@srl295
Copy link
Copy Markdown
Member Author

srl295 commented Oct 7, 2023

OK I think i undertstand now.

  • i've subclassed Array , and changed its constructor
  • however, Array.map() probably assumes it can call new Array(2) to create an empty 2-element array
  • … so it ends up calling new ListItem(2) which doesn't make sense (to ListItem)
  • Perhaps I should instead have a factory static ListItem.from(source: Array<string>, opts: StrsOptions, sections: DependencySections) with the fancy init, and leave the array c'tors alone
  • This is a classic is-a vs has-a problem, if I HAD an array instead of being one, TS wouldn't get confused.

- Figured it out. Problem was a custom Array constructor.
- also updated ElementString class, which would have the same issue.

For: #9121
For: #9119
@srl295 srl295 linked an issue Oct 7, 2023 that may be closed by this pull request
4 tasks
@srl295
Copy link
Copy Markdown
Member Author

srl295 commented Oct 7, 2023

I'll do another check w/ base branch and then merge this.

@srl295 srl295 merged commit f5b28aa into master Oct 8, 2023
@srl295 srl295 deleted the feat/core/9121-more-vars-epic-ldml branch October 8, 2023 00:07
@keyman-server
Copy link
Copy Markdown
Collaborator

Changes in this pull request will be available for download in Keyman version 17.0.187-alpha

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

3 participants