Skip to content

Commit 6e919ad

Browse files
committed
Enable noCheck for JS emit
1 parent dc316af commit 6e919ad

28 files changed

+823
-455
lines changed

src/compiler/checker.ts

+501-259
Large diffs are not rendered by default.

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,
@@ -793,6 +794,11 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
793794
emitSkipped = true;
794795
return;
795796
}
797+
798+
if (compilerOptions.noCheck) {
799+
(isSourceFile(sourceFileOrBundle) ? [sourceFileOrBundle] : filter(sourceFileOrBundle.sourceFiles, isSourceFileNotJson)).forEach(markLinkedReferences);
800+
}
801+
796802
// Transform the source files
797803
const transform = transformNodes(resolver, host, factory, compilerOptions, [sourceFileOrBundle], scriptTransformers, /*allowDtsFiles*/ false);
798804

@@ -924,6 +930,14 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
924930
forEachChild(node, collectLinkedAliases);
925931
}
926932

933+
function markLinkedReferences(file: SourceFile) {
934+
ts.forEachChildRecursively(file, n => {
935+
if (isImportEqualsDeclaration(n) && !(ts.getSyntacticModifierFlags(n) & ts.ModifierFlags.Export)) return "skip"; // These are deferred and marked in a chain when referenced
936+
if (ts.isImportDeclaration(n)) return "skip"; // likewise, these are ultimately what get marked by calls on other nodes - we want to skip them
937+
resolver.markLinkedReferences(n);
938+
});
939+
}
940+
927941
function printSourceFileOrBundle(jsFilePath: string, sourceMapFilePath: string | undefined, transform: TransformationResult<SourceFile | Bundle>, printer: Printer, mapOptions: SourceMapOptions) {
928942
const sourceFileOrBundle = transform.transformed[0];
929943
const bundle = sourceFileOrBundle.kind === SyntaxKind.Bundle ? sourceFileOrBundle : undefined;
@@ -1090,10 +1104,11 @@ export const notImplementedResolver: EmitResolver = {
10901104
isValueAliasDeclaration: notImplemented,
10911105
isReferencedAliasDeclaration: notImplemented,
10921106
isTopLevelValueImportEqualsWithEntityName: notImplemented,
1093-
getNodeCheckFlags: notImplemented,
1107+
hasNodeCheckFlag: notImplemented,
10941108
isDeclarationVisible: notImplemented,
10951109
isLateBound: (_node): _node is LateBoundDeclaration => false,
10961110
collectLinkedAliases: notImplemented,
1111+
markLinkedReferences: notImplemented,
10971112
isImplementationOfOverload: notImplemented,
10981113
requiresAddingImplicitUndefined: notImplemented,
10991114
isExpandoFunctionDeclaration: notImplemented,

src/compiler/program.ts

-3
Original file line numberDiff line numberDiff line change
@@ -4429,9 +4429,6 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
44294429
if (options.noEmit) {
44304430
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noCheck", "noEmit");
44314431
}
4432-
if (!options.emitDeclarationOnly) {
4433-
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "noCheck", "emitDeclarationOnly");
4434-
}
44354432
}
44364433

44374434
if (

src/compiler/transformers/classFields.ts

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

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

19711970
let temp: Identifier | undefined;
19721971
function createClassTempVar() {
@@ -1983,7 +1982,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
19831982
return getClassLexicalEnvironment().classConstructor = node.emitNode.classThis;
19841983
}
19851984

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

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

32963295
function trySubstituteClassAlias(node: Identifier): Expression | undefined {
32973296
if (enabledSubstitutions & ClassPropertySubstitutionFlags.ClassAliases) {
3298-
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ConstructorReference) {
3297+
if (resolver.hasNodeCheckFlag(node, NodeCheckFlags.ConstructorReference)) {
32993298
// Due to the emit for class decorators, any reference to the class from inside of the class body
33003299
// must instead be rewritten to point to a temporary variable to avoid issues with the double-bind
33013300
// 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)