GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — Correctly cache tagged template objects in modules by DanielRosenwasser · Pull Request #18300 · microsoft/TypeScript Conversation
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||
| var f; | ||
| var x = new new new (_a = ["abc", "def"], _a.raw = ["abc", "def"], f(_a, 0)).member("hello")(42) === true; | ||
| var x = new new new f(_a || (_a = __getTemplateObject(["abc", "def"], ["abc", "def"])), 0).member("hello")(42) === true; |
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
This is a regression. Ron Buckton (@rbuckton), any idea why we don't auto-parenthesize here?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
587c8a8 to
166af8c
Compare
…st node that is a call expression).
| } | ||
|
|
||
| function checkTaggedTemplateExpression(node: TaggedTemplateExpression): Type { | ||
| if (languageVersion < ScriptTarget.ES2015) { |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Apparent change in file permissions?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Should be fixed.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| case ExternalEmitHelpers.AsyncDelegator: return "__asyncDelegator"; | ||
| case ExternalEmitHelpers.AsyncValues: return "__asyncValues"; | ||
| case ExternalEmitHelpers.ExportStar: return "__exportStar"; | ||
| case ExternalEmitHelpers.MakeTemplateObject: return "__makeTemplateObject"; |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Not added in this PR, but all of the strings here are duplicated elsewhere in the emitter -- could we move this function to there?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| let hierarchyFacts: HierarchyFacts; | ||
| let taggedTemplateStringDeclarations: VariableDeclaration[]; | ||
| function recordTaggedTemplateString(temp: Identifier) { | ||
| const decl = createVariableDeclaration(temp); |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
taggedTemplateStringDeclarations = append(taggedTemplateStringDeclarations, createVariableDeclaration(temp));
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| // Allocate storage for the template site object if we're in a module. | ||
| // In the global scope, any variable we currently generate could conflict with | ||
| // variables from outside of the current compilation. | ||
| const temp = isExternalModule(currentSourceFile) ? createTempVariable(recordTaggedTemplateString) : undefined; |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Could this variable be created closer to its use, or is there some side effect I'm missing?
If you do move it next to its use, you could just replace !temp ? ... with !isExternalModule(currentSourceFile) ? ...
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| text: ` | ||
| var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) { | ||
| if (Object.defineProperty) { | ||
| return Object.defineProperty(cooked, "raw", { value: raw }); |
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Would be more readable if both branches shared return cooked;:
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } return cooked;
Otherwise it looks like they return different things...
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Alternatively, you can go for even less readable, and do return Object.defineProperty ? Object.defineProperty(cooked, "raw", { value: raw }) : (cooked.raw = raw, cooked);. Can cram the entire helper into one line and it's not bad, actually:
var __makeTemplateObject = (this && this.__makeTemplateObject) || (cooked, raw) => Object.defineProperty ? Object.defineProperty(cooked, "raw", { value: raw }) : (cooked.raw = raw, cooked);
Too bad we don't transpile helpers 👅
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Spoke with Wesley; apparently Uglify can do a better job on the following thanks to ternary/comma precedence rules:
function __makeTemplateObject(cooked, raw) { if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } return cooked; };
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
|
||
| FirstEmitHelper = Extends, | ||
| LastEmitHelper = ExportStar | ||
| LastEmitHelper = ExternalEmitHelpers[" LastPlusOne"] - 1 |
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
You could also just move this next to the last one to make it obvious that these should be updated together. Same for FirstEmitHelper.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Agreed. 👎 for the magic string in the enum.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Would be nice to add a test that shows off the caching in action.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| AsyncDelegator = 1 << 13, // __asyncDelegator (used by ES2017 async generator yield* transformation) | ||
| AsyncValues = 1 << 14, // __asyncValues (used by ES2017 for..await..of transformation) | ||
| ExportStar = 1 << 15, // __exportStar (used by CommonJS/AMD/UMD module transformation) | ||
| Extends = 1 << 0, // __extends (used by the ES2015 class transformation) |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
this change is an example of why aligned comments make me sad :(
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
:(
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| return createParen(expression); | ||
|
|
||
| case SyntaxKind.NewExpression: | ||
| return (<NewExpression>emittedExpression).arguments |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
I would swap this back to the original order.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| // If we're in the global scope, we risk having conflicting variables. | ||
| // Since we currently lack the infrastructure to create sufficiently unique names, | ||
| // we'll fall back to creating the template object on every invocation. | ||
| templateArguments[0] = !temp ? |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
if isExternalModule is cheap to call, it would be nice to do so here; much easier to read.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Also consider flipping the conditional.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
I'd like to see a test that is downlevel, with modules, without importHelpers - just because I don't think I see any covering that configuration. Other than that, most everything else seems fine.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| @@ -0,0 +1 @@ | |||
| new (x ? y : z) No newline at end of file | |||
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Was this a drive-by new test and fix?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Ah, yes:
Fix weird case with un-parenthesized new expressions
Sorry, something went wrong.
There was an error while loading. Please reload this page.
9f3db7f to
f22a1fe
Compare
f22a1fe to
5da45fb
Compare
|
I won't have time to look at this until Monday, but be aware that there was a Needs Consensus PR regarding template literal cache lifetime last week that reached consensus. I don't know yet whether this affects this change. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
Ron Buckton (@rbuckton) within a module, this PR reflects those semantics. At the global scope, we continue to do the same thing as we've always done until we have a better mechanism. Brandon CS Sanders (@sanders) Wesley Wigham (@weswigham) should be there now in |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| priority: 0, | ||
| text: ` | ||
| var __getTemplateObject = (this && this.__getTemplateObject) || function (cooked, raw) { | ||
| if (Object.freeze && Object.defineProperty) { |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Do you need the defineProperty call? I suppose it makes the property non-enumerable...
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
|
||
| FirstEmitHelper = Extends, | ||
| LastEmitHelper = ExportStar | ||
| LastEmitHelper = ExternalEmitHelpers[" LastPlusOne"] - 1 |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Agreed. 👎 for the magic string in the enum.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| scoped: false, | ||
| priority: 0, | ||
| text: ` | ||
| var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) { |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
What about:
cooked.raw = raw; if (Object.freeze) Object.freeze(cooked); return cooked;
Or, the one-line alternative:
return Object.defineProperty ? Object.defineProperty(cooked, "raw", { value: raw }) : (cooked.raw = raw, cooked);
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Uglify already produces a shorter output given this current implementation.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Slightly better one-liner (two less characters, just as readable and correct):
return Object.defineProperty ? Object.defineProperty(cooked, "raw", { value: raw }) : cooked.raw = raw, cooked;
Which is, coincidentally, how uglify restructures what daniel has right now when it minifies it.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| case ExternalEmitHelpers.AsyncDelegator: return "__asyncDelegator"; | ||
| case ExternalEmitHelpers.AsyncValues: return "__asyncValues"; | ||
| case ExternalEmitHelpers.ExportStar: return "__exportStar"; | ||
| case ExternalEmitHelpers.MakeTemplateObject: return "__makeTemplateObject"; |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Would it be worth considering a shorter name than __makeTemplateObject?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Ron Buckton (@rbuckton) Babel uses _taggedTemplateLiteral which is two characters longer. If you can think of something by Monday afternoon before I merge this in, I will consider it 😄
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
__template? (I like this since it doesn't have any camel-casing)
__templatize?
__intoTemplate?
__addRaw?
__createTemplateArg? (not really shorter, I know)
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.