{"action":"created","issue":{"url":"https://api.github.com/repos/Microsoft/TypeScript/issues/3022","labels_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/3022/labels{/name}","comments_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/3022/comments","events_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/3022/events","html_url":"https://github.com/Microsoft/TypeScript/issues/3022","id":73080220,"number":3022,"title":"Proposal: embedded syntax block","user":{"login":"tinganho","id":1324476,"avatar_url":"https://avatars.githubusercontent.com/u/1324476?v=3","gravatar_id":"","url":"https://api.github.com/users/tinganho","html_url":"https://github.com/tinganho","followers_url":"https://api.github.com/users/tinganho/followers","following_url":"https://api.github.com/users/tinganho/following{/other_user}","gists_url":"https://api.github.com/users/tinganho/gists{/gist_id}","starred_url":"https://api.github.com/users/tinganho/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tinganho/subscriptions","organizations_url":"https://api.github.com/users/tinganho/orgs","repos_url":"https://api.github.com/users/tinganho/repos","events_url":"https://api.github.com/users/tinganho/events{/privacy}","received_events_url":"https://api.github.com/users/tinganho/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/Microsoft/TypeScript/labels/In%20Discussion","name":"In Discussion","color":"556b75"},{"url":"https://api.github.com/repos/Microsoft/TypeScript/labels/Suggestion","name":"Suggestion","color":"006b75"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":13,"created_at":"2015-05-04T17:37:05Z","updated_at":"2015-05-05T07:59:09Z","closed_at":null,"body":"I have watched this PR #2673 and this #296 discussion for a time. But I somehow don't think it is the right approach to accept `JSX` directly into `TS`. There seem to be a demand of embedding HTML and even CSS in JS. Facebook might be the pioneer in embedding HTML in JS and therefore gotten a lot of attention recently with `JSX/React`. If `JSX` got accepted into `TS`, it would probably send a clear message to the JS and TS community that the TS team thinks JSX is the right way(and the only way) to go in terms of rendering views. I think it is more a correct way to accept an \"embedded syntax block\", so different frameworks have a chance to compete with JSX. It is a more generalized approach as oppose to accepting JSX directly into the TS.\r\n\r\nAlso remember that @ahejlsberg said \"A framework is created nearly every day\". So who knows if React will survive the next 2 years? Just remember how fast `Angular 1` was popular and very quickly perceived as outdated(roughly a year?). That's how fast the web moves today.\r\n\r\nSo in rough terms here is my thoughts on this \"embedded syntax block\". I will take `JSX` as an example:\r\n\r\nFirst, we refer to a JSX to TS transpiler. So we can transpile JSX to TS in our source code:\r\n```typescript\r\n///<transpiler name=\"jsx\" path=\"../node_modules/jsx-ts-transpiler/transpiler.ts\"/>\r\n```\r\nNow, we define a JSX block we want transpiled into TS using the syntax `syntax 'jsx' {...}`:\r\n```typescript\r\nlet HelloMessage = React.createClass({\r\n  render: function() {\r\n    return syntax 'jsx' { <div>Hello {this.props.name}</div> }\r\n  }\r\n});\r\n```\r\nThe TS's `scanner` stops at `syntax 'jsx' {` and feeds the string that reaches the closing brace `}` of the syntax block to the JSX-TS transpiler in this case: `<div>Hello {this.props.name}</div>`. The JSX-TS transpiler emits the correct TS code back along with a source map so we can map any lines and columns in the emitted TS back to our JSX. Here is how the transpiler looks like:\r\n```typescript\r\nexport transpile(source: string) {\r\n  // Do something with the source\r\n  return { output, sourceMap, diagnostics };\r\n}\r\n```\r\nNow the TS scanner goes ahead an parse it as if it was a normal TS file.\r\n```typescript\r\nlet HelloMessage = React.createClass({\r\n  render: function() {\r\n    return React.createElement(\"div\", null, \"Hello\", this.props.name);\r\n  }\r\n});\r\n```\r\nNow, we want all nodes outside of any \"embedded syntax block\" to have the same positions(`pos` and `end`) as if they where without any line and column shifts. So that we can have the correct positions on errors and warnings autocomplete etc. This is easily done by just offsetting a node's `pos` and `end` by keeping track of how much the emitted JSX-TS output shifts in character positions. For the emitted AST nodes we would marked them coming from a particular embedded syntax block(the embedded syntax block itself is an AST node with `pos` and `end`). The emitted TS nodes will be assigned `pos` and `end` beginning from `0` and not the start of its' syntax block.\r\n\r\nNow, we have all the information we need to output the correct positions in source map and diagnostics. The diagnostics and the source map needs to be rewritten to take into consideration the new embedded syntax blocks along with its' emitted TS code.\r\n\r\nI think this is a more open approach. If you accepts JSX directly into TS, then you are practically closing the door for any future syntax embeds and letting Facebook decide the future of syntax embeds."},"comment":{"url":"https://api.github.com/repos/Microsoft/TypeScript/issues/comments/98986903","html_url":"https://github.com/Microsoft/TypeScript/issues/3022#issuecomment-98986903","issue_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/3022","id":98986903,"user":{"login":"tinganho","id":1324476,"avatar_url":"https://avatars.githubusercontent.com/u/1324476?v=3","gravatar_id":"","url":"https://api.github.com/users/tinganho","html_url":"https://github.com/tinganho","followers_url":"https://api.github.com/users/tinganho/followers","following_url":"https://api.github.com/users/tinganho/following{/other_user}","gists_url":"https://api.github.com/users/tinganho/gists{/gist_id}","starred_url":"https://api.github.com/users/tinganho/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tinganho/subscriptions","organizations_url":"https://api.github.com/users/tinganho/orgs","repos_url":"https://api.github.com/users/tinganho/repos","events_url":"https://api.github.com/users/tinganho/events{/privacy}","received_events_url":"https://api.github.com/users/tinganho/received_events","type":"User","site_admin":false},"created_at":"2015-05-05T07:59:09Z","updated_at":"2015-05-05T07:59:09Z","body":"@icetraxx isn't `'jsx' {...}` enough? You would need at least a `start( { )`, `end ( } )` and if you want to support more than one type of embed you need to specify the `type ( 'jsx' )` of the embed?\r\n\r\nFor the Babel transforms:\r\nI'm not sure if this is correct but it seems like Babel are visiting/looping through all the nodes one per custom transform and is only editable within their range of supported AST nodes?\r\nhttp://babeljs.io/docs/usage/plugins/\r\n\r\nThis solutions doesn't create an additional loop and doesn't rely on TS team to support any new AST nodes."}}