diff --git a/packages/nx/src/plugins/js/project-graph/build-dependencies/strip-source-code.ts b/packages/nx/src/plugins/js/project-graph/build-dependencies/strip-source-code.ts new file mode 100644 index 0000000000000..02c3de6781734 --- /dev/null +++ b/packages/nx/src/plugins/js/project-graph/build-dependencies/strip-source-code.ts @@ -0,0 +1,178 @@ +import type { Scanner } from 'typescript'; + +let SyntaxKind: typeof import('typescript').SyntaxKind; + +/** + * @deprecated This is deprecated and will be removed in Nx 18. + * This was not intended to be exposed. + * Please talk to us if you need this. + */ +export function stripSourceCode(scanner: Scanner, contents: string): string { + if (!SyntaxKind) { + SyntaxKind = require('typescript').SyntaxKind; + } + + if (contents.indexOf('loadChildren') > -1) { + return contents; + } + + scanner.setText(contents); + let token = scanner.scan(); + let lastNonTriviaToken = SyntaxKind.Unknown; + const statements = []; + const templateStack = []; + let ignoringLine = false; + let braceDepth = 0; + let start = null; + while (token !== SyntaxKind.EndOfFileToken) { + const currentToken = token; + const potentialStart = scanner.getStartPos(); + switch (token) { + case SyntaxKind.MultiLineCommentTrivia: + case SyntaxKind.SingleLineCommentTrivia: { + const isMultiLineCommentTrivia = + token === SyntaxKind.MultiLineCommentTrivia; + const start = potentialStart + 2; + token = scanner.scan(); + const end = scanner.getStartPos() - (isMultiLineCommentTrivia ? 2 : 0); + const comment = contents.substring(start, end).trim(); + if (comment === 'nx-ignore-next-line') { + // reading till the end of the line + while ( + token === SyntaxKind.WhitespaceTrivia || + token === SyntaxKind.NewLineTrivia + ) { + token = scanner.scan(); + } + ignoringLine = true; + } + break; + } + + case SyntaxKind.NewLineTrivia: { + ignoringLine = false; + token = scanner.scan(); + break; + } + + case SyntaxKind.RequireKeyword: + case SyntaxKind.ImportKeyword: { + token = scanner.scan(); + if (ignoringLine) { + break; + } + while ( + token === SyntaxKind.WhitespaceTrivia || + token === SyntaxKind.NewLineTrivia + ) { + token = scanner.scan(); + } + start = potentialStart; + break; + } + + case SyntaxKind.TemplateHead: { + templateStack.push(braceDepth); + braceDepth = 0; + token = scanner.scan(); + break; + } + + case SyntaxKind.SlashToken: { + if (shouldRescanSlashToken(lastNonTriviaToken)) { + token = scanner.reScanSlashToken(); + } + token = scanner.scan(); + break; + } + + case SyntaxKind.OpenBraceToken: { + ++braceDepth; + token = scanner.scan(); + break; + } + + case SyntaxKind.CloseBraceToken: { + if (braceDepth) { + --braceDepth; + } else if (templateStack.length) { + token = scanner.reScanTemplateToken(false); + if (token === SyntaxKind.LastTemplateToken) { + braceDepth = templateStack.pop(); + } + } + token = scanner.scan(); + break; + } + + case SyntaxKind.ExportKeyword: { + token = scanner.scan(); + if (ignoringLine) { + break; + } + while ( + token === SyntaxKind.WhitespaceTrivia || + token === SyntaxKind.NewLineTrivia + ) { + token = scanner.scan(); + } + if ( + token === SyntaxKind.OpenBraceToken || + token === SyntaxKind.AsteriskToken || + token === SyntaxKind.TypeKeyword + ) { + start = potentialStart; + } + break; + } + + case SyntaxKind.StringLiteral: { + if (start !== null) { + token = scanner.scan(); + if (token === SyntaxKind.CloseParenToken) { + token = scanner.scan(); + } + const end = scanner.getStartPos(); + statements.push(contents.substring(start, end)); + start = null; + } else { + token = scanner.scan(); + } + break; + } + + default: { + token = scanner.scan(); + } + } + + if (currentToken > SyntaxKind.LastTriviaToken) { + lastNonTriviaToken = currentToken; + } + } + + return statements.join('\n'); +} + +function shouldRescanSlashToken( + lastNonTriviaToken: import('typescript').SyntaxKind +) { + switch (lastNonTriviaToken) { + case SyntaxKind.Identifier: + case SyntaxKind.StringLiteral: + case SyntaxKind.NumericLiteral: + case SyntaxKind.BigIntLiteral: + case SyntaxKind.RegularExpressionLiteral: + case SyntaxKind.ThisKeyword: + case SyntaxKind.PlusPlusToken: + case SyntaxKind.MinusMinusToken: + case SyntaxKind.CloseParenToken: + case SyntaxKind.CloseBracketToken: + case SyntaxKind.CloseBraceToken: + case SyntaxKind.TrueKeyword: + case SyntaxKind.FalseKeyword: + return false; + default: + return true; + } +} diff --git a/packages/nx/src/plugins/js/project-graph/build-dependencies/typescript-import-locator.ts b/packages/nx/src/plugins/js/project-graph/build-dependencies/typescript-import-locator.ts index e2cf0db356287..92fc063a0ed02 100644 --- a/packages/nx/src/plugins/js/project-graph/build-dependencies/typescript-import-locator.ts +++ b/packages/nx/src/plugins/js/project-graph/build-dependencies/typescript-import-locator.ts @@ -9,8 +9,7 @@ import type { import * as path from 'path'; import { DependencyType } from '../../../../config/project-graph'; import { defaultFileRead } from '../../../../project-graph/file-utils'; - -let SyntaxKind: typeof import('typescript').SyntaxKind; +import { stripSourceCode } from './strip-source-code'; let tsModule: typeof import('typescript'); @@ -174,172 +173,3 @@ export class TypeScriptImportLocator { return node.getText().slice(1, -1); } } -function shouldRescanSlashToken( - lastNonTriviaToken: import('typescript').SyntaxKind -) { - switch (lastNonTriviaToken) { - case SyntaxKind.Identifier: - case SyntaxKind.StringLiteral: - case SyntaxKind.NumericLiteral: - case SyntaxKind.BigIntLiteral: - case SyntaxKind.RegularExpressionLiteral: - case SyntaxKind.ThisKeyword: - case SyntaxKind.PlusPlusToken: - case SyntaxKind.MinusMinusToken: - case SyntaxKind.CloseParenToken: - case SyntaxKind.CloseBracketToken: - case SyntaxKind.CloseBraceToken: - case SyntaxKind.TrueKeyword: - case SyntaxKind.FalseKeyword: - return false; - default: - return true; - } -} - -export function stripSourceCode(scanner: Scanner, contents: string): string { - if (!SyntaxKind) { - SyntaxKind = require('typescript').SyntaxKind; - } - - if (contents.indexOf('loadChildren') > -1) { - return contents; - } - - scanner.setText(contents); - let token = scanner.scan(); - let lastNonTriviaToken = SyntaxKind.Unknown; - const statements = []; - const templateStack = []; - let ignoringLine = false; - let braceDepth = 0; - let start = null; - while (token !== SyntaxKind.EndOfFileToken) { - const currentToken = token; - const potentialStart = scanner.getStartPos(); - switch (token) { - case SyntaxKind.MultiLineCommentTrivia: - case SyntaxKind.SingleLineCommentTrivia: { - const isMultiLineCommentTrivia = - token === SyntaxKind.MultiLineCommentTrivia; - const start = potentialStart + 2; - token = scanner.scan(); - const end = scanner.getStartPos() - (isMultiLineCommentTrivia ? 2 : 0); - const comment = contents.substring(start, end).trim(); - if (comment === 'nx-ignore-next-line') { - // reading till the end of the line - while ( - token === SyntaxKind.WhitespaceTrivia || - token === SyntaxKind.NewLineTrivia - ) { - token = scanner.scan(); - } - ignoringLine = true; - } - break; - } - - case SyntaxKind.NewLineTrivia: { - ignoringLine = false; - token = scanner.scan(); - break; - } - - case SyntaxKind.RequireKeyword: - case SyntaxKind.ImportKeyword: { - token = scanner.scan(); - if (ignoringLine) { - break; - } - while ( - token === SyntaxKind.WhitespaceTrivia || - token === SyntaxKind.NewLineTrivia - ) { - token = scanner.scan(); - } - start = potentialStart; - break; - } - - case SyntaxKind.TemplateHead: { - templateStack.push(braceDepth); - braceDepth = 0; - token = scanner.scan(); - break; - } - - case SyntaxKind.SlashToken: { - if (shouldRescanSlashToken(lastNonTriviaToken)) { - token = scanner.reScanSlashToken(); - } - token = scanner.scan(); - break; - } - - case SyntaxKind.OpenBraceToken: { - ++braceDepth; - token = scanner.scan(); - break; - } - - case SyntaxKind.CloseBraceToken: { - if (braceDepth) { - --braceDepth; - } else if (templateStack.length) { - token = scanner.reScanTemplateToken(false); - if (token === SyntaxKind.LastTemplateToken) { - braceDepth = templateStack.pop(); - } - } - token = scanner.scan(); - break; - } - - case SyntaxKind.ExportKeyword: { - token = scanner.scan(); - if (ignoringLine) { - break; - } - while ( - token === SyntaxKind.WhitespaceTrivia || - token === SyntaxKind.NewLineTrivia - ) { - token = scanner.scan(); - } - if ( - token === SyntaxKind.OpenBraceToken || - token === SyntaxKind.AsteriskToken || - token === SyntaxKind.TypeKeyword - ) { - start = potentialStart; - } - break; - } - - case SyntaxKind.StringLiteral: { - if (start !== null) { - token = scanner.scan(); - if (token === SyntaxKind.CloseParenToken) { - token = scanner.scan(); - } - const end = scanner.getStartPos(); - statements.push(contents.substring(start, end)); - start = null; - } else { - token = scanner.scan(); - } - break; - } - - default: { - token = scanner.scan(); - } - } - - if (currentToken > SyntaxKind.LastTriviaToken) { - lastNonTriviaToken = currentToken; - } - } - - return statements.join('\n'); -}