Use NodeFlags to detect nodes in ambient contexts instead of climbing ancestors (#17831)
* Use NodeFlags to detect nodes in ambient contexts instead of climbing ancestors * Set context flags on tokens * Remove 'isDeclarationFile' parameter to 'initializeState' and move to 'parseSourceFileWorker' * Changes based on code review * Update API baselines
This commit is contained in:
parent
1321d2ae31
commit
cc2a2a79b5
|
@ -1550,7 +1550,7 @@ namespace ts {
|
|||
function setExportContextFlag(node: ModuleDeclaration | SourceFile) {
|
||||
// A declaration source file or ambient module declaration that contains no export declarations (but possibly regular
|
||||
// declarations with export modifiers) is an export context in which declarations are implicitly exported.
|
||||
if (isInAmbientContext(node) && !hasExportDeclarations(node)) {
|
||||
if (node.flags & NodeFlags.Ambient && !hasExportDeclarations(node)) {
|
||||
node.flags |= NodeFlags.ExportContext;
|
||||
}
|
||||
else {
|
||||
|
@ -1726,7 +1726,7 @@ namespace ts {
|
|||
node.originalKeywordKind >= SyntaxKind.FirstFutureReservedWord &&
|
||||
node.originalKeywordKind <= SyntaxKind.LastFutureReservedWord &&
|
||||
!isIdentifierName(node) &&
|
||||
!isInAmbientContext(node)) {
|
||||
!(node.flags & NodeFlags.Ambient)) {
|
||||
|
||||
// Report error only if there are no parse errors in file
|
||||
if (!file.parseDiagnostics.length) {
|
||||
|
@ -2481,7 +2481,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function bindParameter(node: ParameterDeclaration) {
|
||||
if (inStrictMode && !isInAmbientContext(node)) {
|
||||
if (inStrictMode && !(node.flags & NodeFlags.Ambient)) {
|
||||
// It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a
|
||||
// strict mode FunctionLikeDeclaration or FunctionExpression(13.1)
|
||||
checkStrictModeEvalOrArguments(node, node.name);
|
||||
|
@ -2503,7 +2503,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function bindFunctionDeclaration(node: FunctionDeclaration) {
|
||||
if (!file.isDeclarationFile && !isInAmbientContext(node)) {
|
||||
if (!file.isDeclarationFile && !(node.flags & NodeFlags.Ambient)) {
|
||||
if (isAsyncFunction(node)) {
|
||||
emitFlags |= NodeFlags.HasAsyncFunctions;
|
||||
}
|
||||
|
@ -2520,7 +2520,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function bindFunctionExpression(node: FunctionExpression) {
|
||||
if (!file.isDeclarationFile && !isInAmbientContext(node)) {
|
||||
if (!file.isDeclarationFile && !(node.flags & NodeFlags.Ambient)) {
|
||||
if (isAsyncFunction(node)) {
|
||||
emitFlags |= NodeFlags.HasAsyncFunctions;
|
||||
}
|
||||
|
@ -2534,7 +2534,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function bindPropertyOrMethodOrAccessor(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) {
|
||||
if (!file.isDeclarationFile && !isInAmbientContext(node) && isAsyncFunction(node)) {
|
||||
if (!file.isDeclarationFile && !(node.flags & NodeFlags.Ambient) && isAsyncFunction(node)) {
|
||||
emitFlags |= NodeFlags.HasAsyncFunctions;
|
||||
}
|
||||
|
||||
|
@ -2583,7 +2583,7 @@ namespace ts {
|
|||
// On the other side we do want to report errors on non-initialized 'lets' because of TDZ
|
||||
const reportUnreachableCode =
|
||||
!options.allowUnreachableCode &&
|
||||
!isInAmbientContext(node) &&
|
||||
!(node.flags & NodeFlags.Ambient) &&
|
||||
(
|
||||
node.kind !== SyntaxKind.VariableStatement ||
|
||||
getCombinedNodeFlags((<VariableStatement>node).declarationList) & NodeFlags.BlockScoped ||
|
||||
|
|
|
@ -691,7 +691,7 @@ namespace ts {
|
|||
else {
|
||||
// find a module that about to be augmented
|
||||
// do not validate names of augmentations that are defined in ambient context
|
||||
const moduleNotFoundError = !isInAmbientContext(moduleName.parent.parent)
|
||||
const moduleNotFoundError = !(moduleName.parent.parent.flags & NodeFlags.Ambient)
|
||||
? Diagnostics.Invalid_module_name_in_augmentation_module_0_cannot_be_found
|
||||
: undefined;
|
||||
let mainModule = resolveExternalModuleNameWorker(moduleName, moduleName, moduleNotFoundError, /*isForAugmentation*/ true);
|
||||
|
@ -796,7 +796,7 @@ namespace ts {
|
|||
if ((modulekind && (declarationFile.externalModuleIndicator || useFile.externalModuleIndicator)) ||
|
||||
(!compilerOptions.outFile && !compilerOptions.out) ||
|
||||
isInTypeQuery(usage) ||
|
||||
isInAmbientContext(declaration)) {
|
||||
declaration.flags & NodeFlags.Ambient) {
|
||||
// nodes are in different files and order cannot be determined
|
||||
return true;
|
||||
}
|
||||
|
@ -1384,7 +1384,7 @@ namespace ts {
|
|||
|
||||
Debug.assert(declaration !== undefined, "Declaration to checkResolvedBlockScopedVariable is undefined");
|
||||
|
||||
if (!isInAmbientContext(declaration) && !isBlockScopedNameDeclaredBeforeUse(declaration, errorLocation)) {
|
||||
if (!(declaration.flags & NodeFlags.Ambient) && !isBlockScopedNameDeclaredBeforeUse(declaration, errorLocation)) {
|
||||
if (result.flags & SymbolFlags.BlockScopedVariable) {
|
||||
error(errorLocation, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, declarationNameToString(getNameOfDeclaration(declaration)));
|
||||
}
|
||||
|
@ -3949,7 +3949,7 @@ namespace ts {
|
|||
const parent = getDeclarationContainer(node);
|
||||
// If the node is not exported or it is not ambient module element (except import declaration)
|
||||
if (!(getCombinedModifierFlags(node) & ModifierFlags.Export) &&
|
||||
!(node.kind !== SyntaxKind.ImportEqualsDeclaration && parent.kind !== SyntaxKind.SourceFile && isInAmbientContext(parent))) {
|
||||
!(node.kind !== SyntaxKind.ImportEqualsDeclaration && parent.kind !== SyntaxKind.SourceFile && parent.flags & NodeFlags.Ambient)) {
|
||||
return isGlobalSourceFile(parent);
|
||||
}
|
||||
// Exported members/ambient module elements (exception import declaration) are visible if parent is visible
|
||||
|
@ -4327,7 +4327,7 @@ namespace ts {
|
|||
|
||||
if ((noImplicitAny || isInJavaScriptFile(declaration)) &&
|
||||
declaration.kind === SyntaxKind.VariableDeclaration && !isBindingPattern(declaration.name) &&
|
||||
!(getCombinedModifierFlags(declaration) & ModifierFlags.Export) && !isInAmbientContext(declaration)) {
|
||||
!(getCombinedModifierFlags(declaration) & ModifierFlags.Export) && !(declaration.flags & NodeFlags.Ambient)) {
|
||||
// If --noImplicitAny is on or the declaration is in a Javascript file,
|
||||
// use control flow tracked 'any' type for non-ambient, non-exported var or let variables with no
|
||||
// initializer or a 'null' or 'undefined' initializer.
|
||||
|
@ -5200,7 +5200,7 @@ namespace ts {
|
|||
function isLiteralEnumMember(member: EnumMember) {
|
||||
const expr = member.initializer;
|
||||
if (!expr) {
|
||||
return !isInAmbientContext(member);
|
||||
return !(member.flags & NodeFlags.Ambient);
|
||||
}
|
||||
switch (expr.kind) {
|
||||
case SyntaxKind.StringLiteral:
|
||||
|
@ -12760,7 +12760,7 @@ namespace ts {
|
|||
const assumeInitialized = isParameter || isAlias || isOuterVariable ||
|
||||
type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & TypeFlags.Any) !== 0 || isInTypeQuery(node) || node.parent.kind === SyntaxKind.ExportSpecifier) ||
|
||||
node.parent.kind === SyntaxKind.NonNullExpression ||
|
||||
isInAmbientContext(declaration);
|
||||
declaration.flags & NodeFlags.Ambient;
|
||||
const initialType = assumeInitialized ? (isParameter ? removeOptionalityFromDeclaredType(type, getRootDeclaration(declaration) as VariableLikeDeclaration) : type) :
|
||||
type === autoType || type === autoArrayType ? undefinedType :
|
||||
getNullableType(type, TypeFlags.Undefined);
|
||||
|
@ -15232,7 +15232,7 @@ namespace ts {
|
|||
}
|
||||
else if (valueDeclaration.kind === SyntaxKind.ClassDeclaration &&
|
||||
node.parent.kind !== SyntaxKind.TypeReference &&
|
||||
!isInAmbientContext(valueDeclaration) &&
|
||||
!(valueDeclaration.flags & NodeFlags.Ambient) &&
|
||||
!isBlockScopedNameDeclaredBeforeUse(valueDeclaration, right)) {
|
||||
error(right, Diagnostics.Class_0_used_before_its_declaration, idText(right));
|
||||
}
|
||||
|
@ -17100,7 +17100,7 @@ namespace ts {
|
|||
return type;
|
||||
}
|
||||
|
||||
function isCommonJsRequire(node: Node) {
|
||||
function isCommonJsRequire(node: Node): boolean {
|
||||
if (!isRequireCall(node, /*checkArgumentIsStringLiteral*/ true)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -17124,7 +17124,7 @@ namespace ts {
|
|||
if (targetDeclarationKind !== SyntaxKind.Unknown) {
|
||||
const decl = getDeclarationOfKind(resolvedRequire, targetDeclarationKind);
|
||||
// function/variable declaration should be ambient
|
||||
return isInAmbientContext(decl);
|
||||
return !!(decl.flags & NodeFlags.Ambient);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -19242,7 +19242,7 @@ namespace ts {
|
|||
checkDecorators(node);
|
||||
checkSignatureDeclaration(node);
|
||||
if (node.kind === SyntaxKind.GetAccessor) {
|
||||
if (!isInAmbientContext(node) && nodeIsPresent(node.body) && (node.flags & NodeFlags.HasImplicitReturn)) {
|
||||
if (!(node.flags & NodeFlags.Ambient) && nodeIsPresent(node.body) && (node.flags & NodeFlags.HasImplicitReturn)) {
|
||||
if (!(node.flags & NodeFlags.HasExplicitReturn)) {
|
||||
error(node.name, Diagnostics.A_get_accessor_must_return_a_value);
|
||||
}
|
||||
|
@ -19425,7 +19425,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function isPrivateWithinAmbient(node: Node): boolean {
|
||||
return hasModifier(node, ModifierFlags.Private) && isInAmbientContext(node);
|
||||
return hasModifier(node, ModifierFlags.Private) && !!(node.flags & NodeFlags.Ambient);
|
||||
}
|
||||
|
||||
function getEffectiveDeclarationFlags(n: Node, flagsToCheck: ModifierFlags): ModifierFlags {
|
||||
|
@ -19436,7 +19436,7 @@ namespace ts {
|
|||
if (n.parent.kind !== SyntaxKind.InterfaceDeclaration &&
|
||||
n.parent.kind !== SyntaxKind.ClassDeclaration &&
|
||||
n.parent.kind !== SyntaxKind.ClassExpression &&
|
||||
isInAmbientContext(n)) {
|
||||
n.flags & NodeFlags.Ambient) {
|
||||
if (!(flags & ModifierFlags.Ambient)) {
|
||||
// It is nested in an ambient context, which means it is automatically exported
|
||||
flags |= ModifierFlags.Export;
|
||||
|
@ -19575,7 +19575,7 @@ namespace ts {
|
|||
let multipleConstructorImplementation = false;
|
||||
for (const current of declarations) {
|
||||
const node = <FunctionLike>current;
|
||||
const inAmbientContext = isInAmbientContext(node);
|
||||
const inAmbientContext = node.flags & NodeFlags.Ambient;
|
||||
const inAmbientContextOrInterface = node.parent.kind === SyntaxKind.InterfaceDeclaration || node.parent.kind === SyntaxKind.TypeLiteral || inAmbientContext;
|
||||
if (inAmbientContextOrInterface) {
|
||||
// check if declarations are consecutive only if they are non-ambient
|
||||
|
@ -20430,7 +20430,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function checkUnusedLocalsAndParameters(node: Node): void {
|
||||
if (node.parent.kind !== SyntaxKind.InterfaceDeclaration && noUnusedIdentifiers && !isInAmbientContext(node)) {
|
||||
if (node.parent.kind !== SyntaxKind.InterfaceDeclaration && noUnusedIdentifiers && !(node.flags & NodeFlags.Ambient)) {
|
||||
node.locals.forEach(local => {
|
||||
if (!local.isReferenced) {
|
||||
if (local.valueDeclaration && getRootDeclaration(local.valueDeclaration).kind === SyntaxKind.Parameter) {
|
||||
|
@ -20483,7 +20483,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function checkUnusedClassMembers(node: ClassDeclaration | ClassExpression): void {
|
||||
if (compilerOptions.noUnusedLocals && !isInAmbientContext(node)) {
|
||||
if (compilerOptions.noUnusedLocals && !(node.flags & NodeFlags.Ambient)) {
|
||||
if (node.members) {
|
||||
for (const member of node.members) {
|
||||
if (member.kind === SyntaxKind.MethodDeclaration || member.kind === SyntaxKind.PropertyDeclaration) {
|
||||
|
@ -20504,7 +20504,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function checkUnusedTypeParameters(node: ClassDeclaration | ClassExpression | FunctionDeclaration | MethodDeclaration | FunctionExpression | ArrowFunction | ConstructorDeclaration | SignatureDeclaration | InterfaceDeclaration | TypeAliasDeclaration) {
|
||||
if (compilerOptions.noUnusedLocals && !isInAmbientContext(node)) {
|
||||
if (compilerOptions.noUnusedLocals && !(node.flags & NodeFlags.Ambient)) {
|
||||
if (node.typeParameters) {
|
||||
// Only report errors on the last declaration for the type parameter container;
|
||||
// this ensures that all uses have been accounted for.
|
||||
|
@ -20523,7 +20523,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function checkUnusedModuleMembers(node: ModuleDeclaration | SourceFile): void {
|
||||
if (compilerOptions.noUnusedLocals && !isInAmbientContext(node)) {
|
||||
if (compilerOptions.noUnusedLocals && !(node.flags & NodeFlags.Ambient)) {
|
||||
node.locals.forEach(local => {
|
||||
if (!local.isReferenced && !local.exportSymbol) {
|
||||
for (const declaration of local.declarations) {
|
||||
|
@ -20556,7 +20556,7 @@ namespace ts {
|
|||
|
||||
function checkCollisionWithArgumentsInGeneratedCode(node: SignatureDeclaration) {
|
||||
// no rest parameters \ declaration context \ overload - no codegen impact
|
||||
if (!hasRestParameter(node) || isInAmbientContext(node) || nodeIsMissing((<FunctionLikeDeclaration>node).body)) {
|
||||
if (!hasRestParameter(node) || node.flags & NodeFlags.Ambient || nodeIsMissing((<FunctionLikeDeclaration>node).body)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -20582,7 +20582,7 @@ namespace ts {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (isInAmbientContext(node)) {
|
||||
if (node.flags & NodeFlags.Ambient) {
|
||||
// ambient context - no codegen impact
|
||||
return false;
|
||||
}
|
||||
|
@ -20647,7 +20647,7 @@ namespace ts {
|
|||
// bubble up and find containing type
|
||||
const enclosingClass = getContainingClass(node);
|
||||
// if containing type was not found or it is ambient - exit (no codegen)
|
||||
if (!enclosingClass || isInAmbientContext(enclosingClass)) {
|
||||
if (!enclosingClass || enclosingClass.flags & NodeFlags.Ambient) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -21962,7 +21962,7 @@ namespace ts {
|
|||
checkClassForDuplicateDeclarations(node);
|
||||
|
||||
// Only check for reserved static identifiers on non-ambient context.
|
||||
if (!isInAmbientContext(node)) {
|
||||
if (!(node.flags & NodeFlags.Ambient)) {
|
||||
checkClassForStaticPropertyNameConflicts(node);
|
||||
}
|
||||
|
||||
|
@ -22268,7 +22268,7 @@ namespace ts {
|
|||
}
|
||||
// In ambient enum declarations that specify no const modifier, enum member declarations that omit
|
||||
// a value are considered computed members (as opposed to having auto-incremented values).
|
||||
if (isInAmbientContext(member.parent) && !isConst(member.parent)) {
|
||||
if (member.parent.flags & NodeFlags.Ambient && !isConst(member.parent)) {
|
||||
return undefined;
|
||||
}
|
||||
// If the member declaration specifies no value, the member is considered a constant enum member.
|
||||
|
@ -22301,7 +22301,7 @@ namespace ts {
|
|||
else if (isConstEnum) {
|
||||
error(initializer, Diagnostics.In_const_enum_declarations_member_initializer_must_be_constant_expression);
|
||||
}
|
||||
else if (isInAmbientContext(member.parent)) {
|
||||
else if (member.parent.flags & NodeFlags.Ambient) {
|
||||
error(initializer, Diagnostics.In_ambient_enum_declarations_member_initializer_must_be_constant_expression);
|
||||
}
|
||||
else {
|
||||
|
@ -22414,7 +22414,7 @@ namespace ts {
|
|||
computeEnumMemberValues(node);
|
||||
|
||||
const enumIsConst = isConst(node);
|
||||
if (compilerOptions.isolatedModules && enumIsConst && isInAmbientContext(node)) {
|
||||
if (compilerOptions.isolatedModules && enumIsConst && node.flags & NodeFlags.Ambient) {
|
||||
error(node.name, Diagnostics.Ambient_const_enums_are_not_allowed_when_the_isolatedModules_flag_is_provided);
|
||||
}
|
||||
|
||||
|
@ -22466,7 +22466,7 @@ namespace ts {
|
|||
for (const declaration of declarations) {
|
||||
if ((declaration.kind === SyntaxKind.ClassDeclaration ||
|
||||
(declaration.kind === SyntaxKind.FunctionDeclaration && nodeIsPresent((<FunctionLikeDeclaration>declaration).body))) &&
|
||||
!isInAmbientContext(declaration)) {
|
||||
!(declaration.flags & NodeFlags.Ambient)) {
|
||||
return declaration;
|
||||
}
|
||||
}
|
||||
|
@ -22491,7 +22491,7 @@ namespace ts {
|
|||
if (produceDiagnostics) {
|
||||
// Grammar checking
|
||||
const isGlobalAugmentation = isGlobalScopeAugmentation(node);
|
||||
const inAmbientContext = isInAmbientContext(node);
|
||||
const inAmbientContext = node.flags & NodeFlags.Ambient;
|
||||
if (isGlobalAugmentation && !inAmbientContext) {
|
||||
error(node.name, Diagnostics.Augmentations_for_the_global_scope_should_have_declare_modifier_unless_they_appear_in_already_ambient_context);
|
||||
}
|
||||
|
@ -22710,7 +22710,7 @@ namespace ts {
|
|||
if (compilerOptions.isolatedModules
|
||||
&& node.kind === SyntaxKind.ExportSpecifier
|
||||
&& !(target.flags & SymbolFlags.Value)
|
||||
&& !isInAmbientContext(node)) {
|
||||
&& !(node.flags & NodeFlags.Ambient)) {
|
||||
error(node, Diagnostics.Cannot_re_export_a_type_when_the_isolatedModules_flag_is_provided);
|
||||
}
|
||||
}
|
||||
|
@ -22761,7 +22761,7 @@ namespace ts {
|
|||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
markExportAsReferenced(node);
|
||||
}
|
||||
if (isInternalModuleImportEqualsDeclaration(node)) {
|
||||
if (node.moduleReference.kind !== SyntaxKind.ExternalModuleReference) {
|
||||
const target = resolveAlias(getSymbolOfNode(node));
|
||||
if (target !== unknownSymbol) {
|
||||
if (target.flags & SymbolFlags.Value) {
|
||||
|
@ -22777,7 +22777,7 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (modulekind >= ModuleKind.ES2015 && !isInAmbientContext(node)) {
|
||||
if (modulekind >= ModuleKind.ES2015 && !(node.flags & NodeFlags.Ambient)) {
|
||||
// Import equals declaration is deprecated in es6 or above
|
||||
grammarErrorOnNode(node, Diagnostics.Import_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_import_d_from_mod_or_another_module_format_instead);
|
||||
}
|
||||
|
@ -22803,7 +22803,7 @@ namespace ts {
|
|||
|
||||
const inAmbientExternalModule = node.parent.kind === SyntaxKind.ModuleBlock && isAmbientModule(node.parent.parent);
|
||||
const inAmbientNamespaceDeclaration = !inAmbientExternalModule && node.parent.kind === SyntaxKind.ModuleBlock &&
|
||||
!node.moduleSpecifier && isInAmbientContext(node);
|
||||
!node.moduleSpecifier && node.flags & NodeFlags.Ambient;
|
||||
if (node.parent.kind !== SyntaxKind.SourceFile && !inAmbientExternalModule && !inAmbientNamespaceDeclaration) {
|
||||
error(node, Diagnostics.Export_declarations_are_not_permitted_in_a_namespace);
|
||||
}
|
||||
|
@ -22876,11 +22876,11 @@ namespace ts {
|
|||
|
||||
checkExternalModuleExports(container);
|
||||
|
||||
if (isInAmbientContext(node) && !isEntityNameExpression(node.expression)) {
|
||||
if ((node.flags & NodeFlags.Ambient) && !isEntityNameExpression(node.expression)) {
|
||||
grammarErrorOnNode(node.expression, Diagnostics.The_expression_of_an_export_assignment_must_be_an_identifier_or_qualified_name_in_an_ambient_context);
|
||||
}
|
||||
|
||||
if (node.isExportEquals && !isInAmbientContext(node)) {
|
||||
if (node.isExportEquals && !(node.flags & NodeFlags.Ambient)) {
|
||||
if (modulekind >= ModuleKind.ES2015) {
|
||||
// export assignment is not supported in es6 modules
|
||||
grammarErrorOnNode(node, Diagnostics.Export_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_export_default_or_another_module_format_instead);
|
||||
|
@ -24514,7 +24514,7 @@ namespace ts {
|
|||
function checkExternalEmitHelpers(location: Node, helpers: ExternalEmitHelpers) {
|
||||
if ((requestedExternalEmitHelpers & helpers) !== helpers && compilerOptions.importHelpers) {
|
||||
const sourceFile = getSourceFileOfNode(location);
|
||||
if (isEffectiveExternalModule(sourceFile, compilerOptions) && !isInAmbientContext(location)) {
|
||||
if (isEffectiveExternalModule(sourceFile, compilerOptions) && !(location.flags & NodeFlags.Ambient)) {
|
||||
const helpersModule = resolveHelpersModule(sourceFile, location);
|
||||
if (helpersModule !== unknownSymbol) {
|
||||
const uncheckedHelpers = helpers & ~requestedExternalEmitHelpers;
|
||||
|
@ -24716,7 +24716,7 @@ namespace ts {
|
|||
else if (node.kind === SyntaxKind.Parameter) {
|
||||
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_parameter, "declare");
|
||||
}
|
||||
else if (isInAmbientContext(node.parent) && node.parent.kind === SyntaxKind.ModuleBlock) {
|
||||
else if ((node.parent.flags & NodeFlags.Ambient) && node.parent.kind === SyntaxKind.ModuleBlock) {
|
||||
return grammarErrorOnNode(modifier, Diagnostics.A_declare_modifier_cannot_be_used_in_an_already_ambient_context);
|
||||
}
|
||||
flags |= ModifierFlags.Ambient;
|
||||
|
@ -24752,7 +24752,7 @@ namespace ts {
|
|||
if (flags & ModifierFlags.Async) {
|
||||
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "async");
|
||||
}
|
||||
else if (flags & ModifierFlags.Ambient || isInAmbientContext(node.parent)) {
|
||||
else if (flags & ModifierFlags.Ambient || node.parent.flags & NodeFlags.Ambient) {
|
||||
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_in_an_ambient_context, "async");
|
||||
}
|
||||
else if (node.kind === SyntaxKind.Parameter) {
|
||||
|
@ -25100,7 +25100,7 @@ namespace ts {
|
|||
node.kind === SyntaxKind.FunctionDeclaration ||
|
||||
node.kind === SyntaxKind.FunctionExpression ||
|
||||
node.kind === SyntaxKind.MethodDeclaration);
|
||||
if (isInAmbientContext(node)) {
|
||||
if (node.flags & NodeFlags.Ambient) {
|
||||
return grammarErrorOnNode(node.asteriskToken, Diagnostics.Generators_are_not_allowed_in_an_ambient_context);
|
||||
}
|
||||
if (!node.body) {
|
||||
|
@ -25287,7 +25287,7 @@ namespace ts {
|
|||
if (languageVersion < ScriptTarget.ES5) {
|
||||
return grammarErrorOnNode(accessor.name, Diagnostics.Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher);
|
||||
}
|
||||
else if (isInAmbientContext(accessor)) {
|
||||
else if (accessor.flags & NodeFlags.Ambient) {
|
||||
return grammarErrorOnNode(accessor.name, Diagnostics.An_accessor_cannot_be_declared_in_an_ambient_context);
|
||||
}
|
||||
else if (accessor.body === undefined && !hasModifier(accessor, ModifierFlags.Abstract)) {
|
||||
|
@ -25366,7 +25366,7 @@ namespace ts {
|
|||
// However, property declarations disallow computed names in general,
|
||||
// and accessors are not allowed in ambient contexts in general,
|
||||
// so this error only really matters for methods.
|
||||
if (isInAmbientContext(node)) {
|
||||
if (node.flags & NodeFlags.Ambient) {
|
||||
return checkGrammarForNonSymbolComputedProperty(node.name, Diagnostics.A_computed_property_name_in_an_ambient_context_must_directly_refer_to_a_built_in_symbol);
|
||||
}
|
||||
else if (!node.body) {
|
||||
|
@ -25461,7 +25461,7 @@ namespace ts {
|
|||
|
||||
function checkGrammarVariableDeclaration(node: VariableDeclaration) {
|
||||
if (node.parent.parent.kind !== SyntaxKind.ForInStatement && node.parent.parent.kind !== SyntaxKind.ForOfStatement) {
|
||||
if (isInAmbientContext(node)) {
|
||||
if (node.flags & NodeFlags.Ambient) {
|
||||
if (node.initializer) {
|
||||
if (isConst(node) && !node.type) {
|
||||
if (!isStringOrNumberLiteralExpression(node.initializer)) {
|
||||
|
@ -25491,7 +25491,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
if (compilerOptions.module !== ModuleKind.ES2015 && compilerOptions.module !== ModuleKind.ESNext && compilerOptions.module !== ModuleKind.System && !compilerOptions.noEmit &&
|
||||
!isInAmbientContext(node.parent.parent) && hasModifier(node.parent.parent, ModifierFlags.Export)) {
|
||||
!(node.parent.parent.flags & NodeFlags.Ambient) && hasModifier(node.parent.parent, ModifierFlags.Export)) {
|
||||
checkESModuleMarker(node.name);
|
||||
}
|
||||
|
||||
|
@ -25650,7 +25650,7 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
if (isInAmbientContext(node) && node.initializer) {
|
||||
if (node.flags & NodeFlags.Ambient && node.initializer) {
|
||||
return grammarErrorOnFirstToken(node.initializer, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts);
|
||||
}
|
||||
}
|
||||
|
@ -25693,11 +25693,11 @@ namespace ts {
|
|||
}
|
||||
|
||||
function checkGrammarSourceFile(node: SourceFile): boolean {
|
||||
return isInAmbientContext(node) && checkGrammarTopLevelElementsForRequiredDeclareModifier(node);
|
||||
return !!(node.flags & NodeFlags.Ambient) && checkGrammarTopLevelElementsForRequiredDeclareModifier(node);
|
||||
}
|
||||
|
||||
function checkGrammarStatementInAmbientContext(node: Node): boolean {
|
||||
if (isInAmbientContext(node)) {
|
||||
if (node.flags & NodeFlags.Ambient) {
|
||||
// An accessors is already reported about the ambient context
|
||||
if (isAccessor(node.parent)) {
|
||||
return getNodeLinks(node).hasReportedStatementInAmbientContext = true;
|
||||
|
|
|
@ -631,6 +631,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
export function parseIsolatedEntityName(content: string, languageVersion: ScriptTarget): EntityName {
|
||||
// Choice of `isDeclarationFile` should be arbitrary
|
||||
initializeState(content, languageVersion, /*syntaxCursor*/ undefined, ScriptKind.JS);
|
||||
// Prime the scanner.
|
||||
nextToken();
|
||||
|
@ -643,7 +644,7 @@ namespace ts {
|
|||
export function parseJsonText(fileName: string, sourceText: string): JsonSourceFile {
|
||||
initializeState(sourceText, ScriptTarget.ES2015, /*syntaxCursor*/ undefined, ScriptKind.JSON);
|
||||
// Set source file so that errors will be reported with this file name
|
||||
sourceFile = createSourceFile(fileName, ScriptTarget.ES2015, ScriptKind.JSON);
|
||||
sourceFile = createSourceFile(fileName, ScriptTarget.ES2015, ScriptKind.JSON, /*isDeclaration*/ false);
|
||||
const result = <JsonSourceFile>sourceFile;
|
||||
|
||||
// Prime the scanner.
|
||||
|
@ -685,7 +686,16 @@ namespace ts {
|
|||
identifierCount = 0;
|
||||
nodeCount = 0;
|
||||
|
||||
contextFlags = scriptKind === ScriptKind.JS || scriptKind === ScriptKind.JSX || scriptKind === ScriptKind.JSON ? NodeFlags.JavaScriptFile : NodeFlags.None;
|
||||
switch (scriptKind) {
|
||||
case ScriptKind.JS:
|
||||
case ScriptKind.JSX:
|
||||
case ScriptKind.JSON:
|
||||
contextFlags = NodeFlags.JavaScriptFile;
|
||||
break;
|
||||
default:
|
||||
contextFlags = NodeFlags.None;
|
||||
break;
|
||||
}
|
||||
parseErrorBeforeNextFinishedNode = false;
|
||||
|
||||
// Initialize and prime the scanner before parsing the source elements.
|
||||
|
@ -709,7 +719,12 @@ namespace ts {
|
|||
}
|
||||
|
||||
function parseSourceFileWorker(fileName: string, languageVersion: ScriptTarget, setParentNodes: boolean, scriptKind: ScriptKind): SourceFile {
|
||||
sourceFile = createSourceFile(fileName, languageVersion, scriptKind);
|
||||
const isDeclarationFile = isDeclarationFileName(fileName);
|
||||
if (isDeclarationFile) {
|
||||
contextFlags |= NodeFlags.Ambient;
|
||||
}
|
||||
|
||||
sourceFile = createSourceFile(fileName, languageVersion, scriptKind, isDeclarationFile);
|
||||
sourceFile.flags = contextFlags;
|
||||
|
||||
// Prime the scanner.
|
||||
|
@ -786,7 +801,7 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function createSourceFile(fileName: string, languageVersion: ScriptTarget, scriptKind: ScriptKind): SourceFile {
|
||||
function createSourceFile(fileName: string, languageVersion: ScriptTarget, scriptKind: ScriptKind, isDeclarationFile: boolean): SourceFile {
|
||||
// code from createNode is inlined here so createNode won't have to deal with special case of creating source files
|
||||
// this is quite rare comparing to other nodes and createNode should be as fast as possible
|
||||
const sourceFile = <SourceFile>new SourceFileConstructor(SyntaxKind.SourceFile, /*pos*/ 0, /* end */ sourceText.length);
|
||||
|
@ -797,7 +812,7 @@ namespace ts {
|
|||
sourceFile.languageVersion = languageVersion;
|
||||
sourceFile.fileName = normalizePath(fileName);
|
||||
sourceFile.languageVariant = getLanguageVariant(scriptKind);
|
||||
sourceFile.isDeclarationFile = fileExtensionIs(sourceFile.fileName, Extension.Dts);
|
||||
sourceFile.isDeclarationFile = isDeclarationFile;
|
||||
sourceFile.scriptKind = scriptKind;
|
||||
|
||||
return sourceFile;
|
||||
|
@ -5135,6 +5150,18 @@ namespace ts {
|
|||
const fullStart = getNodePos();
|
||||
const decorators = parseDecorators();
|
||||
const modifiers = parseModifiers();
|
||||
if (some(modifiers, m => m.kind === SyntaxKind.DeclareKeyword)) {
|
||||
for (const m of modifiers) {
|
||||
m.flags |= NodeFlags.Ambient;
|
||||
}
|
||||
return doInsideOfContext(NodeFlags.Ambient, () => parseDeclarationWorker(fullStart, decorators, modifiers));
|
||||
}
|
||||
else {
|
||||
return parseDeclarationWorker(fullStart, decorators, modifiers);
|
||||
}
|
||||
}
|
||||
|
||||
function parseDeclarationWorker(fullStart: number, decorators: NodeArray<Decorator> | undefined, modifiers: NodeArray<Modifier> | undefined): Statement {
|
||||
switch (token()) {
|
||||
case SyntaxKind.VarKeyword:
|
||||
case SyntaxKind.LetKeyword:
|
||||
|
@ -5492,8 +5519,8 @@ namespace ts {
|
|||
return false;
|
||||
}
|
||||
|
||||
function parseDecorators(): NodeArray<Decorator> {
|
||||
let list: Decorator[];
|
||||
function parseDecorators(): NodeArray<Decorator> | undefined {
|
||||
let list: Decorator[] | undefined;
|
||||
const listPos = getNodePos();
|
||||
while (true) {
|
||||
const decoratorStart = getNodePos();
|
||||
|
@ -6177,7 +6204,7 @@ namespace ts {
|
|||
export namespace JSDocParser {
|
||||
export function parseJSDocTypeExpressionForTests(content: string, start: number, length: number): { jsDocTypeExpression: JSDocTypeExpression, diagnostics: Diagnostic[] } | undefined {
|
||||
initializeState(content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS);
|
||||
sourceFile = createSourceFile("file.js", ScriptTarget.Latest, ScriptKind.JS);
|
||||
sourceFile = createSourceFile("file.js", ScriptTarget.Latest, ScriptKind.JS, /*isDeclarationFile*/ false);
|
||||
scanner.setText(content, start, length);
|
||||
currentToken = scanner.scan();
|
||||
const jsDocTypeExpression = parseJSDocTypeExpression();
|
||||
|
@ -7507,4 +7534,8 @@ namespace ts {
|
|||
Value = -1
|
||||
}
|
||||
}
|
||||
|
||||
function isDeclarationFileName(fileName: string): boolean {
|
||||
return fileExtensionIs(fileName, Extension.Dts);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -454,7 +454,8 @@ namespace ts {
|
|||
/* @internal */
|
||||
PossiblyContainsDynamicImport = 1 << 19,
|
||||
JSDoc = 1 << 20, // If node was parsed inside jsdoc
|
||||
/* @internal */ InWithStatement = 1 << 21, // If any ancestor of node was the `statement` of a WithStatement (not the `expression`)
|
||||
/* @internal */ Ambient = 1 << 21, // If node was inside an ambient context -- a declaration file, or inside something with the `declare` modifier.
|
||||
/* @internal */ InWithStatement = 1 << 22, // If any ancestor of node was the `statement` of a WithStatement (not the `expression`)
|
||||
|
||||
BlockScoped = Let | Const,
|
||||
|
||||
|
@ -462,7 +463,7 @@ namespace ts {
|
|||
ReachabilityAndEmitFlags = ReachabilityCheckFlags | HasAsyncFunctions,
|
||||
|
||||
// Parsing context flags
|
||||
ContextFlags = DisallowInContext | YieldContext | DecoratorContext | AwaitContext | JavaScriptFile | InWithStatement,
|
||||
ContextFlags = DisallowInContext | YieldContext | DecoratorContext | AwaitContext | JavaScriptFile | InWithStatement | Ambient,
|
||||
|
||||
// Exclude these flags when parsing a Type
|
||||
TypeExcludesFlags = YieldContext | AwaitContext,
|
||||
|
|
|
@ -1728,16 +1728,6 @@ namespace ts {
|
|||
return false;
|
||||
}
|
||||
|
||||
export function isInAmbientContext(node: Node): boolean {
|
||||
while (node) {
|
||||
if (hasModifier(node, ModifierFlags.Ambient) || (node.kind === SyntaxKind.SourceFile && (node as SourceFile).isDeclarationFile)) {
|
||||
return true;
|
||||
}
|
||||
node = node.parent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// True if the given identifier, string literal, or number literal is the name of a declaration node
|
||||
export function isDeclarationName(name: Node): boolean {
|
||||
switch (name.kind) {
|
||||
|
|
|
@ -591,7 +591,7 @@ module m3 { }\
|
|||
const index = 0;
|
||||
const newTextAndChange = withInsert(oldText, index, "declare ");
|
||||
|
||||
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 3);
|
||||
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
|
||||
});
|
||||
|
||||
it("Insert function above arrow function with comment", () => {
|
||||
|
@ -674,7 +674,7 @@ module m3 { }\
|
|||
const oldText = ScriptSnapshot.fromString(source);
|
||||
const newTextAndChange = withInsert(oldText, 0, "{");
|
||||
|
||||
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 9);
|
||||
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 4);
|
||||
});
|
||||
|
||||
it("Removing block around function declarations", () => {
|
||||
|
@ -683,7 +683,7 @@ module m3 { }\
|
|||
const oldText = ScriptSnapshot.fromString(source);
|
||||
const newTextAndChange = withDelete(oldText, 0, "{".length);
|
||||
|
||||
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 9);
|
||||
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 4);
|
||||
});
|
||||
|
||||
it("Moving methods from class to object literal", () => {
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace ts.BreakpointResolver {
|
|||
}
|
||||
|
||||
// Cannot set breakpoint in ambient declarations
|
||||
if (isInAmbientContext(tokenAtLocation)) {
|
||||
if (tokenAtLocation.flags & NodeFlags.Ambient) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
|
|
@ -335,7 +335,7 @@ namespace ts.refactor.extractSymbol {
|
|||
return [createDiagnosticForNode(nodeToCheck, Messages.StatementOrExpressionExpected)];
|
||||
}
|
||||
|
||||
if (isInAmbientContext(nodeToCheck)) {
|
||||
if (nodeToCheck.flags & NodeFlags.Ambient) {
|
||||
return [createDiagnosticForNode(nodeToCheck, Messages.CannotExtractAmbientBlock)];
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ namespace ts {
|
|||
kind === SyntaxKind.Identifier ? new IdentifierObject(SyntaxKind.Identifier, pos, end) :
|
||||
new TokenObject(kind, pos, end);
|
||||
node.parent = parent;
|
||||
node.flags = parent.flags & NodeFlags.ContextFlags;
|
||||
return node;
|
||||
}
|
||||
|
||||
|
|
|
@ -947,7 +947,7 @@ namespace ts {
|
|||
if (flags & ModifierFlags.Static) result.push(ScriptElementKindModifier.staticModifier);
|
||||
if (flags & ModifierFlags.Abstract) result.push(ScriptElementKindModifier.abstractModifier);
|
||||
if (flags & ModifierFlags.Export) result.push(ScriptElementKindModifier.exportedModifier);
|
||||
if (isInAmbientContext(node)) result.push(ScriptElementKindModifier.ambientModifier);
|
||||
if (node.flags & NodeFlags.Ambient) result.push(ScriptElementKindModifier.ambientModifier);
|
||||
|
||||
return result.length > 0 ? result.join(",") : ScriptElementKindModifier.none;
|
||||
}
|
||||
|
|
|
@ -411,7 +411,7 @@ declare namespace ts {
|
|||
BlockScoped = 3,
|
||||
ReachabilityCheckFlags = 384,
|
||||
ReachabilityAndEmitFlags = 1408,
|
||||
ContextFlags = 2193408,
|
||||
ContextFlags = 6387712,
|
||||
TypeExcludesFlags = 20480,
|
||||
}
|
||||
enum ModifierFlags {
|
||||
|
|
|
@ -411,7 +411,7 @@ declare namespace ts {
|
|||
BlockScoped = 3,
|
||||
ReachabilityCheckFlags = 384,
|
||||
ReachabilityAndEmitFlags = 1408,
|
||||
ContextFlags = 2193408,
|
||||
ContextFlags = 6387712,
|
||||
TypeExcludesFlags = 20480,
|
||||
}
|
||||
enum ModifierFlags {
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
tests/cases/conformance/parser/ecmascript5/ConstructorDeclarations/parserConstructorDeclaration4.ts(2,3): error TS1031: 'declare' modifier cannot appear on a class element.
|
||||
tests/cases/conformance/parser/ecmascript5/ConstructorDeclarations/parserConstructorDeclaration4.ts(2,25): error TS1183: An implementation cannot be declared in ambient contexts.
|
||||
|
||||
|
||||
==== tests/cases/conformance/parser/ecmascript5/ConstructorDeclarations/parserConstructorDeclaration4.ts (2 errors) ====
|
||||
==== tests/cases/conformance/parser/ecmascript5/ConstructorDeclarations/parserConstructorDeclaration4.ts (1 errors) ====
|
||||
class C {
|
||||
declare constructor() { }
|
||||
~~~~~~~
|
||||
!!! error TS1031: 'declare' modifier cannot appear on a class element.
|
||||
~
|
||||
!!! error TS1183: An implementation cannot be declared in ambient contexts.
|
||||
}
|
|
@ -1,9 +1,12 @@
|
|||
tests/cases/conformance/parser/ecmascript5/MemberAccessorDeclarations/parserMemberAccessorDeclaration11.ts(2,5): error TS1031: 'declare' modifier cannot appear on a class element.
|
||||
tests/cases/conformance/parser/ecmascript5/MemberAccessorDeclarations/parserMemberAccessorDeclaration11.ts(2,17): error TS2378: A 'get' accessor must return a value.
|
||||
|
||||
|
||||
==== tests/cases/conformance/parser/ecmascript5/MemberAccessorDeclarations/parserMemberAccessorDeclaration11.ts (1 errors) ====
|
||||
==== tests/cases/conformance/parser/ecmascript5/MemberAccessorDeclarations/parserMemberAccessorDeclaration11.ts (2 errors) ====
|
||||
class C {
|
||||
declare get Foo() { }
|
||||
~~~~~~~
|
||||
!!! error TS1031: 'declare' modifier cannot appear on a class element.
|
||||
~~~
|
||||
!!! error TS2378: A 'get' accessor must return a value.
|
||||
}
|
|
@ -1,12 +1,9 @@
|
|||
tests/cases/conformance/parser/ecmascript5/MemberFunctionDeclarations/parserMemberFunctionDeclaration5.ts(2,5): error TS1031: 'declare' modifier cannot appear on a class element.
|
||||
tests/cases/conformance/parser/ecmascript5/MemberFunctionDeclarations/parserMemberFunctionDeclaration5.ts(2,19): error TS1183: An implementation cannot be declared in ambient contexts.
|
||||
|
||||
|
||||
==== tests/cases/conformance/parser/ecmascript5/MemberFunctionDeclarations/parserMemberFunctionDeclaration5.ts (2 errors) ====
|
||||
==== tests/cases/conformance/parser/ecmascript5/MemberFunctionDeclarations/parserMemberFunctionDeclaration5.ts (1 errors) ====
|
||||
class C {
|
||||
declare Foo() { }
|
||||
~~~~~~~
|
||||
!!! error TS1031: 'declare' modifier cannot appear on a class element.
|
||||
~
|
||||
!!! error TS1183: An implementation cannot be declared in ambient contexts.
|
||||
}
|
Loading…
Reference in a new issue