Skip to content

Commit

Permalink
Update AST to unify type with other modifiers
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolo-ribaudo committed Dec 19, 2024
1 parent de82ce7 commit 741b566
Show file tree
Hide file tree
Showing 27 changed files with 98 additions and 110 deletions.
21 changes: 13 additions & 8 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,6 @@ import {
ImportDeclaration,
ImportEqualsDeclaration,
ImportOrExportSpecifier,
ImportPhase,
ImportSpecifier,
ImportTypeNode,
IndexedAccessType,
Expand Down Expand Up @@ -9852,14 +9851,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
factory.createImportDeclaration(
/*modifiers*/ undefined,
factory.createImportClause(
/*isTypeOnly*/ false,
/*phaseModifier*/ undefined,
/*name*/ undefined,
factory.createNamedImports([factory.createImportSpecifier(
/*isTypeOnly*/ false,
propertyName && isIdentifier(propertyName) ? factory.createIdentifier(idText(propertyName)) : undefined,
factory.createIdentifier(localName),
)]),
ImportPhase.Evaluation,
),
factory.createStringLiteral(specifier),
/*attributes*/ undefined,
Expand Down Expand Up @@ -9946,7 +9944,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
addResult(
factory.createImportDeclaration(
/*modifiers*/ undefined,
factory.createImportClause(isTypeOnly, factory.createIdentifier(localName), /*namedBindings*/ undefined, ImportPhase.Evaluation),
factory.createImportClause(
/* phaseModifier */ isTypeOnly ? SyntaxKind.TypeKeyword : undefined,
factory.createIdentifier(localName),
/*namedBindings*/ undefined
),
specifier,
attributes,
),
Expand All @@ -9961,7 +9963,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
addResult(
factory.createImportDeclaration(
/*modifiers*/ undefined,
factory.createImportClause(isTypeOnly, /*name*/ undefined, factory.createNamespaceImport(factory.createIdentifier(localName)), ImportPhase.Evaluation),
factory.createImportClause(
/* phaseModifier */ isTypeOnly ? SyntaxKind.TypeKeyword : undefined,
/*name*/ undefined,
factory.createNamespaceImport(factory.createIdentifier(localName))
),
specifier,
(node as ImportClause).parent.attributes,
),
Expand All @@ -9988,7 +9994,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
factory.createImportDeclaration(
/*modifiers*/ undefined,
factory.createImportClause(
isTypeOnly,
/* phaseModifier */ isTypeOnly ? SyntaxKind.TypeKeyword : undefined,
/*name*/ undefined,
factory.createNamedImports([
factory.createImportSpecifier(
Expand All @@ -9997,7 +10003,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
factory.createIdentifier(localName),
),
]),
ImportPhase.Evaluation,
),
specifier,
(node as ImportSpecifier).parent.parent.parent.attributes,
Expand Down Expand Up @@ -52863,7 +52868,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (node.isTypeOnly && node.namedBindings?.kind === SyntaxKind.NamedImports) {
return checkGrammarNamedImportsOrExports(node.namedBindings);
}
if (node.phase !== ImportPhase.Evaluation && moduleKind !== ModuleKind.ESNext) {
if (node.phaseModifier === SyntaxKind.DeferKeyword && moduleKind !== ModuleKind.ESNext) {
return grammarErrorOnNode(node, Diagnostics.Deferred_imports_are_only_supported_when_the_module_flag_is_set_to_esnext);
}
return false;
Expand Down
10 changes: 4 additions & 6 deletions src/compiler/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,6 @@ import {
ImportDeclaration,
ImportEqualsDeclaration,
ImportOrExportSpecifier,
ImportPhase,
ImportSpecifier,
ImportTypeNode,
IndexedAccessTypeNode,
Expand Down Expand Up @@ -3686,12 +3685,11 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
}

function emitImportClause(node: ImportClause) {
if (node.isTypeOnly) {
emitTokenWithComment(SyntaxKind.TypeKeyword, node.pos, writeKeyword, node);
if (node.phaseModifier !== undefined) {
emitTokenWithComment(node.phaseModifier, node.pos, writeKeyword, node);
writeSpace();
}
else if (node.phase !== ImportPhase.Evaluation) {
emitTokenWithComment(SyntaxKind.DeferKeyword, node.pos, writeKeyword, node);
} else if (node.isTypeOnly) {
emitTokenWithComment(SyntaxKind.TypeKeyword, node.pos, writeKeyword, node);
writeSpace();
}
emit(node.name);
Expand Down
23 changes: 14 additions & 9 deletions src/compiler/factory/nodeFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ import {
ImportClause,
ImportDeclaration,
ImportEqualsDeclaration,
ImportPhase,
ImportPhaseModifier,
ImportSpecifier,
ImportTypeAssertionContainer,
ImportTypeNode,
Expand Down Expand Up @@ -4724,28 +4724,33 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
}

// @api
function createImportClause(isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined, phase: ImportPhase): ImportClause {
function createImportClause(phaseModifier: ImportPhaseModifier | boolean | undefined, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause {
const node = createBaseDeclaration<ImportClause>(SyntaxKind.ImportClause);
node.isTypeOnly = isTypeOnly;
if (typeof phaseModifier === "boolean") {
phaseModifier = phaseModifier ? SyntaxKind.TypeKeyword : undefined;
}
node.isTypeOnly = phaseModifier === SyntaxKind.TypeKeyword;
node.phaseModifier = phaseModifier;
node.name = name;
node.namedBindings = namedBindings;
node.phase = phase;
node.transformFlags |= propagateChildFlags(node.name) |
propagateChildFlags(node.namedBindings);
if (isTypeOnly) {
if (phaseModifier === SyntaxKind.TypeKeyword) {
node.transformFlags |= TransformFlags.ContainsTypeScript;
}
node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context
return node;
}

// @api
function updateImportClause(node: ImportClause, isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined, phase: ImportPhase) {
return node.isTypeOnly !== isTypeOnly
function updateImportClause(node: ImportClause, phaseModifier: ImportPhaseModifier | boolean | undefined, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined) {
if (typeof phaseModifier === "boolean") {
phaseModifier = phaseModifier ? SyntaxKind.TypeKeyword : undefined;
}
return node.phaseModifier !== phaseModifier
|| node.name !== name
|| node.namedBindings !== namedBindings
|| node.phase !== phase
? update(createImportClause(isTypeOnly, name, namedBindings, phase), node)
? update(createImportClause(phaseModifier, name, namedBindings), node)
: node;
}

Expand Down
3 changes: 1 addition & 2 deletions src/compiler/factory/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ import {
ImportCall,
ImportDeclaration,
ImportEqualsDeclaration,
ImportPhase,
InternalEmitFlags,
isAssignmentExpression,
isAssignmentOperator,
Expand Down Expand Up @@ -731,7 +730,7 @@ export function createExternalHelpersImportDeclarationIfNeeded(nodeFactory: Node

const externalHelpersImportDeclaration = nodeFactory.createImportDeclaration(
/*modifiers*/ undefined,
nodeFactory.createImportClause(/*isTypeOnly*/ false, /*name*/ undefined, namedBindings, ImportPhase.Evaluation),
nodeFactory.createImportClause(/*phaseModifier*/ undefined, /*name*/ undefined, namedBindings),
nodeFactory.createStringLiteral(externalHelpersModuleNameText),
/*attributes*/ undefined,
);
Expand Down
27 changes: 13 additions & 14 deletions src/compiler/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ import {
ImportDeclaration,
ImportEqualsDeclaration,
ImportOrExportSpecifier,
ImportPhase,
ImportPhaseModifier,
ImportSpecifier,
ImportTypeAssertionContainer,
ImportTypeNode,
Expand Down Expand Up @@ -8368,30 +8368,29 @@ namespace Parser {
identifier = parseIdentifier();
}

let isTypeOnly = false;
let phase = ImportPhase.Evaluation;
let phaseModifier: ImportPhaseModifier | undefined = undefined;
if (
identifier?.escapedText === "type" &&
(token() !== SyntaxKind.FromKeyword || isIdentifier() && lookAhead(nextTokenIsFromKeywordOrEqualsToken)) &&
(isIdentifier() || tokenAfterImportDefinitelyProducesImportDeclaration())
) {
isTypeOnly = true;
phaseModifier = SyntaxKind.TypeKeyword;
identifier = isIdentifier() ? parseIdentifier() : undefined;
}
else if (identifier?.escapedText === "defer" && token() !== SyntaxKind.FromKeyword) {
phase = ImportPhase.Defer;
phaseModifier = SyntaxKind.DeferKeyword;
identifier = undefined;
if (isIdentifier()) {
parseErrorAtCurrentToken(Diagnostics.Default_imports_aren_t_allowed_for_deferred_imports);
identifier = parseIdentifier();
}
}

if (identifier && !tokenAfterImportedIdentifierDefinitelyProducesImportDeclaration() && phase !== ImportPhase.Defer) {
return parseImportEqualsDeclaration(pos, hasJSDoc, modifiers, identifier, isTypeOnly);
if (identifier && !tokenAfterImportedIdentifierDefinitelyProducesImportDeclaration() && phaseModifier !== SyntaxKind.DeferKeyword) {
return parseImportEqualsDeclaration(pos, hasJSDoc, modifiers, identifier, phaseModifier === SyntaxKind.TypeKeyword);
}

const importClause = tryParseImportClause(identifier, afterImportPos, isTypeOnly, /*skipJsDocLeadingAsterisks*/ undefined, phase);
const importClause = tryParseImportClause(identifier, afterImportPos, phaseModifier, /*skipJsDocLeadingAsterisks*/ undefined);
const moduleSpecifier = parseModuleSpecifier();
const attributes = tryParseImportAttributes();

Expand All @@ -8400,7 +8399,7 @@ namespace Parser {
return withJSDoc(finishNode(node, pos), hasJSDoc);
}

function tryParseImportClause(identifier: Identifier | undefined, pos: number, isTypeOnly: boolean, skipJsDocLeadingAsterisks = false, phase: ImportPhase) {
function tryParseImportClause(identifier: Identifier | undefined, pos: number, phaseModifier: undefined | ImportPhaseModifier, skipJsDocLeadingAsterisks = false) {
// ImportDeclaration:
// import ImportClause from ModuleSpecifier ;
// import ModuleSpecifier;
Expand All @@ -8410,7 +8409,7 @@ namespace Parser {
token() === SyntaxKind.AsteriskToken || // import *
token() === SyntaxKind.OpenBraceToken // import {
) {
importClause = parseImportClause(identifier, pos, isTypeOnly, skipJsDocLeadingAsterisks, phase);
importClause = parseImportClause(identifier, pos, phaseModifier, skipJsDocLeadingAsterisks);
parseExpected(SyntaxKind.FromKeyword);
}
return importClause;
Expand Down Expand Up @@ -8476,7 +8475,7 @@ namespace Parser {
return finished;
}

function parseImportClause(identifier: Identifier | undefined, pos: number, isTypeOnly: boolean, skipJsDocLeadingAsterisks: boolean, phase: ImportPhase) {
function parseImportClause(identifier: Identifier | undefined, pos: number, phaseModifier: undefined | ImportPhaseModifier, skipJsDocLeadingAsterisks: boolean) {
// ImportClause:
// ImportedDefaultBinding
// NameSpaceImport
Expand All @@ -8496,15 +8495,15 @@ namespace Parser {
namedBindings = parseNamespaceImport();
}
else {
if (phase === ImportPhase.Defer) {
if (phaseModifier === SyntaxKind.DeferKeyword) {
parseErrorAtCurrentToken(Diagnostics.Named_imports_aren_t_allowed_for_deferred_imports);
}
namedBindings = parseNamedImportsOrExports(SyntaxKind.NamedImports);
}
if (skipJsDocLeadingAsterisks) scanner.setSkipJsDocLeadingAsterisks(false);
}

return finishNode(factory.createImportClause(isTypeOnly, identifier, namedBindings, phase), pos);
return finishNode(factory.createImportClause(phaseModifier, identifier, namedBindings), pos);
}

function parseModuleReference() {
Expand Down Expand Up @@ -9538,7 +9537,7 @@ namespace Parser {
identifier = parseIdentifier();
}

const importClause = tryParseImportClause(identifier, afterImportTagPos, /*isTypeOnly*/ true, /*skipJsDocLeadingAsterisks*/ true, ImportPhase.Evaluation);
const importClause = tryParseImportClause(identifier, afterImportTagPos, SyntaxKind.TypeKeyword, /*skipJsDocLeadingAsterisks*/ true);
const moduleSpecifier = parseModuleSpecifier();
const attributes = tryParseImportAttributes();

Expand Down
9 changes: 3 additions & 6 deletions src/compiler/transformers/declarations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -886,10 +886,9 @@ export function transformDeclarations(context: TransformationContext): Transform
decl.modifiers,
factory.updateImportClause(
decl.importClause,
decl.importClause.isTypeOnly,
decl.importClause.phaseModifier,
visibleDefaultBinding,
/*namedBindings*/ undefined,
decl.importClause.phase,
),
rewriteModuleSpecifier(decl, decl.moduleSpecifier),
tryGetResolutionModeOverride(decl.attributes),
Expand All @@ -903,10 +902,9 @@ export function transformDeclarations(context: TransformationContext): Transform
decl.modifiers,
factory.updateImportClause(
decl.importClause,
decl.importClause.isTypeOnly,
decl.importClause.phaseModifier,
visibleDefaultBinding,
namedBindings,
decl.importClause.phase,
),
rewriteModuleSpecifier(decl, decl.moduleSpecifier),
tryGetResolutionModeOverride(decl.attributes),
Expand All @@ -920,10 +918,9 @@ export function transformDeclarations(context: TransformationContext): Transform
decl.modifiers,
factory.updateImportClause(
decl.importClause,
decl.importClause.isTypeOnly,
decl.importClause.phaseModifier,
visibleDefaultBinding,
bindingList && bindingList.length ? factory.updateNamedImports(decl.importClause.namedBindings, bindingList) : undefined,
decl.importClause.phase,
),
rewriteModuleSpecifier(decl, decl.moduleSpecifier),
tryGetResolutionModeOverride(decl.attributes),
Expand Down
3 changes: 1 addition & 2 deletions src/compiler/transformers/jsx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import {
getSemanticJsxChildren,
Identifier,
idText,
ImportPhase,
ImportSpecifier,
insertStatementAfterCustomPrologue,
isExpression,
Expand Down Expand Up @@ -173,7 +172,7 @@ export function transformJsx(context: TransformationContext): (x: SourceFile | B
for (const [importSource, importSpecifiersMap] of arrayFrom(currentFileState.utilizedImplicitRuntimeImports.entries())) {
if (isExternalModule(node)) {
// Add `import` statement
const importStatement = factory.createImportDeclaration(/*modifiers*/ undefined, factory.createImportClause(/*isTypeOnly*/ false, /*name*/ undefined, factory.createNamedImports(arrayFrom(importSpecifiersMap.values())), ImportPhase.Evaluation), factory.createStringLiteral(importSource), /*attributes*/ undefined);
const importStatement = factory.createImportDeclaration(/*modifiers*/ undefined, factory.createImportClause(/*phaseModifier*/ undefined, /*name*/ undefined, factory.createNamedImports(arrayFrom(importSpecifiersMap.values()))), factory.createStringLiteral(importSource), /*attributes*/ undefined);
setParentRecursive(importStatement, /*incremental*/ false);
statements = insertStatementAfterCustomPrologue(statements.slice(), importStatement);
}
Expand Down
7 changes: 2 additions & 5 deletions src/compiler/transformers/module/esnextAnd2015.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import {
idText,
ImportDeclaration,
ImportEqualsDeclaration,
ImportPhase,
insertStatementsAfterCustomPrologue,
isExportNamespaceAsDefaultDeclaration,
isExternalModule,
Expand Down Expand Up @@ -220,12 +219,11 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S
const importStatement = factory.createImportDeclaration(
/*modifiers*/ undefined,
factory.createImportClause(
/*isTypeOnly*/ false,
/*phaseModifier*/ undefined,
/*name*/ undefined,
factory.createNamedImports([
factory.createImportSpecifier(/*isTypeOnly*/ false, factory.createIdentifier("createRequire"), createRequireName),
]),
ImportPhase.Evaluation,
),
factory.createStringLiteral("module"),
/*attributes*/ undefined,
Expand Down Expand Up @@ -353,12 +351,11 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S
const importDecl = factory.createImportDeclaration(
/*modifiers*/ undefined,
factory.createImportClause(
/*isTypeOnly*/ false,
/*phaseModifier*/ undefined,
/*name*/ undefined,
factory.createNamespaceImport(
synthName,
),
ImportPhase.Evaluation,
),
updatedModuleSpecifier!,
node.attributes,
Expand Down
Loading

0 comments on commit 741b566

Please sign in to comment.