mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
Import assertions (#5391)
This commit is contained in:
parent
20b8362887
commit
f557c0579b
21 changed files with 735 additions and 210 deletions
1
Cakefile
1
Cakefile
|
@ -476,6 +476,7 @@ runTests = (CoffeeScript) ->
|
|||
skipUnless '/foo.bar/s.test("foo\tbar")', ['regex_dotall.coffee']
|
||||
skipUnless '1_2_3', ['numeric_literal_separators.coffee']
|
||||
skipUnless '1n', ['numbers_bigint.coffee']
|
||||
skipUnless 'async () => { await import(\'data:application/json,{"foo":"bar"}\', { assert: { type: "json" } }) }', ['import_assertions.coffee']
|
||||
files = fs.readdirSync('test').filter (filename) ->
|
||||
filename not in testFilesToSkip
|
||||
|
||||
|
|
|
@ -277,7 +277,7 @@ defined above. The <code>LOC</code> function, when used below in the grammar rul
|
|||
is used to make sure that newly created node class objects get correct
|
||||
location data assigned to them. By default, the grammar will assign the
|
||||
location data spanned by <em>all</em> of the tokens on the left (e.g. a string
|
||||
such as <code>'Body TERMINATOR Line'</code>) to the “top-level” node returned by
|
||||
such as <code>'Body TERMINATOR Line'</code>) to the “top-level” node returned by
|
||||
the grammar rule (the function on the right). But for “inner” node class
|
||||
objects created by grammar rules, they won’t get correct location data
|
||||
assigned to them without adding <code>LOC</code>.</p>
|
||||
|
@ -1146,13 +1146,20 @@ and optional references to the superclass.</p>
|
|||
]
|
||||
|
||||
Import: [
|
||||
o <span class="hljs-string">'IMPORT String'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ImportDeclaration <span class="hljs-literal">null</span>, $<span class="hljs-number">2</span>
|
||||
o <span class="hljs-string">'IMPORT ImportDefaultSpecifier FROM String'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ImportDeclaration <span class="hljs-keyword">new</span> ImportClause($<span class="hljs-number">2</span>, <span class="hljs-literal">null</span>), $<span class="hljs-number">4</span>
|
||||
o <span class="hljs-string">'IMPORT ImportNamespaceSpecifier FROM String'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ImportDeclaration <span class="hljs-keyword">new</span> ImportClause(<span class="hljs-literal">null</span>, $<span class="hljs-number">2</span>), $<span class="hljs-number">4</span>
|
||||
o <span class="hljs-string">'IMPORT { } FROM String'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ImportDeclaration <span class="hljs-keyword">new</span> ImportClause(<span class="hljs-literal">null</span>, <span class="hljs-keyword">new</span> ImportSpecifierList []), $<span class="hljs-number">5</span>
|
||||
o <span class="hljs-string">'IMPORT { ImportSpecifierList OptComma } FROM String'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ImportDeclaration <span class="hljs-keyword">new</span> ImportClause(<span class="hljs-literal">null</span>, <span class="hljs-keyword">new</span> ImportSpecifierList $<span class="hljs-number">3</span>), $<span class="hljs-number">7</span>
|
||||
o <span class="hljs-string">'IMPORT ImportDefaultSpecifier , ImportNamespaceSpecifier FROM String'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ImportDeclaration <span class="hljs-keyword">new</span> ImportClause($<span class="hljs-number">2</span>, $<span class="hljs-number">4</span>), $<span class="hljs-number">6</span>
|
||||
o <span class="hljs-string">'IMPORT ImportDefaultSpecifier , { ImportSpecifierList OptComma } FROM String'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ImportDeclaration <span class="hljs-keyword">new</span> ImportClause($<span class="hljs-number">2</span>, <span class="hljs-keyword">new</span> ImportSpecifierList $<span class="hljs-number">5</span>), $<span class="hljs-number">9</span>
|
||||
o <span class="hljs-string">'IMPORT String'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ImportDeclaration <span class="hljs-literal">null</span>, $<span class="hljs-number">2</span>
|
||||
o <span class="hljs-string">'IMPORT String ASSERT Object'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ImportDeclaration <span class="hljs-literal">null</span>, $<span class="hljs-number">2</span>, $<span class="hljs-number">4</span>
|
||||
o <span class="hljs-string">'IMPORT ImportDefaultSpecifier FROM String'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ImportDeclaration <span class="hljs-keyword">new</span> ImportClause($<span class="hljs-number">2</span>, <span class="hljs-literal">null</span>), $<span class="hljs-number">4</span>
|
||||
o <span class="hljs-string">'IMPORT ImportDefaultSpecifier FROM String ASSERT Object'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ImportDeclaration <span class="hljs-keyword">new</span> ImportClause($<span class="hljs-number">2</span>, <span class="hljs-literal">null</span>), $<span class="hljs-number">4</span>, $<span class="hljs-number">6</span>
|
||||
o <span class="hljs-string">'IMPORT ImportNamespaceSpecifier FROM String'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ImportDeclaration <span class="hljs-keyword">new</span> ImportClause(<span class="hljs-literal">null</span>, $<span class="hljs-number">2</span>), $<span class="hljs-number">4</span>
|
||||
o <span class="hljs-string">'IMPORT ImportNamespaceSpecifier FROM String ASSERT Object'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ImportDeclaration <span class="hljs-keyword">new</span> ImportClause(<span class="hljs-literal">null</span>, $<span class="hljs-number">2</span>), $<span class="hljs-number">4</span>, $<span class="hljs-number">6</span>
|
||||
o <span class="hljs-string">'IMPORT { } FROM String'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ImportDeclaration <span class="hljs-keyword">new</span> ImportClause(<span class="hljs-literal">null</span>, <span class="hljs-keyword">new</span> ImportSpecifierList []), $<span class="hljs-number">5</span>
|
||||
o <span class="hljs-string">'IMPORT { } FROM String ASSERT Object'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ImportDeclaration <span class="hljs-keyword">new</span> ImportClause(<span class="hljs-literal">null</span>, <span class="hljs-keyword">new</span> ImportSpecifierList []), $<span class="hljs-number">5</span>, $<span class="hljs-number">7</span>
|
||||
o <span class="hljs-string">'IMPORT { ImportSpecifierList OptComma } FROM String'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ImportDeclaration <span class="hljs-keyword">new</span> ImportClause(<span class="hljs-literal">null</span>, <span class="hljs-keyword">new</span> ImportSpecifierList $<span class="hljs-number">3</span>), $<span class="hljs-number">7</span>
|
||||
o <span class="hljs-string">'IMPORT { ImportSpecifierList OptComma } FROM String ASSERT Object'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ImportDeclaration <span class="hljs-keyword">new</span> ImportClause(<span class="hljs-literal">null</span>, <span class="hljs-keyword">new</span> ImportSpecifierList $<span class="hljs-number">3</span>), $<span class="hljs-number">7</span>, $<span class="hljs-number">9</span>
|
||||
o <span class="hljs-string">'IMPORT ImportDefaultSpecifier , ImportNamespaceSpecifier FROM String'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ImportDeclaration <span class="hljs-keyword">new</span> ImportClause($<span class="hljs-number">2</span>, $<span class="hljs-number">4</span>), $<span class="hljs-number">6</span>
|
||||
o <span class="hljs-string">'IMPORT ImportDefaultSpecifier , ImportNamespaceSpecifier FROM String ASSERT Object'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ImportDeclaration <span class="hljs-keyword">new</span> ImportClause($<span class="hljs-number">2</span>, $<span class="hljs-number">4</span>), $<span class="hljs-number">6</span>, $<span class="hljs-number">8</span>
|
||||
o <span class="hljs-string">'IMPORT ImportDefaultSpecifier , { ImportSpecifierList OptComma } FROM String'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ImportDeclaration <span class="hljs-keyword">new</span> ImportClause($<span class="hljs-number">2</span>, <span class="hljs-keyword">new</span> ImportSpecifierList $<span class="hljs-number">5</span>), $<span class="hljs-number">9</span>
|
||||
o <span class="hljs-string">'IMPORT ImportDefaultSpecifier , { ImportSpecifierList OptComma } FROM String ASSERT Object'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ImportDeclaration <span class="hljs-keyword">new</span> ImportClause($<span class="hljs-number">2</span>, <span class="hljs-keyword">new</span> ImportSpecifierList $<span class="hljs-number">5</span>), $<span class="hljs-number">9</span>, $<span class="hljs-number">11</span>
|
||||
]
|
||||
|
||||
ImportSpecifierList: [
|
||||
|
@ -1179,20 +1186,23 @@ and optional references to the superclass.</p>
|
|||
]
|
||||
|
||||
Export: [
|
||||
o <span class="hljs-string">'EXPORT { }'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportNamedDeclaration <span class="hljs-keyword">new</span> ExportSpecifierList []
|
||||
o <span class="hljs-string">'EXPORT { ExportSpecifierList OptComma }'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportNamedDeclaration <span class="hljs-keyword">new</span> ExportSpecifierList $<span class="hljs-number">3</span>
|
||||
o <span class="hljs-string">'EXPORT Class'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportNamedDeclaration $<span class="hljs-number">2</span>
|
||||
o <span class="hljs-string">'EXPORT Identifier = Expression'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportNamedDeclaration LOC(<span class="hljs-number">2</span>,<span class="hljs-number">4</span>)(<span class="hljs-keyword">new</span> Assign $<span class="hljs-number">2</span>, $<span class="hljs-number">4</span>, <span class="hljs-literal">null</span>,
|
||||
o <span class="hljs-string">'EXPORT { }'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportNamedDeclaration <span class="hljs-keyword">new</span> ExportSpecifierList []
|
||||
o <span class="hljs-string">'EXPORT { ExportSpecifierList OptComma }'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportNamedDeclaration <span class="hljs-keyword">new</span> ExportSpecifierList $<span class="hljs-number">3</span>
|
||||
o <span class="hljs-string">'EXPORT Class'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportNamedDeclaration $<span class="hljs-number">2</span>
|
||||
o <span class="hljs-string">'EXPORT Identifier = Expression'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportNamedDeclaration LOC(<span class="hljs-number">2</span>,<span class="hljs-number">4</span>)(<span class="hljs-keyword">new</span> Assign $<span class="hljs-number">2</span>, $<span class="hljs-number">4</span>, <span class="hljs-literal">null</span>,
|
||||
moduleDeclaration: <span class="hljs-string">'export'</span>)
|
||||
o <span class="hljs-string">'EXPORT Identifier = TERMINATOR Expression'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportNamedDeclaration LOC(<span class="hljs-number">2</span>,<span class="hljs-number">5</span>)(<span class="hljs-keyword">new</span> Assign $<span class="hljs-number">2</span>, $<span class="hljs-number">5</span>, <span class="hljs-literal">null</span>,
|
||||
o <span class="hljs-string">'EXPORT Identifier = TERMINATOR Expression'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportNamedDeclaration LOC(<span class="hljs-number">2</span>,<span class="hljs-number">5</span>)(<span class="hljs-keyword">new</span> Assign $<span class="hljs-number">2</span>, $<span class="hljs-number">5</span>, <span class="hljs-literal">null</span>,
|
||||
moduleDeclaration: <span class="hljs-string">'export'</span>)
|
||||
o <span class="hljs-string">'EXPORT Identifier = INDENT Expression OUTDENT'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportNamedDeclaration LOC(<span class="hljs-number">2</span>,<span class="hljs-number">6</span>)(<span class="hljs-keyword">new</span> Assign $<span class="hljs-number">2</span>, $<span class="hljs-number">5</span>, <span class="hljs-literal">null</span>,
|
||||
o <span class="hljs-string">'EXPORT Identifier = INDENT Expression OUTDENT'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportNamedDeclaration LOC(<span class="hljs-number">2</span>,<span class="hljs-number">6</span>)(<span class="hljs-keyword">new</span> Assign $<span class="hljs-number">2</span>, $<span class="hljs-number">5</span>, <span class="hljs-literal">null</span>,
|
||||
moduleDeclaration: <span class="hljs-string">'export'</span>)
|
||||
o <span class="hljs-string">'EXPORT DEFAULT Expression'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportDefaultDeclaration $<span class="hljs-number">3</span>
|
||||
o <span class="hljs-string">'EXPORT DEFAULT INDENT Object OUTDENT'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportDefaultDeclaration <span class="hljs-keyword">new</span> Value $<span class="hljs-number">4</span>
|
||||
o <span class="hljs-string">'EXPORT EXPORT_ALL FROM String'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportAllDeclaration <span class="hljs-keyword">new</span> Literal($<span class="hljs-number">2</span>), $<span class="hljs-number">4</span>
|
||||
o <span class="hljs-string">'EXPORT { } FROM String'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportNamedDeclaration <span class="hljs-keyword">new</span> ExportSpecifierList([]), $<span class="hljs-number">5</span>
|
||||
o <span class="hljs-string">'EXPORT { ExportSpecifierList OptComma } FROM String'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportNamedDeclaration <span class="hljs-keyword">new</span> ExportSpecifierList($<span class="hljs-number">3</span>), $<span class="hljs-number">7</span>
|
||||
o <span class="hljs-string">'EXPORT DEFAULT Expression'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportDefaultDeclaration $<span class="hljs-number">3</span>
|
||||
o <span class="hljs-string">'EXPORT DEFAULT INDENT Object OUTDENT'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportDefaultDeclaration <span class="hljs-keyword">new</span> Value $<span class="hljs-number">4</span>
|
||||
o <span class="hljs-string">'EXPORT EXPORT_ALL FROM String'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportAllDeclaration <span class="hljs-keyword">new</span> Literal($<span class="hljs-number">2</span>), $<span class="hljs-number">4</span>
|
||||
o <span class="hljs-string">'EXPORT EXPORT_ALL FROM String ASSERT Object'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportAllDeclaration <span class="hljs-keyword">new</span> Literal($<span class="hljs-number">2</span>), $<span class="hljs-number">4</span>, $<span class="hljs-number">6</span>
|
||||
o <span class="hljs-string">'EXPORT { } FROM String'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportNamedDeclaration <span class="hljs-keyword">new</span> ExportSpecifierList([]), $<span class="hljs-number">5</span>
|
||||
o <span class="hljs-string">'EXPORT { } FROM String ASSERT Object'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportNamedDeclaration <span class="hljs-keyword">new</span> ExportSpecifierList([]), $<span class="hljs-number">5</span>, $<span class="hljs-number">7</span>
|
||||
o <span class="hljs-string">'EXPORT { ExportSpecifierList OptComma } FROM String'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportNamedDeclaration <span class="hljs-keyword">new</span> ExportSpecifierList($<span class="hljs-number">3</span>), $<span class="hljs-number">7</span>
|
||||
o <span class="hljs-string">'EXPORT { ExportSpecifierList OptComma } FROM String ASSERT Object'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportNamedDeclaration <span class="hljs-keyword">new</span> ExportSpecifierList($<span class="hljs-number">3</span>), $<span class="hljs-number">7</span>, $<span class="hljs-number">9</span>
|
||||
]
|
||||
|
||||
ExportSpecifierList: [
|
||||
|
|
|
@ -414,6 +414,9 @@ though <code>is</code> means <code>===</code> otherwise.</p>
|
|||
<span class="hljs-keyword">if</span> id <span class="hljs-keyword">is</span> <span class="hljs-string">'default'</span> <span class="hljs-keyword">and</span> @seenExport <span class="hljs-keyword">and</span> @tag() <span class="hljs-keyword">in</span> [<span class="hljs-string">'EXPORT'</span>, <span class="hljs-string">'AS'</span>]
|
||||
@token <span class="hljs-string">'DEFAULT'</span>, id
|
||||
<span class="hljs-keyword">return</span> id.length
|
||||
<span class="hljs-keyword">if</span> id <span class="hljs-keyword">is</span> <span class="hljs-string">'assert'</span> <span class="hljs-keyword">and</span> (@seenImport <span class="hljs-keyword">or</span> @seenExport) <span class="hljs-keyword">and</span> @tag() <span class="hljs-keyword">is</span> <span class="hljs-string">'STRING'</span>
|
||||
@token <span class="hljs-string">'ASSERT'</span>, id
|
||||
<span class="hljs-keyword">return</span> id.length
|
||||
<span class="hljs-keyword">if</span> id <span class="hljs-keyword">is</span> <span class="hljs-string">'do'</span> <span class="hljs-keyword">and</span> regExSuper = <span class="hljs-regexp">/^(\s*super)(?!\(\))/</span>.exec @chunk[<span class="hljs-number">3.</span>..]
|
||||
@token <span class="hljs-string">'SUPER'</span>, <span class="hljs-string">'super'</span>
|
||||
@token <span class="hljs-string">'CALL_START'</span>, <span class="hljs-string">'('</span>
|
||||
|
|
|
@ -5845,11 +5845,11 @@ opposed to the <code>Object.defineProperty</code> method).</p>
|
|||
|
||||
<div class="content"><div class='highlight'><pre>
|
||||
<span class="hljs-built_in">exports</span>.ModuleDeclaration = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ModuleDeclaration</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
|
||||
constructor: <span class="hljs-function"><span class="hljs-params">(@clause, @source)</span> -></span>
|
||||
constructor: <span class="hljs-function"><span class="hljs-params">(@clause, @source, @assertions)</span> -></span>
|
||||
super()
|
||||
@checkSource()
|
||||
|
||||
children: [<span class="hljs-string">'clause'</span>, <span class="hljs-string">'source'</span>]
|
||||
children: [<span class="hljs-string">'clause'</span>, <span class="hljs-string">'source'</span>, <span class="hljs-string">'assertions'</span>]
|
||||
|
||||
isStatement: YES
|
||||
jumps: THIS
|
||||
|
@ -5880,6 +5880,14 @@ whether we’re at the “program top-level”.</p>
|
|||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> o.indent.length <span class="hljs-keyword">isnt</span> <span class="hljs-number">0</span>
|
||||
@error <span class="hljs-string">"<span class="hljs-subst">#{moduleDeclarationType}</span> statements must be at top-level scope"</span>
|
||||
|
||||
astAssertions: <span class="hljs-function"><span class="hljs-params">(o)</span> -></span>
|
||||
<span class="hljs-keyword">if</span> @assertions?.properties?
|
||||
@assertions.properties.map (assertion) =>
|
||||
{ start, end, loc, left, right } = assertion.ast(o)
|
||||
{ type: <span class="hljs-string">'ImportAttribute'</span>, start, end, loc, key: left, value: right }
|
||||
<span class="hljs-keyword">else</span>
|
||||
[]
|
||||
|
||||
<span class="hljs-built_in">exports</span>.ImportDeclaration = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ImportDeclaration</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ModuleDeclaration</span></span>
|
||||
compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -></span>
|
||||
@checkScope o, <span class="hljs-string">'import'</span>
|
||||
|
@ -5892,6 +5900,9 @@ whether we’re at the “program top-level”.</p>
|
|||
<span class="hljs-keyword">if</span> @source?.value?
|
||||
code.push @makeCode <span class="hljs-string">' from '</span> <span class="hljs-keyword">unless</span> @clause <span class="hljs-keyword">is</span> <span class="hljs-literal">null</span>
|
||||
code.push @makeCode @source.value
|
||||
<span class="hljs-keyword">if</span> @assertions?
|
||||
code.push @makeCode <span class="hljs-string">' assert '</span>
|
||||
code.push @assertions.compileToFragments(o)...
|
||||
|
||||
code.push @makeCode <span class="hljs-string">';'</span>
|
||||
code
|
||||
|
@ -5904,6 +5915,7 @@ whether we’re at the “program top-level”.</p>
|
|||
ret =
|
||||
specifiers: @clause?.ast(o) ? []
|
||||
source: @source.ast o
|
||||
assertions: @astAssertions(o)
|
||||
ret.importKind = <span class="hljs-string">'value'</span> <span class="hljs-keyword">if</span> @clause
|
||||
ret
|
||||
|
||||
|
@ -5965,7 +5977,12 @@ that will be the <code>specifiers</code> property of an <code>ImportDeclaration<
|
|||
<span class="hljs-keyword">else</span>
|
||||
code = code.concat @clause.compileNode o
|
||||
|
||||
code.push @makeCode <span class="hljs-string">" from <span class="hljs-subst">#{@source.value}</span>"</span> <span class="hljs-keyword">if</span> @source?.value?
|
||||
<span class="hljs-keyword">if</span> @source?.value?
|
||||
code.push @makeCode <span class="hljs-string">" from <span class="hljs-subst">#{@source.value}</span>"</span>
|
||||
<span class="hljs-keyword">if</span> @assertions?
|
||||
code.push @makeCode <span class="hljs-string">' assert '</span>
|
||||
code.push @assertions.compileToFragments(o)...
|
||||
|
||||
code.push @makeCode <span class="hljs-string">';'</span>
|
||||
code</pre></div></div>
|
||||
|
||||
|
@ -5994,6 +6011,7 @@ that will be the <code>specifiers</code> property of an <code>ImportDeclaration<
|
|||
astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -></span>
|
||||
ret =
|
||||
source: @source?.ast(o) ? <span class="hljs-literal">null</span>
|
||||
assertions: @astAssertions(o)
|
||||
exportKind: <span class="hljs-string">'value'</span>
|
||||
clauseAst = @clause.ast o
|
||||
<span class="hljs-keyword">if</span> @clause <span class="hljs-keyword">instanceof</span> ExportSpecifierList
|
||||
|
@ -6008,11 +6026,13 @@ that will be the <code>specifiers</code> property of an <code>ImportDeclaration<
|
|||
astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -></span>
|
||||
<span class="hljs-keyword">return</span>
|
||||
declaration: @clause.ast o
|
||||
assertions: @astAssertions(o)
|
||||
|
||||
<span class="hljs-built_in">exports</span>.ExportAllDeclaration = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ExportAllDeclaration</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ExportDeclaration</span></span>
|
||||
astProperties: <span class="hljs-function"><span class="hljs-params">(o)</span> -></span>
|
||||
<span class="hljs-keyword">return</span>
|
||||
source: @source.ast o
|
||||
assertions: @astAssertions(o)
|
||||
exportKind: <span class="hljs-string">'value'</span>
|
||||
|
||||
<span class="hljs-built_in">exports</span>.ModuleSpecifierList = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ModuleSpecifierList</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
|
||||
|
@ -6148,8 +6168,8 @@ that will be the <code>specifiers</code> property of an <code>ImportDeclaration<
|
|||
super o
|
||||
|
||||
checkArguments: <span class="hljs-function">-></span>
|
||||
<span class="hljs-keyword">unless</span> @args.length <span class="hljs-keyword">is</span> <span class="hljs-number">1</span>
|
||||
@error <span class="hljs-string">'import() requires exactly one argument'</span>
|
||||
<span class="hljs-keyword">unless</span> <span class="hljs-number">1</span> <= @args.length <= <span class="hljs-number">2</span>
|
||||
@error <span class="hljs-string">'import() accepts either one or two arguments'</span>
|
||||
|
||||
astNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -></span>
|
||||
@checkArguments()
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -4268,6 +4268,8 @@ import { now as currentTimestamp } from 'underscore'
|
|||
import { first, last } from 'underscore'
|
||||
import utilityBelt, { each } from 'underscore'
|
||||
|
||||
import dates from './calendar.json' assert { type: 'json' }
|
||||
|
||||
export default Math
|
||||
export square = (x) -> x * x
|
||||
export class Mathematics
|
||||
|
@ -4279,6 +4281,7 @@ export { Mathematics as default, sqrt as squareRoot }
|
|||
|
||||
export * from 'underscore'
|
||||
export { max, min } from 'underscore'
|
||||
export { version } from './package.json' assert { type: 'json' }
|
||||
</textarea>
|
||||
<pre class="placeholder-code"><span class="cm-variable">import</span> <span class="cm-string">'./local-file.js'</span> <span class="cm-comment"># Must be the filename of the generated file</span>
|
||||
<span class="cm-variable">import</span> <span class="cm-string">'package'</span>
|
||||
|
@ -4291,6 +4294,8 @@ export { max, min } from 'underscore'
|
|||
<span class="cm-variable">import</span> <span class="cm-punctuation">{</span> <span class="cm-variable">first</span><span class="cm-punctuation">,</span> <span class="cm-variable">last</span> <span class="cm-punctuation">}</span> <span class="cm-variable">from</span> <span class="cm-string">'underscore'</span>
|
||||
<span class="cm-variable">import</span> <span class="cm-variable">utilityBelt</span><span class="cm-punctuation">,</span> <span class="cm-punctuation">{</span> <span class="cm-variable">each</span> <span class="cm-punctuation">}</span> <span class="cm-variable">from</span> <span class="cm-string">'underscore'</span>
|
||||
|
||||
<span class="cm-variable">import</span> <span class="cm-variable">dates</span> <span class="cm-variable">from</span> <span class="cm-string">'./calendar.json'</span> <span class="cm-variable">assert</span> <span class="cm-punctuation">{</span> <span class="cm-variable">type</span><span class="cm-punctuation">:</span> <span class="cm-string">'json'</span> <span class="cm-punctuation">}</span>
|
||||
|
||||
<span class="cm-variable">export</span> <span class="cm-variable">default</span> <span class="cm-variable">Math</span>
|
||||
<span class="cm-variable">export</span> <span class="cm-variable">square</span> <span class="cm-punctuation">=</span> <span class="cm-punctuation">(</span><span class="cm-variable">x</span><span class="cm-punctuation">)</span> <span class="cm-operator">-></span> <span class="cm-variable">x</span> <span class="cm-operator">*</span> <span class="cm-variable">x</span>
|
||||
<span class="cm-variable">export</span> <span class="cm-keyword">class</span> <span class="cm-variable">Mathematics</span>
|
||||
|
@ -4302,6 +4307,7 @@ export { max, min } from 'underscore'
|
|||
|
||||
<span class="cm-variable">export</span> <span class="cm-operator">*</span> <span class="cm-variable">from</span> <span class="cm-string">'underscore'</span>
|
||||
<span class="cm-variable">export</span> <span class="cm-punctuation">{</span> <span class="cm-variable">max</span><span class="cm-punctuation">,</span> <span class="cm-variable">min</span> <span class="cm-punctuation">}</span> <span class="cm-variable">from</span> <span class="cm-string">'underscore'</span>
|
||||
<span class="cm-variable">export</span> <span class="cm-punctuation">{</span> <span class="cm-variable">version</span> <span class="cm-punctuation">}</span> <span class="cm-variable">from</span> <span class="cm-string">'./package.json'</span> <span class="cm-variable">assert</span> <span class="cm-punctuation">{</span> <span class="cm-variable">type</span><span class="cm-punctuation">:</span> <span class="cm-string">'json'</span> <span class="cm-punctuation">}</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="col-md-6 javascript-output-column">
|
||||
|
@ -4330,6 +4336,10 @@ import utilityBelt, {
|
|||
each
|
||||
} from 'underscore';
|
||||
|
||||
import dates from './calendar.json' assert {
|
||||
type: 'json'
|
||||
};
|
||||
|
||||
export default Math;
|
||||
|
||||
export var square = function(x) {
|
||||
|
@ -4366,6 +4376,12 @@ export {
|
|||
max,
|
||||
min
|
||||
} from 'underscore';
|
||||
|
||||
export {
|
||||
version
|
||||
} from './package.json' assert {
|
||||
type: 'json'
|
||||
};
|
||||
</textarea>
|
||||
<pre class="placeholder-code"><span class="cm-keyword">import</span> <span class="cm-string">'./local-file.js'</span>;
|
||||
|
||||
|
@ -4392,6 +4408,10 @@ export {
|
|||
<span class="cm-def">each</span>
|
||||
} <span class="cm-keyword">from</span> <span class="cm-string">'underscore'</span>;
|
||||
|
||||
<span class="cm-keyword">import</span> <span class="cm-def">dates</span> <span class="cm-keyword">from</span> <span class="cm-string">'./calendar.json'</span> <span class="cm-variable">assert</span> {
|
||||
<span class="cm-variable">type</span>: <span class="cm-string">'json'</span>
|
||||
};
|
||||
|
||||
<span class="cm-keyword">export</span> <span class="cm-keyword">default</span> <span class="cm-variable">Math</span>;
|
||||
|
||||
<span class="cm-keyword">export</span> <span class="cm-keyword">var</span> <span class="cm-def">square</span> <span class="cm-operator">=</span> <span class="cm-keyword">function</span>(<span class="cm-def">x</span>) {
|
||||
|
@ -4428,6 +4448,12 @@ export {
|
|||
<span class="cm-variable">max</span>,
|
||||
<span class="cm-variable">min</span>
|
||||
} <span class="cm-keyword">from</span> <span class="cm-string">'underscore'</span>;
|
||||
|
||||
<span class="cm-keyword">export</span> {
|
||||
<span class="cm-variable">version</span>
|
||||
} <span class="cm-keyword">from</span> <span class="cm-string">'./package.json'</span> <span class="cm-variable">assert</span> {
|
||||
<span class="cm-variable">type</span>: <span class="cm-string">'json'</span>
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -2218,6 +2218,31 @@ test "AST as expected for ModuleDeclaration node", ->
|
|||
type: 'StringLiteral'
|
||||
value: '.'
|
||||
|
||||
testStatement 'import X from "." assert { type: "json" }',
|
||||
type: 'ImportDeclaration'
|
||||
specifiers: [
|
||||
type: 'ImportDefaultSpecifier'
|
||||
local:
|
||||
type: 'Identifier'
|
||||
name: 'X'
|
||||
declaration: no
|
||||
]
|
||||
importKind: 'value'
|
||||
source:
|
||||
type: 'StringLiteral'
|
||||
value: '.'
|
||||
assertions: [
|
||||
type: 'ImportAttribute'
|
||||
key:
|
||||
type: 'Identifier'
|
||||
name: 'type'
|
||||
value:
|
||||
type: 'StringLiteral'
|
||||
value: 'json'
|
||||
extra:
|
||||
raw: '"json"'
|
||||
]
|
||||
|
||||
test "AST as expected for ImportDeclaration node", ->
|
||||
testStatement 'import React, {Component} from "react"',
|
||||
type: 'ImportDeclaration'
|
||||
|
@ -2369,6 +2394,26 @@ test "AST as expected for ExportAllDeclaration node", ->
|
|||
raw: '"module-name"'
|
||||
exportKind: 'value'
|
||||
|
||||
testStatement 'export * from "module-name" assert { type: "json" }',
|
||||
type: 'ExportAllDeclaration'
|
||||
source:
|
||||
type: 'StringLiteral'
|
||||
value: 'module-name'
|
||||
extra:
|
||||
raw: '"module-name"'
|
||||
assertions: [
|
||||
type: 'ImportAttribute'
|
||||
key:
|
||||
type: 'Identifier'
|
||||
name: 'type'
|
||||
value:
|
||||
type: 'StringLiteral'
|
||||
value: 'json'
|
||||
extra:
|
||||
raw: '"json"'
|
||||
]
|
||||
exportKind: 'value'
|
||||
|
||||
test "AST as expected for ExportSpecifierList node", ->
|
||||
testStatement 'export {a, b, c}',
|
||||
type: 'ExportNamedDeclaration'
|
||||
|
@ -22988,21 +23033,21 @@ test "`new.target` cannot be assigned", ->
|
|||
^
|
||||
'''
|
||||
|
||||
test "#4834: dynamic import requires exactly one argument", ->
|
||||
test "#4834: dynamic import accepts either one or two arguments", ->
|
||||
assertErrorFormat '''
|
||||
import()
|
||||
''', '''
|
||||
[stdin]:1:1: error: import() requires exactly one argument
|
||||
[stdin]:1:1: error: import() accepts either one or two arguments
|
||||
import()
|
||||
^^^^^^^^
|
||||
'''
|
||||
|
||||
assertErrorFormat '''
|
||||
import('x', {})
|
||||
import('x', {}, 3)
|
||||
''', '''
|
||||
[stdin]:1:1: error: import() requires exactly one argument
|
||||
import('x', {})
|
||||
^^^^^^^^^^^^^^^
|
||||
[stdin]:1:1: error: import() accepts either one or two arguments
|
||||
import('x', {}, 3)
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
'''
|
||||
|
||||
test "#4834: dynamic import requires explicit call parentheses", ->
|
||||
|
@ -25667,6 +25712,97 @@ test "the `baseFileName` helper returns the file name to write to", ->
|
|||
filename = name + ext
|
||||
eq filename, expectedFileName
|
||||
|
||||
</script>
|
||||
<script type="text/x-coffeescript" class="test" id="import_assertions">
|
||||
# This file is running in CommonJS (in Node) or as a classic Script (in the browser tests) so it can use import() within an async function, but not at the top level; and we can’t use static import.
|
||||
test "dynamic import assertion", ->
|
||||
{ default: secret } = await import('data:application/json,{"ofLife":42}', { assert: { type: 'json' } })
|
||||
eq secret.ofLife, 42
|
||||
|
||||
test "assert keyword", ->
|
||||
assert = 1
|
||||
|
||||
{ default: assert } = await import('data:application/json,{"thatIAm":42}', { assert: { type: 'json' } })
|
||||
eq assert.thatIAm, 42
|
||||
|
||||
eqJS """
|
||||
import assert from 'regression-test'
|
||||
""", """
|
||||
import assert from 'regression-test';
|
||||
"""
|
||||
|
||||
|
||||
test "static import assertion", ->
|
||||
eqJS """
|
||||
import 'data:application/json,{"foo":3}' assert { type: 'json' }
|
||||
""", """
|
||||
import 'data:application/json,{"foo":3}' assert {
|
||||
type: 'json'
|
||||
};
|
||||
"""
|
||||
|
||||
eqJS """
|
||||
import secret from 'data:application/json,{"ofLife":42}' assert { type: 'json' }
|
||||
""", """
|
||||
import secret from 'data:application/json,{"ofLife":42}' assert {
|
||||
type: 'json'
|
||||
};
|
||||
"""
|
||||
|
||||
eqJS """
|
||||
import * as secret from 'data:application/json,{"ofLife":42}' assert { type: 'json' }
|
||||
""", """
|
||||
import * as secret from 'data:application/json,{"ofLife":42}' assert {
|
||||
type: 'json'
|
||||
};
|
||||
"""
|
||||
|
||||
# The only file types for which import assertions are currently supported are JSON (Node and browsers) and CSS (browsers), neither of which support named exports; however there’s nothing in the JavaScript grammar preventing a future supported file type from providing named exports.
|
||||
eqJS """
|
||||
import { foo } from './file.unknown' assert { type: 'unknown' }
|
||||
""", """
|
||||
import {
|
||||
foo
|
||||
} from './file.unknown' assert {
|
||||
type: 'unknown'
|
||||
};
|
||||
"""
|
||||
|
||||
eqJS """
|
||||
import file, { foo } from './file.unknown' assert { type: 'unknown' }
|
||||
""", """
|
||||
import file, {
|
||||
foo
|
||||
} from './file.unknown' assert {
|
||||
type: 'unknown'
|
||||
};
|
||||
"""
|
||||
|
||||
eqJS """
|
||||
import foo from 'bar' assert {}
|
||||
""", """
|
||||
import foo from 'bar' assert {};
|
||||
"""
|
||||
|
||||
test "static export with assertion", ->
|
||||
eqJS """
|
||||
export * from 'data:application/json,{"foo":3}' assert { type: 'json' }
|
||||
""", """
|
||||
export * from 'data:application/json,{"foo":3}' assert {
|
||||
type: 'json'
|
||||
};
|
||||
"""
|
||||
|
||||
eqJS """
|
||||
export { profile } from './user.json' assert { type: 'json' }
|
||||
""", """
|
||||
export {
|
||||
profile
|
||||
} from './user.json' assert {
|
||||
type: 'json'
|
||||
};
|
||||
"""
|
||||
|
||||
</script>
|
||||
<script type="text/x-coffeescript" class="test" id="importing">
|
||||
# Importing
|
||||
|
|
|
@ -9,6 +9,8 @@ import { now as currentTimestamp } from 'underscore'
|
|||
import { first, last } from 'underscore'
|
||||
import utilityBelt, { each } from 'underscore'
|
||||
|
||||
import dates from './calendar.json' assert { type: 'json' }
|
||||
|
||||
export default Math
|
||||
export square = (x) -> x * x
|
||||
export class Mathematics
|
||||
|
@ -20,3 +22,4 @@ export { Mathematics as default, sqrt as squareRoot }
|
|||
|
||||
export * from 'underscore'
|
||||
export { max, min } from 'underscore'
|
||||
export { version } from './package.json' assert { type: 'json' }
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -58,7 +58,7 @@
|
|||
// is used to make sure that newly created node class objects get correct
|
||||
// location data assigned to them. By default, the grammar will assign the
|
||||
// location data spanned by *all* of the tokens on the left (e.g. a string
|
||||
// such as `'Body TERMINATOR Line'`) to the “top-level” node returned by
|
||||
// such as `'Body TERMINATOR Line'`) to the “top-level” node returned by
|
||||
// the grammar rule (the function on the right). But for “inner” node class
|
||||
// objects created by grammar rules, they won’t get correct location data
|
||||
// assigned to them without adding `LOC`.
|
||||
|
@ -900,41 +900,89 @@
|
|||
return new ImportDeclaration(null,
|
||||
$2);
|
||||
}),
|
||||
o('IMPORT String ASSERT Object',
|
||||
function() {
|
||||
return new ImportDeclaration(null,
|
||||
$2,
|
||||
$4);
|
||||
}),
|
||||
o('IMPORT ImportDefaultSpecifier FROM String',
|
||||
function() {
|
||||
return new ImportDeclaration(new ImportClause($2,
|
||||
null),
|
||||
$4);
|
||||
}),
|
||||
o('IMPORT ImportDefaultSpecifier FROM String ASSERT Object',
|
||||
function() {
|
||||
return new ImportDeclaration(new ImportClause($2,
|
||||
null),
|
||||
$4,
|
||||
$6);
|
||||
}),
|
||||
o('IMPORT ImportNamespaceSpecifier FROM String',
|
||||
function() {
|
||||
return new ImportDeclaration(new ImportClause(null,
|
||||
$2),
|
||||
$4);
|
||||
}),
|
||||
o('IMPORT ImportNamespaceSpecifier FROM String ASSERT Object',
|
||||
function() {
|
||||
return new ImportDeclaration(new ImportClause(null,
|
||||
$2),
|
||||
$4,
|
||||
$6);
|
||||
}),
|
||||
o('IMPORT { } FROM String',
|
||||
function() {
|
||||
return new ImportDeclaration(new ImportClause(null,
|
||||
new ImportSpecifierList([])),
|
||||
$5);
|
||||
}),
|
||||
o('IMPORT { } FROM String ASSERT Object',
|
||||
function() {
|
||||
return new ImportDeclaration(new ImportClause(null,
|
||||
new ImportSpecifierList([])),
|
||||
$5,
|
||||
$7);
|
||||
}),
|
||||
o('IMPORT { ImportSpecifierList OptComma } FROM String',
|
||||
function() {
|
||||
return new ImportDeclaration(new ImportClause(null,
|
||||
new ImportSpecifierList($3)),
|
||||
$7);
|
||||
}),
|
||||
o('IMPORT { ImportSpecifierList OptComma } FROM String ASSERT Object',
|
||||
function() {
|
||||
return new ImportDeclaration(new ImportClause(null,
|
||||
new ImportSpecifierList($3)),
|
||||
$7,
|
||||
$9);
|
||||
}),
|
||||
o('IMPORT ImportDefaultSpecifier , ImportNamespaceSpecifier FROM String',
|
||||
function() {
|
||||
return new ImportDeclaration(new ImportClause($2,
|
||||
$4),
|
||||
$6);
|
||||
}),
|
||||
o('IMPORT ImportDefaultSpecifier , ImportNamespaceSpecifier FROM String ASSERT Object',
|
||||
function() {
|
||||
return new ImportDeclaration(new ImportClause($2,
|
||||
$4),
|
||||
$6,
|
||||
$8);
|
||||
}),
|
||||
o('IMPORT ImportDefaultSpecifier , { ImportSpecifierList OptComma } FROM String',
|
||||
function() {
|
||||
return new ImportDeclaration(new ImportClause($2,
|
||||
new ImportSpecifierList($5)),
|
||||
$9);
|
||||
}),
|
||||
o('IMPORT ImportDefaultSpecifier , { ImportSpecifierList OptComma } FROM String ASSERT Object',
|
||||
function() {
|
||||
return new ImportDeclaration(new ImportClause($2,
|
||||
new ImportSpecifierList($5)),
|
||||
$9,
|
||||
$11);
|
||||
})
|
||||
],
|
||||
ImportSpecifierList: [
|
||||
|
@ -1048,15 +1096,33 @@
|
|||
return new ExportAllDeclaration(new Literal($2),
|
||||
$4);
|
||||
}),
|
||||
o('EXPORT EXPORT_ALL FROM String ASSERT Object',
|
||||
function() {
|
||||
return new ExportAllDeclaration(new Literal($2),
|
||||
$4,
|
||||
$6);
|
||||
}),
|
||||
o('EXPORT { } FROM String',
|
||||
function() {
|
||||
return new ExportNamedDeclaration(new ExportSpecifierList([]),
|
||||
$5);
|
||||
}),
|
||||
o('EXPORT { } FROM String ASSERT Object',
|
||||
function() {
|
||||
return new ExportNamedDeclaration(new ExportSpecifierList([]),
|
||||
$5,
|
||||
$7);
|
||||
}),
|
||||
o('EXPORT { ExportSpecifierList OptComma } FROM String',
|
||||
function() {
|
||||
return new ExportNamedDeclaration(new ExportSpecifierList($3),
|
||||
$7);
|
||||
}),
|
||||
o('EXPORT { ExportSpecifierList OptComma } FROM String ASSERT Object',
|
||||
function() {
|
||||
return new ExportNamedDeclaration(new ExportSpecifierList($3),
|
||||
$7,
|
||||
$9);
|
||||
})
|
||||
],
|
||||
ExportSpecifierList: [
|
||||
|
|
|
@ -177,6 +177,10 @@
|
|||
this.token('DEFAULT', id);
|
||||
return id.length;
|
||||
}
|
||||
if (id === 'assert' && (this.seenImport || this.seenExport) && this.tag() === 'STRING') {
|
||||
this.token('ASSERT', id);
|
||||
return id.length;
|
||||
}
|
||||
if (id === 'do' && (regExSuper = /^(\s*super)(?!\(\))/.exec(this.chunk.slice(3)))) {
|
||||
this.token('SUPER', 'super');
|
||||
this.token('CALL_START', '(');
|
||||
|
|
|
@ -4782,10 +4782,11 @@
|
|||
//### Import and Export
|
||||
exports.ModuleDeclaration = ModuleDeclaration = (function() {
|
||||
class ModuleDeclaration extends Base {
|
||||
constructor(clause, source1) {
|
||||
constructor(clause, source1, assertions) {
|
||||
super();
|
||||
this.clause = clause;
|
||||
this.source = source1;
|
||||
this.assertions = assertions;
|
||||
this.checkSource();
|
||||
}
|
||||
|
||||
|
@ -4805,9 +4806,29 @@
|
|||
}
|
||||
}
|
||||
|
||||
astAssertions(o) {
|
||||
var ref1;
|
||||
if (((ref1 = this.assertions) != null ? ref1.properties : void 0) != null) {
|
||||
return this.assertions.properties.map((assertion) => {
|
||||
var end, left, loc, right, start;
|
||||
({start, end, loc, left, right} = assertion.ast(o));
|
||||
return {
|
||||
type: 'ImportAttribute',
|
||||
start,
|
||||
end,
|
||||
loc,
|
||||
key: left,
|
||||
value: right
|
||||
};
|
||||
});
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
ModuleDeclaration.prototype.children = ['clause', 'source'];
|
||||
ModuleDeclaration.prototype.children = ['clause', 'source', 'assertions'];
|
||||
|
||||
ModuleDeclaration.prototype.isStatement = YES;
|
||||
|
||||
|
@ -4834,6 +4855,10 @@
|
|||
code.push(this.makeCode(' from '));
|
||||
}
|
||||
code.push(this.makeCode(this.source.value));
|
||||
if (this.assertions != null) {
|
||||
code.push(this.makeCode(' assert '));
|
||||
code.push(...this.assertions.compileToFragments(o));
|
||||
}
|
||||
}
|
||||
code.push(this.makeCode(';'));
|
||||
return code;
|
||||
|
@ -4848,7 +4873,8 @@
|
|||
var ref1, ref2, ret;
|
||||
ret = {
|
||||
specifiers: (ref1 = (ref2 = this.clause) != null ? ref2.ast(o) : void 0) != null ? ref1 : [],
|
||||
source: this.source.ast(o)
|
||||
source: this.source.ast(o),
|
||||
assertions: this.astAssertions(o)
|
||||
};
|
||||
if (this.clause) {
|
||||
ret.importKind = 'value';
|
||||
|
@ -4917,6 +4943,10 @@
|
|||
}
|
||||
if (((ref1 = this.source) != null ? ref1.value : void 0) != null) {
|
||||
code.push(this.makeCode(` from ${this.source.value}`));
|
||||
if (this.assertions != null) {
|
||||
code.push(this.makeCode(' assert '));
|
||||
code.push(...this.assertions.compileToFragments(o));
|
||||
}
|
||||
}
|
||||
code.push(this.makeCode(';'));
|
||||
return code;
|
||||
|
@ -4941,6 +4971,7 @@
|
|||
var clauseAst, ref1, ref2, ret;
|
||||
ret = {
|
||||
source: (ref1 = (ref2 = this.source) != null ? ref2.ast(o) : void 0) != null ? ref1 : null,
|
||||
assertions: this.astAssertions(o),
|
||||
exportKind: 'value'
|
||||
};
|
||||
clauseAst = this.clause.ast(o);
|
||||
|
@ -4959,7 +4990,8 @@
|
|||
exports.ExportDefaultDeclaration = ExportDefaultDeclaration = class ExportDefaultDeclaration extends ExportDeclaration {
|
||||
astProperties(o) {
|
||||
return {
|
||||
declaration: this.clause.ast(o)
|
||||
declaration: this.clause.ast(o),
|
||||
assertions: this.astAssertions(o)
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -4969,6 +5001,7 @@
|
|||
astProperties(o) {
|
||||
return {
|
||||
source: this.source.ast(o),
|
||||
assertions: this.astAssertions(o),
|
||||
exportKind: 'value'
|
||||
};
|
||||
}
|
||||
|
@ -5165,8 +5198,9 @@
|
|||
}
|
||||
|
||||
checkArguments() {
|
||||
if (this.args.length !== 1) {
|
||||
return this.error('import() requires exactly one argument');
|
||||
var ref1;
|
||||
if (!((1 <= (ref1 = this.args.length) && ref1 <= 2))) {
|
||||
return this.error('import() accepts either one or two arguments');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -55,11 +55,11 @@ o = (patternString, action, options) ->
|
|||
# is used to make sure that newly created node class objects get correct
|
||||
# location data assigned to them. By default, the grammar will assign the
|
||||
# location data spanned by *all* of the tokens on the left (e.g. a string
|
||||
# such as `'Body TERMINATOR Line'`) to the “top-level” node returned by
|
||||
# such as `'Body TERMINATOR Line'`) to the “top-level” node returned by
|
||||
# the grammar rule (the function on the right). But for “inner” node class
|
||||
# objects created by grammar rules, they won’t get correct location data
|
||||
# assigned to them without adding `LOC`.
|
||||
|
||||
|
||||
# For example, consider the grammar rule `'NEW_TARGET . Property'`, which
|
||||
# is handled by a function that returns
|
||||
# `new MetaProperty LOC(1)(new IdentifierLiteral $1), LOC(3)(new Access $3)`.
|
||||
|
@ -481,13 +481,20 @@ grammar =
|
|||
]
|
||||
|
||||
Import: [
|
||||
o 'IMPORT String', -> new ImportDeclaration null, $2
|
||||
o 'IMPORT ImportDefaultSpecifier FROM String', -> new ImportDeclaration new ImportClause($2, null), $4
|
||||
o 'IMPORT ImportNamespaceSpecifier FROM String', -> new ImportDeclaration new ImportClause(null, $2), $4
|
||||
o 'IMPORT { } FROM String', -> new ImportDeclaration new ImportClause(null, new ImportSpecifierList []), $5
|
||||
o 'IMPORT { ImportSpecifierList OptComma } FROM String', -> new ImportDeclaration new ImportClause(null, new ImportSpecifierList $3), $7
|
||||
o 'IMPORT ImportDefaultSpecifier , ImportNamespaceSpecifier FROM String', -> new ImportDeclaration new ImportClause($2, $4), $6
|
||||
o 'IMPORT ImportDefaultSpecifier , { ImportSpecifierList OptComma } FROM String', -> new ImportDeclaration new ImportClause($2, new ImportSpecifierList $5), $9
|
||||
o 'IMPORT String', -> new ImportDeclaration null, $2
|
||||
o 'IMPORT String ASSERT Object', -> new ImportDeclaration null, $2, $4
|
||||
o 'IMPORT ImportDefaultSpecifier FROM String', -> new ImportDeclaration new ImportClause($2, null), $4
|
||||
o 'IMPORT ImportDefaultSpecifier FROM String ASSERT Object', -> new ImportDeclaration new ImportClause($2, null), $4, $6
|
||||
o 'IMPORT ImportNamespaceSpecifier FROM String', -> new ImportDeclaration new ImportClause(null, $2), $4
|
||||
o 'IMPORT ImportNamespaceSpecifier FROM String ASSERT Object', -> new ImportDeclaration new ImportClause(null, $2), $4, $6
|
||||
o 'IMPORT { } FROM String', -> new ImportDeclaration new ImportClause(null, new ImportSpecifierList []), $5
|
||||
o 'IMPORT { } FROM String ASSERT Object', -> new ImportDeclaration new ImportClause(null, new ImportSpecifierList []), $5, $7
|
||||
o 'IMPORT { ImportSpecifierList OptComma } FROM String', -> new ImportDeclaration new ImportClause(null, new ImportSpecifierList $3), $7
|
||||
o 'IMPORT { ImportSpecifierList OptComma } FROM String ASSERT Object', -> new ImportDeclaration new ImportClause(null, new ImportSpecifierList $3), $7, $9
|
||||
o 'IMPORT ImportDefaultSpecifier , ImportNamespaceSpecifier FROM String', -> new ImportDeclaration new ImportClause($2, $4), $6
|
||||
o 'IMPORT ImportDefaultSpecifier , ImportNamespaceSpecifier FROM String ASSERT Object', -> new ImportDeclaration new ImportClause($2, $4), $6, $8
|
||||
o 'IMPORT ImportDefaultSpecifier , { ImportSpecifierList OptComma } FROM String', -> new ImportDeclaration new ImportClause($2, new ImportSpecifierList $5), $9
|
||||
o 'IMPORT ImportDefaultSpecifier , { ImportSpecifierList OptComma } FROM String ASSERT Object', -> new ImportDeclaration new ImportClause($2, new ImportSpecifierList $5), $9, $11
|
||||
]
|
||||
|
||||
ImportSpecifierList: [
|
||||
|
@ -514,20 +521,23 @@ grammar =
|
|||
]
|
||||
|
||||
Export: [
|
||||
o 'EXPORT { }', -> new ExportNamedDeclaration new ExportSpecifierList []
|
||||
o 'EXPORT { ExportSpecifierList OptComma }', -> new ExportNamedDeclaration new ExportSpecifierList $3
|
||||
o 'EXPORT Class', -> new ExportNamedDeclaration $2
|
||||
o 'EXPORT Identifier = Expression', -> new ExportNamedDeclaration LOC(2,4)(new Assign $2, $4, null,
|
||||
o 'EXPORT { }', -> new ExportNamedDeclaration new ExportSpecifierList []
|
||||
o 'EXPORT { ExportSpecifierList OptComma }', -> new ExportNamedDeclaration new ExportSpecifierList $3
|
||||
o 'EXPORT Class', -> new ExportNamedDeclaration $2
|
||||
o 'EXPORT Identifier = Expression', -> new ExportNamedDeclaration LOC(2,4)(new Assign $2, $4, null,
|
||||
moduleDeclaration: 'export')
|
||||
o 'EXPORT Identifier = TERMINATOR Expression', -> new ExportNamedDeclaration LOC(2,5)(new Assign $2, $5, null,
|
||||
o 'EXPORT Identifier = TERMINATOR Expression', -> new ExportNamedDeclaration LOC(2,5)(new Assign $2, $5, null,
|
||||
moduleDeclaration: 'export')
|
||||
o 'EXPORT Identifier = INDENT Expression OUTDENT', -> new ExportNamedDeclaration LOC(2,6)(new Assign $2, $5, null,
|
||||
o 'EXPORT Identifier = INDENT Expression OUTDENT', -> new ExportNamedDeclaration LOC(2,6)(new Assign $2, $5, null,
|
||||
moduleDeclaration: 'export')
|
||||
o 'EXPORT DEFAULT Expression', -> new ExportDefaultDeclaration $3
|
||||
o 'EXPORT DEFAULT INDENT Object OUTDENT', -> new ExportDefaultDeclaration new Value $4
|
||||
o 'EXPORT EXPORT_ALL FROM String', -> new ExportAllDeclaration new Literal($2), $4
|
||||
o 'EXPORT { } FROM String', -> new ExportNamedDeclaration new ExportSpecifierList([]), $5
|
||||
o 'EXPORT { ExportSpecifierList OptComma } FROM String', -> new ExportNamedDeclaration new ExportSpecifierList($3), $7
|
||||
o 'EXPORT DEFAULT Expression', -> new ExportDefaultDeclaration $3
|
||||
o 'EXPORT DEFAULT INDENT Object OUTDENT', -> new ExportDefaultDeclaration new Value $4
|
||||
o 'EXPORT EXPORT_ALL FROM String', -> new ExportAllDeclaration new Literal($2), $4
|
||||
o 'EXPORT EXPORT_ALL FROM String ASSERT Object', -> new ExportAllDeclaration new Literal($2), $4, $6
|
||||
o 'EXPORT { } FROM String', -> new ExportNamedDeclaration new ExportSpecifierList([]), $5
|
||||
o 'EXPORT { } FROM String ASSERT Object', -> new ExportNamedDeclaration new ExportSpecifierList([]), $5, $7
|
||||
o 'EXPORT { ExportSpecifierList OptComma } FROM String', -> new ExportNamedDeclaration new ExportSpecifierList($3), $7
|
||||
o 'EXPORT { ExportSpecifierList OptComma } FROM String ASSERT Object', -> new ExportNamedDeclaration new ExportSpecifierList($3), $7, $9
|
||||
]
|
||||
|
||||
ExportSpecifierList: [
|
||||
|
|
|
@ -158,6 +158,9 @@ exports.Lexer = class Lexer
|
|||
if id is 'default' and @seenExport and @tag() in ['EXPORT', 'AS']
|
||||
@token 'DEFAULT', id
|
||||
return id.length
|
||||
if id is 'assert' and (@seenImport or @seenExport) and @tag() is 'STRING'
|
||||
@token 'ASSERT', id
|
||||
return id.length
|
||||
if id is 'do' and regExSuper = /^(\s*super)(?!\(\))/.exec @chunk[3...]
|
||||
@token 'SUPER', 'super'
|
||||
@token 'CALL_START', '('
|
||||
|
|
|
@ -3207,11 +3207,11 @@ exports.ClassPrototypeProperty = class ClassPrototypeProperty extends Base
|
|||
#### Import and Export
|
||||
|
||||
exports.ModuleDeclaration = class ModuleDeclaration extends Base
|
||||
constructor: (@clause, @source) ->
|
||||
constructor: (@clause, @source, @assertions) ->
|
||||
super()
|
||||
@checkSource()
|
||||
|
||||
children: ['clause', 'source']
|
||||
children: ['clause', 'source', 'assertions']
|
||||
|
||||
isStatement: YES
|
||||
jumps: THIS
|
||||
|
@ -3229,6 +3229,14 @@ exports.ModuleDeclaration = class ModuleDeclaration extends Base
|
|||
if o.indent.length isnt 0
|
||||
@error "#{moduleDeclarationType} statements must be at top-level scope"
|
||||
|
||||
astAssertions: (o) ->
|
||||
if @assertions?.properties?
|
||||
@assertions.properties.map (assertion) =>
|
||||
{ start, end, loc, left, right } = assertion.ast(o)
|
||||
{ type: 'ImportAttribute', start, end, loc, key: left, value: right }
|
||||
else
|
||||
[]
|
||||
|
||||
exports.ImportDeclaration = class ImportDeclaration extends ModuleDeclaration
|
||||
compileNode: (o) ->
|
||||
@checkScope o, 'import'
|
||||
|
@ -3241,6 +3249,9 @@ exports.ImportDeclaration = class ImportDeclaration extends ModuleDeclaration
|
|||
if @source?.value?
|
||||
code.push @makeCode ' from ' unless @clause is null
|
||||
code.push @makeCode @source.value
|
||||
if @assertions?
|
||||
code.push @makeCode ' assert '
|
||||
code.push @assertions.compileToFragments(o)...
|
||||
|
||||
code.push @makeCode ';'
|
||||
code
|
||||
|
@ -3253,6 +3264,7 @@ exports.ImportDeclaration = class ImportDeclaration extends ModuleDeclaration
|
|||
ret =
|
||||
specifiers: @clause?.ast(o) ? []
|
||||
source: @source.ast o
|
||||
assertions: @astAssertions(o)
|
||||
ret.importKind = 'value' if @clause
|
||||
ret
|
||||
|
||||
|
@ -3301,7 +3313,12 @@ exports.ExportDeclaration = class ExportDeclaration extends ModuleDeclaration
|
|||
else
|
||||
code = code.concat @clause.compileNode o
|
||||
|
||||
code.push @makeCode " from #{@source.value}" if @source?.value?
|
||||
if @source?.value?
|
||||
code.push @makeCode " from #{@source.value}"
|
||||
if @assertions?
|
||||
code.push @makeCode ' assert '
|
||||
code.push @assertions.compileToFragments(o)...
|
||||
|
||||
code.push @makeCode ';'
|
||||
code
|
||||
|
||||
|
@ -3318,6 +3335,7 @@ exports.ExportNamedDeclaration = class ExportNamedDeclaration extends ExportDecl
|
|||
astProperties: (o) ->
|
||||
ret =
|
||||
source: @source?.ast(o) ? null
|
||||
assertions: @astAssertions(o)
|
||||
exportKind: 'value'
|
||||
clauseAst = @clause.ast o
|
||||
if @clause instanceof ExportSpecifierList
|
||||
|
@ -3332,11 +3350,13 @@ exports.ExportDefaultDeclaration = class ExportDefaultDeclaration extends Export
|
|||
astProperties: (o) ->
|
||||
return
|
||||
declaration: @clause.ast o
|
||||
assertions: @astAssertions(o)
|
||||
|
||||
exports.ExportAllDeclaration = class ExportAllDeclaration extends ExportDeclaration
|
||||
astProperties: (o) ->
|
||||
return
|
||||
source: @source.ast o
|
||||
assertions: @astAssertions(o)
|
||||
exportKind: 'value'
|
||||
|
||||
exports.ModuleSpecifierList = class ModuleSpecifierList extends Base
|
||||
|
@ -3447,8 +3467,8 @@ exports.DynamicImportCall = class DynamicImportCall extends Call
|
|||
super o
|
||||
|
||||
checkArguments: ->
|
||||
unless @args.length is 1
|
||||
@error 'import() requires exactly one argument'
|
||||
unless 1 <= @args.length <= 2
|
||||
@error 'import() accepts either one or two arguments'
|
||||
|
||||
astNode: (o) ->
|
||||
@checkArguments()
|
||||
|
|
|
@ -1979,6 +1979,31 @@ test "AST as expected for ModuleDeclaration node", ->
|
|||
type: 'StringLiteral'
|
||||
value: '.'
|
||||
|
||||
testStatement 'import X from "." assert { type: "json" }',
|
||||
type: 'ImportDeclaration'
|
||||
specifiers: [
|
||||
type: 'ImportDefaultSpecifier'
|
||||
local:
|
||||
type: 'Identifier'
|
||||
name: 'X'
|
||||
declaration: no
|
||||
]
|
||||
importKind: 'value'
|
||||
source:
|
||||
type: 'StringLiteral'
|
||||
value: '.'
|
||||
assertions: [
|
||||
type: 'ImportAttribute'
|
||||
key:
|
||||
type: 'Identifier'
|
||||
name: 'type'
|
||||
value:
|
||||
type: 'StringLiteral'
|
||||
value: 'json'
|
||||
extra:
|
||||
raw: '"json"'
|
||||
]
|
||||
|
||||
test "AST as expected for ImportDeclaration node", ->
|
||||
testStatement 'import React, {Component} from "react"',
|
||||
type: 'ImportDeclaration'
|
||||
|
@ -2130,6 +2155,26 @@ test "AST as expected for ExportAllDeclaration node", ->
|
|||
raw: '"module-name"'
|
||||
exportKind: 'value'
|
||||
|
||||
testStatement 'export * from "module-name" assert { type: "json" }',
|
||||
type: 'ExportAllDeclaration'
|
||||
source:
|
||||
type: 'StringLiteral'
|
||||
value: 'module-name'
|
||||
extra:
|
||||
raw: '"module-name"'
|
||||
assertions: [
|
||||
type: 'ImportAttribute'
|
||||
key:
|
||||
type: 'Identifier'
|
||||
name: 'type'
|
||||
value:
|
||||
type: 'StringLiteral'
|
||||
value: 'json'
|
||||
extra:
|
||||
raw: '"json"'
|
||||
]
|
||||
exportKind: 'value'
|
||||
|
||||
test "AST as expected for ExportSpecifierList node", ->
|
||||
testStatement 'export {a, b, c}',
|
||||
type: 'ExportNamedDeclaration'
|
||||
|
|
|
@ -1979,21 +1979,21 @@ test "`new.target` cannot be assigned", ->
|
|||
^
|
||||
'''
|
||||
|
||||
test "#4834: dynamic import requires exactly one argument", ->
|
||||
test "#4834: dynamic import accepts either one or two arguments", ->
|
||||
assertErrorFormat '''
|
||||
import()
|
||||
''', '''
|
||||
[stdin]:1:1: error: import() requires exactly one argument
|
||||
[stdin]:1:1: error: import() accepts either one or two arguments
|
||||
import()
|
||||
^^^^^^^^
|
||||
'''
|
||||
|
||||
assertErrorFormat '''
|
||||
import('x', {})
|
||||
import('x', {}, 3)
|
||||
''', '''
|
||||
[stdin]:1:1: error: import() requires exactly one argument
|
||||
import('x', {})
|
||||
^^^^^^^^^^^^^^^
|
||||
[stdin]:1:1: error: import() accepts either one or two arguments
|
||||
import('x', {}, 3)
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
'''
|
||||
|
||||
test "#4834: dynamic import requires explicit call parentheses", ->
|
||||
|
|
88
test/import_assertions.coffee
Normal file
88
test/import_assertions.coffee
Normal file
|
@ -0,0 +1,88 @@
|
|||
# This file is running in CommonJS (in Node) or as a classic Script (in the browser tests) so it can use import() within an async function, but not at the top level; and we can’t use static import.
|
||||
test "dynamic import assertion", ->
|
||||
{ default: secret } = await import('data:application/json,{"ofLife":42}', { assert: { type: 'json' } })
|
||||
eq secret.ofLife, 42
|
||||
|
||||
test "assert keyword", ->
|
||||
assert = 1
|
||||
|
||||
{ default: assert } = await import('data:application/json,{"thatIAm":42}', { assert: { type: 'json' } })
|
||||
eq assert.thatIAm, 42
|
||||
|
||||
eqJS """
|
||||
import assert from 'regression-test'
|
||||
""", """
|
||||
import assert from 'regression-test';
|
||||
"""
|
||||
|
||||
|
||||
test "static import assertion", ->
|
||||
eqJS """
|
||||
import 'data:application/json,{"foo":3}' assert { type: 'json' }
|
||||
""", """
|
||||
import 'data:application/json,{"foo":3}' assert {
|
||||
type: 'json'
|
||||
};
|
||||
"""
|
||||
|
||||
eqJS """
|
||||
import secret from 'data:application/json,{"ofLife":42}' assert { type: 'json' }
|
||||
""", """
|
||||
import secret from 'data:application/json,{"ofLife":42}' assert {
|
||||
type: 'json'
|
||||
};
|
||||
"""
|
||||
|
||||
eqJS """
|
||||
import * as secret from 'data:application/json,{"ofLife":42}' assert { type: 'json' }
|
||||
""", """
|
||||
import * as secret from 'data:application/json,{"ofLife":42}' assert {
|
||||
type: 'json'
|
||||
};
|
||||
"""
|
||||
|
||||
# The only file types for which import assertions are currently supported are JSON (Node and browsers) and CSS (browsers), neither of which support named exports; however there’s nothing in the JavaScript grammar preventing a future supported file type from providing named exports.
|
||||
eqJS """
|
||||
import { foo } from './file.unknown' assert { type: 'unknown' }
|
||||
""", """
|
||||
import {
|
||||
foo
|
||||
} from './file.unknown' assert {
|
||||
type: 'unknown'
|
||||
};
|
||||
"""
|
||||
|
||||
eqJS """
|
||||
import file, { foo } from './file.unknown' assert { type: 'unknown' }
|
||||
""", """
|
||||
import file, {
|
||||
foo
|
||||
} from './file.unknown' assert {
|
||||
type: 'unknown'
|
||||
};
|
||||
"""
|
||||
|
||||
eqJS """
|
||||
import foo from 'bar' assert {}
|
||||
""", """
|
||||
import foo from 'bar' assert {};
|
||||
"""
|
||||
|
||||
test "static export with assertion", ->
|
||||
eqJS """
|
||||
export * from 'data:application/json,{"foo":3}' assert { type: 'json' }
|
||||
""", """
|
||||
export * from 'data:application/json,{"foo":3}' assert {
|
||||
type: 'json'
|
||||
};
|
||||
"""
|
||||
|
||||
eqJS """
|
||||
export { profile } from './user.json' assert { type: 'json' }
|
||||
""", """
|
||||
export {
|
||||
profile
|
||||
} from './user.json' assert {
|
||||
type: 'json'
|
||||
};
|
||||
"""
|
Loading…
Reference in a new issue