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

Support ES6 syntax for Import statements #1203

Closed
sheetalkamat opened this issue Nov 19, 2014 · 4 comments
Closed

Support ES6 syntax for Import statements #1203

sheetalkamat opened this issue Nov 19, 2014 · 4 comments
Labels
ES6 Relates to the ES6 Spec

Comments

@sheetalkamat
Copy link
Member

As per ES6 grammer

ImportDeclaration :
import ImportClause FromClause ;
import ModuleSpecifier ;

ImportClause :
ImportedDefaultBinding
NameSpaceImport
NamedImports
ImportedDefaultBinding , NameSpaceImport
ImportedDefaultBinding , NamedImports

ImportedDefaultBinding :
ImportedBinding

NameSpaceImport :
* as ImportedBinding

NamedImports :
{ }
{ ImportsList }
{ ImportsList , }

FromClause :
from ModuleSpecifier

ImportsList :
ImportSpecifier
ImportsList , ImportSpecifier

ImportSpecifier :
ImportedBinding
IdentifierName as ImportedBinding

ModuleSpecifier :
StringLiteral

ImportedBinding :
BindingIdentifier

Downlevel emit and meaning of each import syntax:

import BindingIdentifier from StringLiteral
//import _tmp = require(StringLiteral)
//BindingIdentifier = _tmp.default
import * as BindingIdentifier from StringLiteral
//import BindingIdentifier = require(“StringLiteral”)
import { } from StringLiteral
//import _tmp = require(StringLiteral)
import { ImportedBinding1, … } from StringLiteral
//import _tmp = require(StringLiteral)
//ImportedBinding1= _tmp.importedBinding1
//… 
import { IdentifierName1 as ImportedBinding1, … } from StringLiteral
//import _tmp = require(StringLiteral)
//ImportedBinding1 = _tmp. IdentifierName1
//…
import BindingIdentifier1, * as BindingIdentifier2 from StringLiteral
//import BindingIdentifier2 = require(StringLiteral)
//BindingIdentifier1 =  BindingIdentifier2.default
//…
Import BindingIdentifier1, { ImportedBinding2,  IdentifierName1 as ImportedBinding3, … } from StringLiteral
//import _tmp = require(StringLiteral)
//BindingIdentifier1 = _tmp.default
//ImportedBinding2 = _tmp. ImportedBinding1
//ImportedBinding3 = _tmp. IdentifierName1
//… 

In all cases, the import syntax when the import syntax is specified it has exactly the meaning of commented code. The import bindings will have exact same meaning as that of declaration it binds to and there will be no emit if the binding corresponds to type or uninitialized module

@sheetalkamat sheetalkamat added the ES6 Relates to the ES6 Spec label Nov 19, 2014
@rbuckton
Copy link
Member

ES6 Imported bindings are 'mutable', meaning that the module exporting the binding can update the value at any time, and any consumers of the module should have the new value.

The downlevel syntax below creates new identifiers that copy the value of the export, which would break that assumption.

A better way might be:

import { ImportedBinding1 } from StringLiteral;
console.log(ImportedBinding1);

// import _tmp = require(StringLiteral);
// console.log(_tmp.ImportedBinding1);

import { IdentifierName1 as ImportedBinding1 } from StringLiteral;
console.log(ImportedBinding1);

// import _tmp = require(StringLiteral);
// console.log(_tmp.IdentifierName1);

Keeping a reference to the imported module and always pointing to the actual export binding ensures this works as expected.

Sent from my Windows Phone


From: Sheetal Nandimailto:notifications@github.com
Sent: ý11/ý18/ý2014 5:29 PM
To: Microsoft/TypeScriptmailto:TypeScript@noreply.github.com
Subject: [TypeScript] Support ES6 syntax for Import statements (#1203)

As per ES6 grammer

ImportDeclaration :
import ImportClause FromClause ;
import ModuleSpecifier ;

ImportClause :
ImportedDefaultBinding
NameSpaceImport
NamedImports
ImportedDefaultBinding , NameSpaceImport
ImportedDefaultBinding , NamedImports

ImportedDefaultBinding :
ImportedBinding

NameSpaceImport :

  • as ImportedBinding

NamedImports :
{ }
{ ImportsList }
{ ImportsList , }

FromClause :
from ModuleSpecifier

ImportsList :
ImportSpecifier
ImportsList , ImportSpecifier

ImportSpecifier :
ImportedBinding
IdentifierName as ImportedBinding

ModuleSpecifier :
StringLiteral

ImportedBinding :
BindingIdentifier

Downlevel emit and meaning of each import syntax:

import BindingIdentifier from StringLiteral
//import _tmp = require(StringLiteral)
//BindingIdentifier = _tmp.default

import * as BindingIdentifier from StringLiteral
//import BindingIdentifier = require(“StringLiteral”)

import { } from StringLiteral
//import _tmp = require(StringLiteral)

import { ImportedBinding1, … } from StringLiteral
//import _tmp = require(StringLiteral)
//ImportedBinding1= _tmp.importedBinding1
//…

import { IdentifierName1 as ImportedBinding1, … } from StringLiteral
//import _tmp = require(StringLiteral)
//ImportedBinding1 = _tmp. IdentifierName1
//…

import BindingIdentifier1, * as BindingIdentifier2 from StringLiteral
//import BindingIdentifier2 = require(StringLiteral)
//BindingIdentifier1 = BindingIdentifier2.default
//…

Import BindingIdentifier1, { ImportedBinding2, IdentifierName1 as ImportedBinding3, … } from StringLiteral
//import _tmp = require(StringLiteral)
//BindingIdentifier1 = _tmp.default
//ImportedBinding2 = _tmp. ImportedBinding1
//ImportedBinding3 = _tmp. IdentifierName1
//…

In all cases, the import syntax when the import syntax is specified it has exactly the meaning of commented code. The import bindings will have exact same meaning as that of declaration it binds to and there will be no emit if the binding corresponds to type or uninitialized module


Reply to this email directly or view it on GitHubhttps://github.com//issues/1203.

@sheetalkamat
Copy link
Member Author

According to spec section 8.1.1.5.3 the import bindings are immutable:

8.1.1.5.3   CreateImportBinding (N, M, N2)
The concrete Environment Record method CreateImportBinding for module environment records creates a new initialized immutable indirect binding for the name N. A binding must not already exist in this environment record for N. M is a Module Record (see 15.2.1.15), and N2 is the name of a binding that exists in M’s module environment record. Access to the value of the new binding will indirectly access the bound value of value of thetarget binding.
1.  Let envRec be the module environment record for which the method was invoked.
2.  Assert: envRec does not already have a binding for N.
3.  Assert: M is a Module Record.
4.  Assert: M.[[ Environment]] has a binding for N2.
5.  Create an immutable indirect binding in envRec for N that references M and N2 as its target binding. Record that the is initialized.

@sheetalkamat
Copy link
Member Author

But in example
a.ts

export var a = 10;

b.ts

import  {a} from "a"

a should result in dynamic value of a so we would need to emit the _tmp.Idenfitier kind of bindings. Agreed.

But it should also be error to do a = someexpression

@rbuckton
Copy link
Member

Agreed. The bindings are only mutable on the export side

@mhegazy mhegazy closed this as completed Mar 17, 2015
@microsoft microsoft locked and limited conversation to collaborators Jun 18, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
ES6 Relates to the ES6 Spec
Projects
None yet
Development

No branches or pull requests

3 participants