Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correctly handle commas in CP property keys #13231

Merged
merged 2 commits into from
Feb 2, 2017

Conversation

nickiaconis
Copy link
Contributor

This addresses the issue of splitting on all commas in dependency key names, which prompted the opening of #13217.

Currently:

expandProperties('a,b,c.d.e,f', console.log); //=> 'a', 'b', 'c.d.e', 'f'

With this PR applied:

expandProperties('a,b,c.d.e,f', console.log); //=> 'a,b,c.d.e,f'

Edited to remove reference of nested brace expansion, since we don't intend to support it.

current[index] = part;
all.push(current);
});
parts.forEach((part) => {
Copy link
Member

Choose a reason for hiding this comment

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

Map? Or should this be unrolled

Copy link
Member

Choose a reason for hiding this comment

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

Seems like it should be a straight for loop here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point about the map, @stefanpenner.

Since there's an overall desire to reduce function calls, I'll rewrite this as a straight for loop.

@rwjblue
Copy link
Member

rwjblue commented Apr 2, 2016

I was under the impression that we did not intend to support nested brace expansion, so I'm not sure if we should add that.

@stefanpenner/@krisselden - Thoughts?

I'm also somewhat curious to see if we have made this better or worse performance wise, would it be possible to make a small benchmark before and after?

@nickiaconis
Copy link
Contributor Author

@rwjblue I did not remember if we talked about the nesting in person or, if we did, what the conclusion was, and I didn't get a response about it over on #13217. It's possible to remove the second commit, which is the one that introduces nested handling, without affecting comma handling.

I'll put together a benchmark to compare before/comma/nested.

@rwjblue
Copy link
Member

rwjblue commented Apr 2, 2016

Awesome, that would be great, thank you.

@rwjblue
Copy link
Member

rwjblue commented Apr 10, 2016

@nickiaconis - Any updates here?

@nickiaconis
Copy link
Contributor Author

Here are the results of the benchmarking. The code used to run the benchmark is also included in the gist.

Since the "comma" and "nested" versions were so much slower than the "before" version, I wrote a few other implementations. The "iteration" version is a little slower than the "before" version, but I think it's close enough to be acceptable.

@rwjblue
Copy link
Member

rwjblue commented Apr 12, 2016

Thanks for putting in the time on that benchmark! The iteration version looks good to me (implementation and perf wise).

@krisselden - What do you think?

@nickiaconis
Copy link
Contributor Author

On April 12, @krisselden mentioned he was reviewing my benchmarks by trying them in a browser:

JIT stuff can make what you are testing not actually what you think
I just need to confirm them
I’m just not sure why they are so different

I wonder at what conclusion he arrived.

@homu
Copy link
Contributor

homu commented Jun 15, 2016

☔ The latest upstream changes (presumably #13658) made this pull request unmergeable. Please resolve the merge conflicts.

@stefanpenner
Copy link
Member

I am nervous about supporting this feature at all, Is it really common for people to valid properties with , in them?

@nickiaconis
Copy link
Contributor Author

nickiaconis commented Dec 30, 2016

@stefanpenner I don't know if it's common, but it can definitely happen, especially when the property names are generated dynamically. For example, the place where I bumped into this was Erik's app-cache-demo from EmberConf 2016. The (static) data is set in the application route, and it has a model whose ID contains a comma. Later, that ID is used to create a computed property. Of course, this doesn't work because of the bug this PR aims to fix, hence the need to remove all commas from IDs in the component.

@stefanpenner
Copy link
Member

The perf improvement in the iteration fix variant is very nice. I appreciate the due diligence here.

We (the ember core team) needs to decide if this is something we intend to support or not. As demonstrated it doesn't appear to make the status quo worse.

The only technical concern I can think of is, can we make the status quo better, and would enabling this feature prevent that?

@tomdale would love your guidance here.

let part = parts[i];
if (part.indexOf(',') >= 0) {
properties = duplicateAndReplace(properties, part.split(','), i);
// Iterating backward over the pattern makes dealing with indeces easier.
Copy link
Member

Choose a reason for hiding this comment

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

Nitpick: s/indeces/indices/

@tomdale
Copy link
Member

tomdale commented Jan 3, 2017

This seems like a great improvement to me. While it's easy to consider the previous ,-splitting behavior an edge case, it's infuriating to be able to express something valid in the language that isn't supported by your tools—and becomes the kind of thing that makes people think they don't like "magic."

My only comment is that I wouldn't mind having a few more tests to verify correct behavior in other, weird cases like nested {s, missing }s, etc. And I wonder if there is any performance benefit to having a fast path that checks for indexOf('}') and bails early if < 0? (There may not be, given the nature of the implementation.)

(And let me just say, @nickiaconis, I am very impressed that you implemented a stateful mini-parser here instead of trying to gin up an overly complicated regular expression, which seems like what most people try to do in these scenarios.)

@nickiaconis
Copy link
Contributor Author

Thanks for the review, @tomdale!

Upstream changes have added tests for nested {s and missing }s. Now that I've rebased, those cases are covered. Were there any other tests you had in mind?

Speaking of upstream changes, an assertion to catch unbalanced and nested braces was added, which involves iterating over pattern, just as the mini-parser does. I've rolled that assertion into the mini-parser's iteration for a slight performance win. Do you agree with this choice? I've made it a separate commit for now, so it can be either squashed or pruned before merging.

The performance of pattern.indexOf is O(n), and the performance of the mini-parser when pattern.indexOf('{') === -1 is O(n), so there would be no performance benefit to bailing early. It might boost code clarity, but at the cost of a minor performance degradation when pattern.indexOf('{') !== -1, so I'd recommend against.

P.S. What's the rational behind the no-const-outside-module-scope ESLint rule?

@rwjblue
Copy link
Member

rwjblue commented Jan 4, 2017

P.S. What's the rational behind the no-const-outside-module-scope ESLint rule?

See "liberal let" in http://madhatted.com/2016/1/25/let-it-be.

@nickiaconis
Copy link
Contributor Author

Thanks for the info @rwjblue! I'm of the "constantly const" opinion as articulated in https://ponyfoo.com/articles/var-let-const, but it's good to read a differing opinion.

@homu
Copy link
Contributor

homu commented Jan 17, 2017

☔ The latest upstream changes (presumably #14830) made this pull request unmergeable. Please resolve the merge conflicts.

@nickiaconis
Copy link
Contributor Author

@rwjblue I've rebased and resolved merge conflicts, so this is ready for review and/or merge.

@rwjblue
Copy link
Member

rwjblue commented Feb 2, 2017

LETS DO IT!

Serabe added a commit to Serabe/ember.js that referenced this pull request May 7, 2017
There was a bug in the brace expansion implementation before 2.13 that
admitted expressions like `a.{b,c` and `a.b,c` in property expansion
without failing.

On February 2017, emberjs#13231 was merged improving the implementation of
`expandProperties` and fixing the previous issue.

Sadly, people upgrading from 2.12 are having problems with this. We have
two options here:

- Backporting emberjs#13231 fixes it and can be done, as of today, without any
  problem just by cherry-picking its two commits. Sadly, this would
  break people apps in a patch version, and this bug does not seem like
  a critical bugfix.

- Adding a warning if a user is using invalid properties. I went with
  this option since it looks like the less intrusive one while letting
  the users know that their apps will break in the next update.
Serabe added a commit to Serabe/ember.js that referenced this pull request May 8, 2017
There was a bug in the brace expansion implementation before 2.13 that
admitted expressions like `a.{b,c` and `a.b,c` in property expansion
without failing.

On February 2017, emberjs#13231 was merged improving the implementation of
`expandProperties` and fixing the previous issue.

Sadly, people upgrading from 2.12 are having problems with this. We have
two options here:

- Backporting emberjs#13231 fixes it and can be done, as of today, without any
  problem just by cherry-picking its two commits. Sadly, this would
  break people apps in a patch version, and this bug does not seem like
  a critical bugfix.

- Adding a warning if a user is using invalid properties. I went with
  this option since it looks like the less intrusive one while letting
  the users know that their apps will break in the next update.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants