diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6938ed8d77fa3..aaaa0ed50b88c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13440,7 +13440,7 @@ namespace ts { // exists. Otherwise, it is the type of the string index signature in T, if one exists. function getContextualTypeForObjectLiteralMethod(node: MethodDeclaration): Type { Debug.assert(isObjectLiteralMethod(node)); - if (isInsideWithStatementBody(node)) { + if (node.flags & NodeFlags.InWithStatement) { // We cannot answer semantic questions within a with block, do not proceed any further return undefined; } @@ -13559,7 +13559,7 @@ namespace ts { * @returns the contextual type of an expression. */ function getContextualType(node: Expression): Type | undefined { - if (isInsideWithStatementBody(node)) { + if (node.flags & NodeFlags.InWithStatement) { // We cannot answer semantic questions within a with block, do not proceed any further return undefined; } @@ -23124,21 +23124,8 @@ namespace ts { // Language service support - function isInsideWithStatementBody(node: Node): boolean { - if (node) { - while (node.parent) { - if (node.parent.kind === SyntaxKind.WithStatement && (node.parent).statement === node) { - return true; - } - node = node.parent; - } - } - - return false; - } - function getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[] { - if (isInsideWithStatementBody(location)) { + if (location.flags & NodeFlags.InWithStatement) { // We cannot answer semantic questions within a with block, do not proceed any further return []; } @@ -23438,7 +23425,7 @@ namespace ts { return isExternalModule(node) ? getMergedSymbol(node.symbol) : undefined; } - if (isInsideWithStatementBody(node)) { + if (node.flags & NodeFlags.InWithStatement) { // We cannot answer semantic questions within a with block, do not proceed any further return undefined; } @@ -23546,7 +23533,7 @@ namespace ts { } function getTypeOfNode(node: Node): Type { - if (isInsideWithStatementBody(node)) { + if (node.flags & NodeFlags.InWithStatement) { // We cannot answer semantic questions within a with block, do not proceed any further return unknownType; } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index e2bae71e6bf7b..b27d4811ecb43 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -4724,7 +4724,7 @@ namespace ts { parseExpected(SyntaxKind.OpenParenToken); node.expression = allowInAnd(parseExpression); parseExpected(SyntaxKind.CloseParenToken); - node.statement = parseStatement(); + node.statement = doInsideOfContext(NodeFlags.InWithStatement, parseStatement); return finishNode(node); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index fb59c9eb8812c..c7030450a75dd 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -451,6 +451,7 @@ namespace ts { /* @internal */ PossiblyContainsDynamicImport = 1 << 19, JSDoc = 1 << 20, // If node was parsed inside jsdoc + InWithStatement = 1 << 21, // If any ancestor of node was the `statement` of a WithStatement (not the `expression`) BlockScoped = Let | Const, @@ -458,7 +459,7 @@ namespace ts { ReachabilityAndEmitFlags = ReachabilityCheckFlags | HasAsyncFunctions, // Parsing context flags - ContextFlags = DisallowInContext | YieldContext | DecoratorContext | AwaitContext | JavaScriptFile, + ContextFlags = DisallowInContext | YieldContext | DecoratorContext | AwaitContext | JavaScriptFile | InWithStatement, // Exclude these flags when parsing a Type TypeExcludesFlags = YieldContext | AwaitContext,