Skip to content

Commit bbfc1aa

Browse files
authored
Enable JS emit for noCheck and noCheck for transpileModule (#58364)
1 parent b7d8809 commit bbfc1aa

31 files changed

+528
-223
lines changed

src/compiler/checker.ts

+191-25
Large diffs are not rendered by default.

src/compiler/commandLineParser.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -778,7 +778,7 @@ const commandOptionsWithoutBuild: CommandLineOption[] = [
778778
showInSimplifiedHelpView: false,
779779
category: Diagnostics.Compiler_Diagnostics,
780780
description: Diagnostics.Disable_full_type_checking_only_critical_parse_and_emit_errors_will_be_reported,
781-
transpileOptionValue: undefined,
781+
transpileOptionValue: true,
782782
defaultValueDescription: false,
783783
affectsSemanticDiagnostics: true,
784784
affectsBuildInfo: true,

src/compiler/debug.ts

+5
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ import {
6464
ModifierFlags,
6565
Node,
6666
NodeArray,
67+
NodeCheckFlags,
6768
NodeFlags,
6869
nodeIsSynthesized,
6970
noop,
@@ -455,6 +456,10 @@ export namespace Debug {
455456
return formatEnum(flags, (ts as any).NodeFlags, /*isFlags*/ true);
456457
}
457458

459+
export function formatNodeCheckFlags(flags: NodeCheckFlags | undefined): string {
460+
return formatEnum(flags, (ts as any).NodeCheckFlags, /*isFlags*/ true);
461+
}
462+
458463
export function formatModifierFlags(flags: ModifierFlags | undefined): string {
459464
return formatEnum(flags, (ts as any).ModifierFlags, /*isFlags*/ true);
460465
}

src/compiler/emitter.ts

+16-1
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ import {
207207
isGeneratedPrivateIdentifier,
208208
isIdentifier,
209209
isImportAttributes,
210+
isImportEqualsDeclaration,
210211
isIncrementalCompilation,
211212
isInJsonFile,
212213
isJSDocLikeText,
@@ -798,6 +799,11 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
798799
emitSkipped = true;
799800
return;
800801
}
802+
803+
if (compilerOptions.noCheck) {
804+
(isSourceFile(sourceFileOrBundle) ? [sourceFileOrBundle] : filter(sourceFileOrBundle.sourceFiles, isSourceFileNotJson)).forEach(markLinkedReferences);
805+
}
806+
801807
// Transform the source files
802808
const transform = transformNodes(resolver, host, factory, compilerOptions, [sourceFileOrBundle], scriptTransformers, /*allowDtsFiles*/ false);
803809

@@ -933,6 +939,14 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
933939
forEachChild(node, collectLinkedAliases);
934940
}
935941

942+
function markLinkedReferences(file: SourceFile) {
943+
ts.forEachChildRecursively(file, n => {
944+
if (isImportEqualsDeclaration(n) && !(ts.getSyntacticModifierFlags(n) & ts.ModifierFlags.Export)) return "skip"; // These are deferred and marked in a chain when referenced
945+
if (ts.isImportDeclaration(n)) return "skip"; // likewise, these are ultimately what get marked by calls on other nodes - we want to skip them
946+
resolver.markLinkedReferences(n);
947+
});
948+
}
949+
936950
function printSourceFileOrBundle(jsFilePath: string, sourceMapFilePath: string | undefined, transform: TransformationResult<SourceFile | Bundle>, printer: Printer, mapOptions: SourceMapOptions) {
937951
const sourceFileOrBundle = transform.transformed[0];
938952
const bundle = sourceFileOrBundle.kind === SyntaxKind.Bundle ? sourceFileOrBundle : undefined;
@@ -1099,10 +1113,11 @@ export const notImplementedResolver: EmitResolver = {
10991113
isValueAliasDeclaration: notImplemented,
11001114
isReferencedAliasDeclaration: notImplemented,
11011115
isTopLevelValueImportEqualsWithEntityName: notImplemented,
1102-
getNodeCheckFlags: notImplemented,
1116+
hasNodeCheckFlag: notImplemented,
11031117
isDeclarationVisible: notImplemented,
11041118
isLateBound: (_node): _node is LateBoundDeclaration => false,
11051119
collectLinkedAliases: notImplemented,
1120+
markLinkedReferences: notImplemented,
11061121
isImplementationOfOverload: notImplemented,
11071122
requiresAddingImplicitUndefined: notImplemented,
11081123
isExpandoFunctionDeclaration: notImplemented,

src/compiler/program.ts

-3
Original file line numberDiff line numberDiff line change
@@ -4464,9 +4464,6 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
44644464
if (options.noEmit) {
44654465
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noCheck", "noEmit");
44664466
}
4467-
if (!options.emitDeclarationOnly) {
4468-
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "noCheck", "emitDeclarationOnly");
4469-
}
44704467
}
44714468

44724469
if (

src/compiler/transformers/classFields.ts

+7-8
Original file line numberDiff line numberDiff line change
@@ -1754,7 +1754,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
17541754
}
17551755
else if (isPrivateIdentifierClassElementDeclaration(member)) {
17561756
containsInstancePrivateElements = true;
1757-
if (resolver.getNodeCheckFlags(member) & NodeCheckFlags.ContainsConstructorReference) {
1757+
if (resolver.hasNodeCheckFlag(member, NodeCheckFlags.ContainsConstructorReference)) {
17581758
facts |= ClassFacts.NeedsClassConstructorReference;
17591759
}
17601760
}
@@ -1888,7 +1888,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
18881888
getClassLexicalEnvironment().classThis = node.emitNode.classThis;
18891889
}
18901890

1891-
const isClassWithConstructorReference = resolver.getNodeCheckFlags(node) & NodeCheckFlags.ContainsConstructorReference;
1891+
const isClassWithConstructorReference = resolver.hasNodeCheckFlag(node, NodeCheckFlags.ContainsConstructorReference);
18921892
const isExport = hasSyntacticModifier(node, ModifierFlags.Export);
18931893
const isDefault = hasSyntacticModifier(node, ModifierFlags.Default);
18941894
let modifiers = visitNodes(node.modifiers, modifierVisitor, isModifier);
@@ -1964,8 +1964,8 @@ export function transformClassFields(context: TransformationContext): (x: Source
19641964
// these statements after the class expression variable statement.
19651965
const isDecoratedClassDeclaration = !!(facts & ClassFacts.ClassWasDecorated);
19661966
const staticPropertiesOrClassStaticBlocks = getStaticPropertiesAndClassStaticBlock(node);
1967-
const classCheckFlags = resolver.getNodeCheckFlags(node);
1968-
const isClassWithConstructorReference = classCheckFlags & NodeCheckFlags.ContainsConstructorReference;
1967+
const isClassWithConstructorReference = resolver.hasNodeCheckFlag(node, NodeCheckFlags.ContainsConstructorReference);
1968+
const requiresBlockScopedVar = resolver.hasNodeCheckFlag(node, NodeCheckFlags.BlockScopedBindingInLoop);
19691969

19701970
let temp: Identifier | undefined;
19711971
function createClassTempVar() {
@@ -1982,7 +1982,6 @@ export function transformClassFields(context: TransformationContext): (x: Source
19821982
return getClassLexicalEnvironment().classConstructor = node.emitNode.classThis;
19831983
}
19841984

1985-
const requiresBlockScopedVar = classCheckFlags & NodeCheckFlags.BlockScopedBindingInLoop;
19861985
const temp = factory.createTempVariable(requiresBlockScopedVar ? addBlockScopedVariable : hoistVariableDeclaration, /*reservedInNestedScopes*/ true);
19871986
getClassLexicalEnvironment().classConstructor = factory.cloneNode(temp);
19881987
return temp;
@@ -2711,7 +2710,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
27112710
const alreadyTransformed = !!cacheAssignment || isAssignmentExpression(innerExpression) && isGeneratedIdentifier(innerExpression.left);
27122711
if (!alreadyTransformed && !inlinable && shouldHoist) {
27132712
const generatedName = factory.getGeneratedNameForNode(name);
2714-
if (resolver.getNodeCheckFlags(name) & NodeCheckFlags.BlockScopedBindingInLoop) {
2713+
if (resolver.hasNodeCheckFlag(name, NodeCheckFlags.BlockScopedBindingInLoop)) {
27152714
addBlockScopedVariable(generatedName);
27162715
}
27172716
else {
@@ -2959,7 +2958,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
29592958
typeof name === "string" ? factory.createUniqueName(name, GeneratedIdentifierFlags.Optimistic, prefix, suffix) :
29602959
factory.createTempVariable(/*recordTempVariable*/ undefined, /*reservedInNestedScopes*/ true, prefix, suffix);
29612960

2962-
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.BlockScopedBindingInLoop) {
2961+
if (resolver.hasNodeCheckFlag(node, NodeCheckFlags.BlockScopedBindingInLoop)) {
29632962
addBlockScopedVariable(identifier);
29642963
}
29652964
else {
@@ -3294,7 +3293,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
32943293

32953294
function trySubstituteClassAlias(node: Identifier): Expression | undefined {
32963295
if (enabledSubstitutions & ClassPropertySubstitutionFlags.ClassAliases) {
3297-
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ConstructorReference) {
3296+
if (resolver.hasNodeCheckFlag(node, NodeCheckFlags.ConstructorReference)) {
32983297
// Due to the emit for class decorators, any reference to the class from inside of the class body
32993298
// must instead be rewritten to point to a temporary variable to avoid issues with the double-bind
33003299
// behavior of class names in ES6.

src/compiler/transformers/es2015.ts

+7-8
Original file line numberDiff line numberDiff line change
@@ -2867,9 +2867,8 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
28672867
// * Why loop initializer is excluded?
28682868
// - Since we've introduced a fresh name it already will be undefined.
28692869

2870-
const flags = resolver.getNodeCheckFlags(node);
2871-
const isCapturedInFunction = flags & NodeCheckFlags.CapturedBlockScopedBinding;
2872-
const isDeclaredInLoop = flags & NodeCheckFlags.BlockScopedBindingInLoop;
2870+
const isCapturedInFunction = resolver.hasNodeCheckFlag(node, NodeCheckFlags.CapturedBlockScopedBinding);
2871+
const isDeclaredInLoop = resolver.hasNodeCheckFlag(node, NodeCheckFlags.BlockScopedBindingInLoop);
28732872
const emittedAsTopLevel = (hierarchyFacts & HierarchyFacts.TopLevel) !== 0
28742873
|| (isCapturedInFunction
28752874
&& isDeclaredInLoop
@@ -3373,7 +3372,7 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
33733372
}
33743373

33753374
function shouldConvertPartOfIterationStatement(node: Node) {
3376-
return (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ContainsCapturedBlockScopeBinding) !== 0;
3375+
return resolver.hasNodeCheckFlag(node, NodeCheckFlags.ContainsCapturedBlockScopeBinding);
33773376
}
33783377

33793378
function shouldConvertInitializerOfForStatement(node: IterationStatement): node is ForStatementWithConvertibleInitializer {
@@ -3394,7 +3393,7 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
33943393
}
33953394

33963395
function shouldConvertBodyOfIterationStatement(node: IterationStatement): boolean {
3397-
return (resolver.getNodeCheckFlags(node) & NodeCheckFlags.LoopWithCapturedBlockScopedBinding) !== 0;
3396+
return resolver.hasNodeCheckFlag(node, NodeCheckFlags.LoopWithCapturedBlockScopedBinding);
33983397
}
33993398

34003399
/**
@@ -4057,11 +4056,11 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
40574056
}
40584057
else {
40594058
loopParameters.push(factory.createParameterDeclaration(/*modifiers*/ undefined, /*dotDotDotToken*/ undefined, name));
4060-
const checkFlags = resolver.getNodeCheckFlags(decl);
4061-
if (checkFlags & NodeCheckFlags.NeedsLoopOutParameter || hasCapturedBindingsInForHead) {
4059+
const needsOutParam = resolver.hasNodeCheckFlag(decl, NodeCheckFlags.NeedsLoopOutParameter);
4060+
if (needsOutParam || hasCapturedBindingsInForHead) {
40624061
const outParamName = factory.createUniqueName("out_" + idText(name));
40634062
let flags = LoopOutParameterFlags.None;
4064-
if (checkFlags & NodeCheckFlags.NeedsLoopOutParameter) {
4063+
if (needsOutParam) {
40654064
flags |= LoopOutParameterFlags.Body;
40664065
}
40674066
if (isForStatement(container)) {

src/compiler/transformers/es2017.ts

+9-9
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,7 @@ export function transformES2017(context: TransformationContext): (x: SourceFile
659659
// This step isn't needed if we eventually transform this to ES5.
660660
const originalMethod = getOriginalNode(node, isFunctionLikeDeclaration);
661661
const emitSuperHelpers = languageVersion >= ScriptTarget.ES2015 &&
662-
resolver.getNodeCheckFlags(node) & (NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync | NodeCheckFlags.MethodWithSuperPropertyAccessInAsync) &&
662+
(resolver.hasNodeCheckFlag(node, NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync) || resolver.hasNodeCheckFlag(node, NodeCheckFlags.MethodWithSuperPropertyAccessInAsync)) &&
663663
(getFunctionFlags(originalMethod) & FunctionFlags.AsyncGenerator) !== FunctionFlags.AsyncGenerator;
664664

665665
if (emitSuperHelpers) {
@@ -675,10 +675,10 @@ export function transformES2017(context: TransformationContext): (x: SourceFile
675675

676676
if (hasSuperElementAccess) {
677677
// Emit helpers for super element access expressions (`super[x]`).
678-
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync) {
678+
if (resolver.hasNodeCheckFlag(node, NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync)) {
679679
addEmitHelper(updated, advancedAsyncSuperHelper);
680680
}
681-
else if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.MethodWithSuperPropertyAccessInAsync) {
681+
else if (resolver.hasNodeCheckFlag(node, NodeCheckFlags.MethodWithSuperPropertyAccessInAsync)) {
682682
addEmitHelper(updated, asyncSuperHelper);
683683
}
684684
}
@@ -743,7 +743,7 @@ export function transformES2017(context: TransformationContext): (x: SourceFile
743743
const promiseConstructor = languageVersion < ScriptTarget.ES2015 ? getPromiseConstructor(nodeType) : undefined;
744744
const isArrowFunction = node.kind === SyntaxKind.ArrowFunction;
745745
const savedLexicalArgumentsBinding = lexicalArgumentsBinding;
746-
const hasLexicalArguments = (resolver.getNodeCheckFlags(node) & NodeCheckFlags.CaptureArguments) !== 0;
746+
const hasLexicalArguments = resolver.hasNodeCheckFlag(node, NodeCheckFlags.CaptureArguments);
747747
const captureLexicalArguments = hasLexicalArguments && !lexicalArgumentsBinding;
748748
if (captureLexicalArguments) {
749749
lexicalArgumentsBinding = factory.createUniqueName("arguments");
@@ -816,7 +816,7 @@ export function transformES2017(context: TransformationContext): (x: SourceFile
816816

817817
// Minor optimization, emit `_super` helper to capture `super` access in an arrow.
818818
// This step isn't needed if we eventually transform this to ES5.
819-
const emitSuperHelpers = languageVersion >= ScriptTarget.ES2015 && resolver.getNodeCheckFlags(node) & (NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync | NodeCheckFlags.MethodWithSuperPropertyAccessInAsync);
819+
const emitSuperHelpers = languageVersion >= ScriptTarget.ES2015 && (resolver.hasNodeCheckFlag(node, NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync) || resolver.hasNodeCheckFlag(node, NodeCheckFlags.MethodWithSuperPropertyAccessInAsync));
820820

821821
if (emitSuperHelpers) {
822822
enableSubstitutionForAsyncMethodsWithSuper();
@@ -836,10 +836,10 @@ export function transformES2017(context: TransformationContext): (x: SourceFile
836836

837837
if (emitSuperHelpers && hasSuperElementAccess) {
838838
// Emit helpers for super element access expressions (`super[x]`).
839-
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync) {
839+
if (resolver.hasNodeCheckFlag(node, NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync)) {
840840
addEmitHelper(block, advancedAsyncSuperHelper);
841841
}
842-
else if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.MethodWithSuperPropertyAccessInAsync) {
842+
else if (resolver.hasNodeCheckFlag(node, NodeCheckFlags.MethodWithSuperPropertyAccessInAsync)) {
843843
addEmitHelper(block, asyncSuperHelper);
844844
}
845845
}
@@ -926,7 +926,7 @@ export function transformES2017(context: TransformationContext): (x: SourceFile
926926
// If we need to support substitutions for `super` in an async method,
927927
// we should track it here.
928928
if (enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper && isSuperContainer(node)) {
929-
const superContainerFlags = resolver.getNodeCheckFlags(node) & (NodeCheckFlags.MethodWithSuperPropertyAccessInAsync | NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync);
929+
const superContainerFlags = (resolver.hasNodeCheckFlag(node, NodeCheckFlags.MethodWithSuperPropertyAccessInAsync) ? NodeCheckFlags.MethodWithSuperPropertyAccessInAsync : 0) | (resolver.hasNodeCheckFlag(node, NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync) ? NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync : 0);
930930
if (superContainerFlags !== enclosingSuperContainerFlags) {
931931
const savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags;
932932
enclosingSuperContainerFlags = superContainerFlags;
@@ -1058,7 +1058,7 @@ export function transformES2017(context: TransformationContext): (x: SourceFile
10581058
export function createSuperAccessVariableStatement(factory: NodeFactory, resolver: EmitResolver, node: FunctionLikeDeclaration, names: Set<__String>) {
10591059
// Create a variable declaration with a getter/setter (if binding) definition for each name:
10601060
// const _super = Object.create(null, { x: { get: () => super.x, set: (v) => super.x = v }, ... });
1061-
const hasBinding = (resolver.getNodeCheckFlags(node) & NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync) !== 0;
1061+
const hasBinding = resolver.hasNodeCheckFlag(node, NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync);
10621062
const accessors: PropertyAssignment[] = [];
10631063
names.forEach((_, key) => {
10641064
const name = unescapeLeadingUnderscores(key);

0 commit comments

Comments
 (0)