Skip to content

Commit bf054ae

Browse files
authored
Add support for import.meta in System modules (microsoft#32797)
1 parent 2a2866c commit bf054ae

31 files changed

+1883
-75
lines changed

src/compiler/checker.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23161,8 +23161,8 @@ namespace ts {
2316123161
}
2316223162

2316323163
function checkImportMetaProperty(node: MetaProperty) {
23164-
if (languageVersion < ScriptTarget.ESNext || moduleKind < ModuleKind.ESNext) {
23165-
error(node, Diagnostics.The_import_meta_meta_property_is_only_allowed_using_ESNext_for_the_target_and_module_compiler_options);
23164+
if (moduleKind !== ModuleKind.ESNext && moduleKind !== ModuleKind.System) {
23165+
error(node, Diagnostics.The_import_meta_meta_property_is_only_allowed_when_the_module_option_is_esnext_or_system);
2316623166
}
2316723167
const file = getSourceFileOfNode(node);
2316823168
Debug.assert(!!(file.flags & NodeFlags.PossiblyContainsImportMeta), "Containing file is missing import meta node flag.");

src/compiler/diagnosticMessages.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -979,7 +979,7 @@
979979
"category": "Error",
980980
"code": 1342
981981
},
982-
"The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.": {
982+
"The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'.": {
983983
"category": "Error",
984984
"code": 1343
985985
},

src/compiler/transformers/module/system.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@ namespace ts {
2424
context.enableSubstitution(SyntaxKind.BinaryExpression); // Substitutes assignments to exported symbols.
2525
context.enableSubstitution(SyntaxKind.PrefixUnaryExpression); // Substitutes updates to exported symbols.
2626
context.enableSubstitution(SyntaxKind.PostfixUnaryExpression); // Substitutes updates to exported symbols.
27+
context.enableSubstitution(SyntaxKind.MetaProperty); // Substitutes 'import.meta'
2728
context.enableEmitNotification(SyntaxKind.SourceFile); // Restore state when substituting nodes in a file.
2829

2930
const moduleInfoMap: ExternalModuleInfo[] = []; // The ExternalModuleInfo for each file.
3031
const deferredExports: (Statement[] | undefined)[] = []; // Exports to defer until an EndOfDeclarationMarker is found.
3132
const exportFunctionsMap: Identifier[] = []; // The export function associated with a source file.
3233
const noSubstitutionMap: boolean[][] = []; // Set of nodes for which substitution rules should be ignored for each file.
34+
const contextObjectMap: Identifier[] = []; // The context object associated with a source file.
3335

3436
let currentSourceFile: SourceFile; // The current file.
3537
let moduleInfo: ExternalModuleInfo; // ExternalModuleInfo for the current file.
@@ -75,7 +77,7 @@ namespace ts {
7577
// existing identifiers.
7678
exportFunction = createUniqueName("exports");
7779
exportFunctionsMap[id] = exportFunction;
78-
contextObject = createUniqueName("context");
80+
contextObject = contextObjectMap[id] = createUniqueName("context");
7981

8082
// Add the body of the module.
8183
const dependencyGroups = collectDependencyGroups(moduleInfo.externalImports);
@@ -1586,6 +1588,7 @@ namespace ts {
15861588
moduleInfo = moduleInfoMap[id];
15871589
exportFunction = exportFunctionsMap[id];
15881590
noSubstitution = noSubstitutionMap[id];
1591+
contextObject = contextObjectMap[id];
15891592

15901593
if (noSubstitution) {
15911594
delete noSubstitutionMap[id];
@@ -1596,6 +1599,7 @@ namespace ts {
15961599
currentSourceFile = undefined!;
15971600
moduleInfo = undefined!;
15981601
exportFunction = undefined!;
1602+
contextObject = undefined!;
15991603
noSubstitution = undefined;
16001604
}
16011605
else {
@@ -1641,6 +1645,7 @@ namespace ts {
16411645
}
16421646
return node;
16431647
}
1648+
16441649
/**
16451650
* Substitution for a ShorthandPropertyAssignment whose name that may contain an imported or exported symbol.
16461651
*
@@ -1694,6 +1699,8 @@ namespace ts {
16941699
case SyntaxKind.PrefixUnaryExpression:
16951700
case SyntaxKind.PostfixUnaryExpression:
16961701
return substituteUnaryExpression(<PrefixUnaryExpression | PostfixUnaryExpression>node);
1702+
case SyntaxKind.MetaProperty:
1703+
return substituteMetaProperty(<MetaProperty>node);
16971704
}
16981705

16991706
return node;
@@ -1830,6 +1837,13 @@ namespace ts {
18301837
return node;
18311838
}
18321839

1840+
function substituteMetaProperty(node: MetaProperty) {
1841+
if (isImportMeta(node)) {
1842+
return createPropertyAccess(contextObject, createIdentifier("meta"));
1843+
}
1844+
return node;
1845+
}
1846+
18331847
/**
18341848
* Gets the exports of a name.
18351849
*

src/compiler/types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1864,6 +1864,12 @@ namespace ts {
18641864
name: Identifier;
18651865
}
18661866

1867+
/* @internal */
1868+
export interface ImportMetaProperty extends MetaProperty {
1869+
keywordToken: SyntaxKind.ImportKeyword;
1870+
name: Identifier & { escapedText: __String & "meta" };
1871+
}
1872+
18671873
/// A JSX expression of the form <TagName attrs>...</TagName>
18681874
export interface JsxElement extends PrimaryExpression {
18691875
kind: SyntaxKind.JsxElement;

src/compiler/utilities.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -987,6 +987,12 @@ namespace ts {
987987
return n.kind === SyntaxKind.CallExpression && (<CallExpression>n).expression.kind === SyntaxKind.ImportKeyword;
988988
}
989989

990+
export function isImportMeta(n: Node): n is ImportMetaProperty {
991+
return isMetaProperty(n)
992+
&& n.keywordToken === SyntaxKind.ImportKeyword
993+
&& n.name.escapedText === "meta";
994+
}
995+
990996
export function isLiteralImportTypeNode(n: Node): n is LiteralImportTypeNode {
991997
return isImportTypeNode(n) && isLiteralTypeNode(n.argument) && isStringLiteral(n.argument.literal);
992998
}
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
11
error TS2468: Cannot find global value 'Promise'.
2-
tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,32): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
2+
tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,32): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'.
33
tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,44): error TS2339: Property 'blah' does not exist on type 'ImportMeta'.
4-
tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,51): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
4+
tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,51): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'.
55
tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,63): error TS2339: Property 'blue' does not exist on type 'ImportMeta'.
6-
tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,70): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
7-
tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(2,1): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
6+
tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,70): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'.
7+
tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(2,1): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'.
88
tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(2,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access.
9-
tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(11,21): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
9+
tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(11,21): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'.
1010
tests/cases/conformance/es2019/importMeta/example.ts(2,2): error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option.
11-
tests/cases/conformance/es2019/importMeta/example.ts(3,59): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
11+
tests/cases/conformance/es2019/importMeta/example.ts(3,59): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'.
1212
tests/cases/conformance/es2019/importMeta/example.ts(3,71): error TS2339: Property 'url' does not exist on type 'ImportMeta'.
13-
tests/cases/conformance/es2019/importMeta/example.ts(6,16): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
13+
tests/cases/conformance/es2019/importMeta/example.ts(6,16): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'.
1414
tests/cases/conformance/es2019/importMeta/example.ts(6,28): error TS2339: Property 'scriptElement' does not exist on type 'ImportMeta'.
15-
tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(1,16): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
16-
tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(2,16): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
15+
tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(1,16): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'.
16+
tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(2,16): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'.
1717
tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(2,23): error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'?
18-
tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(3,16): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
18+
tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(3,16): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'.
1919
tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(3,23): error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'?
20-
tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(1,15): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
21-
tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(2,15): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
20+
tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(1,15): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'.
21+
tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(2,15): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'.
2222
tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(2,22): error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'?
23-
tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,15): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
23+
tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,15): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'.
2424
tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,22): error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'?
2525

2626

@@ -32,14 +32,14 @@ tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,22): error TS
3232
!!! error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option.
3333
const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString());
3434
~~~~~~~~~~~
35-
!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
35+
!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'.
3636
~~~
3737
!!! error TS2339: Property 'url' does not exist on type 'ImportMeta'.
3838
const blob = await response.blob();
3939

4040
const size = import.meta.scriptElement.dataset.size || 300;
4141
~~~~~~~~~~~
42-
!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
42+
!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'.
4343
~~~~~~~~~~~~~
4444
!!! error TS2339: Property 'scriptElement' does not exist on type 'ImportMeta'.
4545

@@ -53,48 +53,48 @@ tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,22): error TS
5353
==== tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts (5 errors) ====
5454
export let x = import.meta;
5555
~~~~~~~~~~~
56-
!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
56+
!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'.
5757
export let y = import.metal;
5858
~~~~~~~~~~~~
59-
!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
59+
!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'.
6060
~~~~~
6161
!!! error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'?
6262
export let z = import.import.import.malkovich;
6363
~~~~~~~~~~~~~
64-
!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
64+
!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'.
6565
~~~~~~
6666
!!! error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'?
6767

6868
==== tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts (5 errors) ====
6969
let globalA = import.meta;
7070
~~~~~~~~~~~
71-
!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
71+
!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'.
7272
let globalB = import.metal;
7373
~~~~~~~~~~~~
74-
!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
74+
!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'.
7575
~~~~~
7676
!!! error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'?
7777
let globalC = import.import.import.malkovich;
7878
~~~~~~~~~~~~~
79-
!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
79+
!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'.
8080
~~~~~~
8181
!!! error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'?
8282

8383
==== tests/cases/conformance/es2019/importMeta/assignmentTargets.ts (8 errors) ====
8484
export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta;
8585
~~~~~~~~~~~
86-
!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
86+
!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'.
8787
~~~~
8888
!!! error TS2339: Property 'blah' does not exist on type 'ImportMeta'.
8989
~~~~~~~~~~~
90-
!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
90+
!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'.
9191
~~~~
9292
!!! error TS2339: Property 'blue' does not exist on type 'ImportMeta'.
9393
~~~~~~~~~~~
94-
!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
94+
!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'.
9595
import.meta = foo;
9696
~~~~~~~~~~~
97-
!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
97+
!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'.
9898
~~~~~~~~~~~
9999
!!! error TS2364: The left-hand side of an assignment expression must be a variable or a property access.
100100

@@ -107,4 +107,4 @@ tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,22): error TS
107107

108108
const { a, b, c } = import.meta.wellKnownProperty;
109109
~~~~~~~~~~~
110-
!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
110+
!!! error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'.

tests/baselines/reference/importMetaES5.js renamed to tests/baselines/reference/importMeta(module=commonjs,target=es5).js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//// [tests/cases/conformance/es2019/importMeta/importMetaES5.ts] ////
1+
//// [tests/cases/conformance/es2019/importMeta/importMeta.ts] ////
22

33
//// [example.ts]
44
// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example

0 commit comments

Comments
 (0)