diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 07a26a7b837ba..d1a66c1735bf1 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -50,7 +50,7 @@ namespace ts { // 3. non-exported import declarations case SyntaxKind.ImportDeclaration: case SyntaxKind.ImportEqualsDeclaration: - if (!(hasModifier(node, ModifierFlags.Export))) { + if (!(hasSyntacticModifier(node, ModifierFlags.Export))) { return ModuleInstanceState.NonInstantiated; } break; @@ -413,7 +413,7 @@ namespace ts { function declareSymbol(symbolTable: SymbolTable, parent: Symbol | undefined, node: Declaration, includes: SymbolFlags, excludes: SymbolFlags, isReplaceableByMethod?: boolean): Symbol { Debug.assert(!hasDynamicName(node)); - const isDefaultExport = hasModifier(node, ModifierFlags.Default) || isExportSpecifier(node) && node.name.escapedText === "default"; + const isDefaultExport = hasSyntacticModifier(node, ModifierFlags.Default) || isExportSpecifier(node) && node.name.escapedText === "default"; // The exported symbol for an export default function/class node is always named "default" const name = isDefaultExport && parent ? InternalSymbolName.Default : getDeclarationName(node); @@ -508,7 +508,7 @@ namespace ts { } const relatedInformation: DiagnosticRelatedInformation[] = []; - if (isTypeAliasDeclaration(node) && nodeIsMissing(node.type) && hasModifier(node, ModifierFlags.Export) && symbol.flags & (SymbolFlags.Alias | SymbolFlags.Type | SymbolFlags.Namespace)) { + if (isTypeAliasDeclaration(node) && nodeIsMissing(node.type) && hasSyntacticModifier(node, ModifierFlags.Export) && symbol.flags & (SymbolFlags.Alias | SymbolFlags.Type | SymbolFlags.Namespace)) { // export type T; - may have meant export type { T }? relatedInformation.push(createDiagnosticForNode(node, Diagnostics.Did_you_mean_0, `export type { ${unescapeLeadingUnderscores(node.name.escapedText)} }`)); } @@ -572,7 +572,7 @@ namespace ts { // and should never be merged directly with other augmentation, and the latter case would be possible if automatic merge is allowed. if (isJSDocTypeAlias(node)) Debug.assert(isInJSFile(node)); // We shouldn't add symbols for JSDoc nodes if not in a JS file. if ((!isAmbientModule(node) && (hasExportModifier || container.flags & NodeFlags.ExportContext)) || isJSDocTypeAlias(node)) { - if (!container.locals || (hasModifier(node, ModifierFlags.Default) && !getDeclarationName(node))) { + if (!container.locals || (hasSyntacticModifier(node, ModifierFlags.Default) && !getDeclarationName(node))) { return declareSymbol(container.symbol.exports!, container.symbol, node, symbolFlags, symbolExcludes); // No local symbol for an unnamed default! } const exportKind = symbolFlags & SymbolFlags.Value ? SymbolFlags.ExportValue : 0; @@ -637,7 +637,7 @@ namespace ts { const saveExceptionTarget = currentExceptionTarget; const saveActiveLabelList = activeLabelList; const saveHasExplicitReturn = hasExplicitReturn; - const isIIFE = containerFlags & ContainerFlags.IsFunctionExpression && !hasModifier(node, ModifierFlags.Async) && + const isIIFE = containerFlags & ContainerFlags.IsFunctionExpression && !hasSyntacticModifier(node, ModifierFlags.Async) && !(node).asteriskToken && !!getImmediatelyInvokedFunctionExpression(node); // A non-async, non-generator IIFE is considered part of the containing control flow. Return statements behave // similarly to break statements that exit to a label just past the statement body. @@ -1906,7 +1906,7 @@ namespace ts { } function declareClassMember(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { - return hasModifier(node, ModifierFlags.Static) + return hasSyntacticModifier(node, ModifierFlags.Static) ? declareSymbol(container.symbol.exports!, container.symbol, node, symbolFlags, symbolExcludes) : declareSymbol(container.symbol.members!, container.symbol, node, symbolFlags, symbolExcludes); } @@ -1936,7 +1936,7 @@ namespace ts { function bindModuleDeclaration(node: ModuleDeclaration) { setExportContextFlag(node); if (isAmbientModule(node)) { - if (hasModifier(node, ModifierFlags.Export)) { + if (hasSyntacticModifier(node, ModifierFlags.Export)) { errorOnFirstToken(node, Diagnostics.export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always_visible); } if (isModuleAugmentationExternal(node)) { @@ -2869,7 +2869,7 @@ namespace ts { // this.foo assignment in a JavaScript class // Bind this property to the containing class const containingClass = thisContainer.parent; - const symbolTable = hasModifier(thisContainer, ModifierFlags.Static) ? containingClass.symbol.exports! : containingClass.symbol.members!; + const symbolTable = hasSyntacticModifier(thisContainer, ModifierFlags.Static) ? containingClass.symbol.exports! : containingClass.symbol.members!; if (hasDynamicName(node)) { bindDynamicallyNamedThisPropertyAssignment(node, containingClass.symbol); } @@ -3403,7 +3403,7 @@ namespace ts { case SyntaxKind.ModuleDeclaration: return getModuleInstanceState(s as ModuleDeclaration) !== ModuleInstanceState.Instantiated; case SyntaxKind.EnumDeclaration: - return hasModifier(s, ModifierFlags.Const); + return hasSyntacticModifier(s, ModifierFlags.Const); default: return false; } @@ -3637,7 +3637,7 @@ namespace ts { } // If a parameter has an accessibility modifier, then it is TypeScript syntax. - if (hasModifier(node, ModifierFlags.ParameterPropertyModifier)) { + if (hasSyntacticModifier(node, ModifierFlags.ParameterPropertyModifier)) { transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.ContainsTypeScriptClassSyntax; } @@ -3676,7 +3676,7 @@ namespace ts { function computeClassDeclaration(node: ClassDeclaration, subtreeFlags: TransformFlags) { let transformFlags: TransformFlags; - if (hasModifier(node, ModifierFlags.Ambient)) { + if (hasSyntacticModifier(node, ModifierFlags.Ambient)) { // An ambient declaration is TypeScript syntax. transformFlags = TransformFlags.AssertTypeScript; } @@ -3767,7 +3767,7 @@ namespace ts { let transformFlags = subtreeFlags; // TypeScript-specific modifiers and overloads are TypeScript syntax - if (hasModifier(node, ModifierFlags.TypeScriptModifier) + if (hasSyntacticModifier(node, ModifierFlags.TypeScriptModifier) || !node.body) { transformFlags |= TransformFlags.AssertTypeScript; } @@ -3788,7 +3788,7 @@ namespace ts { // Decorators, TypeScript-specific modifiers, type parameters, type annotations, and // overloads are TypeScript syntax. if (node.decorators - || hasModifier(node, ModifierFlags.TypeScriptModifier) + || hasSyntacticModifier(node, ModifierFlags.TypeScriptModifier) || node.typeParameters || node.type || !node.body @@ -3802,7 +3802,7 @@ namespace ts { } // An async method declaration is ES2017 syntax. - if (hasModifier(node, ModifierFlags.Async)) { + if (hasSyntacticModifier(node, ModifierFlags.Async)) { transformFlags |= node.asteriskToken ? TransformFlags.AssertES2018 : TransformFlags.AssertES2017; } @@ -3820,7 +3820,7 @@ namespace ts { // Decorators, TypeScript-specific modifiers, type annotations, and overloads are // TypeScript syntax. if (node.decorators - || hasModifier(node, ModifierFlags.TypeScriptModifier) + || hasSyntacticModifier(node, ModifierFlags.TypeScriptModifier) || node.type || !node.body) { transformFlags |= TransformFlags.AssertTypeScript; @@ -3839,7 +3839,7 @@ namespace ts { let transformFlags = subtreeFlags | TransformFlags.ContainsClassFields; // Decorators, TypeScript-specific modifiers, and type annotations are TypeScript syntax. - if (some(node.decorators) || hasModifier(node, ModifierFlags.TypeScriptModifier) || node.type || node.questionToken || node.exclamationToken) { + if (some(node.decorators) || hasSyntacticModifier(node, ModifierFlags.TypeScriptModifier) || node.type || node.questionToken || node.exclamationToken) { transformFlags |= TransformFlags.AssertTypeScript; } @@ -3854,7 +3854,7 @@ namespace ts { function computeFunctionDeclaration(node: FunctionDeclaration, subtreeFlags: TransformFlags) { let transformFlags: TransformFlags; - const modifierFlags = getModifierFlags(node); + const modifierFlags = getSyntacticModifierFlags(node); const body = node.body; if (!body || (modifierFlags & ModifierFlags.Ambient)) { @@ -3902,14 +3902,14 @@ namespace ts { // TypeScript-specific modifiers, type parameters, and type annotations are TypeScript // syntax. - if (hasModifier(node, ModifierFlags.TypeScriptModifier) + if (hasSyntacticModifier(node, ModifierFlags.TypeScriptModifier) || node.typeParameters || node.type) { transformFlags |= TransformFlags.AssertTypeScript; } // An async function expression is ES2017 syntax. - if (hasModifier(node, ModifierFlags.Async)) { + if (hasSyntacticModifier(node, ModifierFlags.Async)) { transformFlags |= node.asteriskToken ? TransformFlags.AssertES2018 : TransformFlags.AssertES2017; } @@ -3935,14 +3935,14 @@ namespace ts { // TypeScript-specific modifiers, type parameters, and type annotations are TypeScript // syntax. - if (hasModifier(node, ModifierFlags.TypeScriptModifier) + if (hasSyntacticModifier(node, ModifierFlags.TypeScriptModifier) || node.typeParameters || node.type) { transformFlags |= TransformFlags.AssertTypeScript; } // An async arrow function is ES2017 syntax. - if (hasModifier(node, ModifierFlags.Async)) { + if (hasSyntacticModifier(node, ModifierFlags.Async)) { transformFlags |= TransformFlags.AssertES2017; } @@ -4016,7 +4016,7 @@ namespace ts { const declarationListTransformFlags = node.declarationList.transformFlags; // An ambient declaration is TypeScript syntax. - if (hasModifier(node, ModifierFlags.Ambient)) { + if (hasSyntacticModifier(node, ModifierFlags.Ambient)) { transformFlags = TransformFlags.AssertTypeScript; } else { @@ -4064,7 +4064,7 @@ namespace ts { function computeModuleDeclaration(node: ModuleDeclaration, subtreeFlags: TransformFlags) { let transformFlags = TransformFlags.AssertTypeScript; - const modifierFlags = getModifierFlags(node); + const modifierFlags = getSyntacticModifierFlags(node); if ((modifierFlags & ModifierFlags.Ambient) === 0) { transformFlags |= subtreeFlags; diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0872ee38e2b35..2a214d2e0f34c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1470,13 +1470,13 @@ namespace ts { (current.parent).initializer === current; if (initializerOfProperty) { - if (hasModifier(current.parent, ModifierFlags.Static)) { + if (hasSyntacticModifier(current.parent, ModifierFlags.Static)) { if (declaration.kind === SyntaxKind.MethodDeclaration) { return true; } } else { - const isDeclarationInstanceProperty = declaration.kind === SyntaxKind.PropertyDeclaration && !hasModifier(declaration, ModifierFlags.Static); + const isDeclarationInstanceProperty = declaration.kind === SyntaxKind.PropertyDeclaration && !hasSyntacticModifier(declaration, ModifierFlags.Static); if (!isDeclarationInstanceProperty || getContainingClass(usage) !== getContainingClass(declaration)) { return true; } @@ -1739,7 +1739,7 @@ namespace ts { // local variables of the constructor. This effectively means that entities from outer scopes // by the same name as a constructor parameter or local variable are inaccessible // in initializer expressions for instance member variables. - if (!hasModifier(location, ModifierFlags.Static)) { + if (!hasSyntacticModifier(location, ModifierFlags.Static)) { const ctor = findConstructorDeclaration(location.parent as ClassLikeDeclaration); if (ctor && ctor.locals) { if (lookup(ctor.locals, name, meaning & SymbolFlags.Value)) { @@ -1761,7 +1761,7 @@ namespace ts { result = undefined; break; } - if (lastLocation && hasModifier(lastLocation, ModifierFlags.Static)) { + if (lastLocation && hasSyntacticModifier(lastLocation, ModifierFlags.Static)) { // TypeScript 1.0 spec (April 2014): 3.4.1 // The scope of a type parameter extends over the entire declaration with which the type // parameter list is associated, with the exception of static member declarations in classes. @@ -2046,14 +2046,14 @@ namespace ts { // initializers in instance property declaration of class like entities are executed in constructor and thus deferred return isTypeQueryNode(location) || (( isFunctionLikeDeclaration(location) || - (location.kind === SyntaxKind.PropertyDeclaration && !hasModifier(location, ModifierFlags.Static)) + (location.kind === SyntaxKind.PropertyDeclaration && !hasSyntacticModifier(location, ModifierFlags.Static)) ) && (!lastLocation || lastLocation !== (location as FunctionLike | PropertyDeclaration).name)); // A name is evaluated within the enclosing scope - so it shouldn't count as deferred } if (lastLocation && lastLocation === (location as FunctionExpression | ArrowFunction).name) { return false; } // generator functions and async functions are not inlined in control flow when immediately invoked - if ((location as FunctionExpression | ArrowFunction).asteriskToken || hasModifier(location, ModifierFlags.Async)) { + if ((location as FunctionExpression | ArrowFunction).asteriskToken || hasSyntacticModifier(location, ModifierFlags.Async)) { return true; } return !getImmediatelyInvokedFunctionExpression(location); @@ -2113,7 +2113,7 @@ namespace ts { // No static member is present. // Check if we're in an instance method and look for a relevant instance member. - if (location === container && !hasModifier(location, ModifierFlags.Static)) { + if (location === container && !hasSyntacticModifier(location, ModifierFlags.Static)) { const instanceType = (getDeclaredTypeOfSymbol(classSymbol)).thisType!; // TODO: GH#18217 if (getPropertyOfType(instanceType, name)) { error(errorLocation, Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0, diagnosticName(nameArg)); @@ -2404,7 +2404,7 @@ namespace ts { } function isSyntacticDefault(node: Node) { - return ((isExportAssignment(node) && !node.isExportEquals) || hasModifier(node, ModifierFlags.Default) || isExportSpecifier(node)); + return ((isExportAssignment(node) && !node.isExportEquals) || hasSyntacticModifier(node, ModifierFlags.Default) || isExportSpecifier(node)); } function canHaveSyntheticDefault(file: SourceFile | undefined, moduleSymbol: Symbol, dontResolveAlias: boolean) { @@ -4007,17 +4007,17 @@ namespace ts { const anyImportSyntax = getAnyImportSyntax(declaration); if (anyImportSyntax && - !hasModifier(anyImportSyntax, ModifierFlags.Export) && // import clause without export + !hasSyntacticModifier(anyImportSyntax, ModifierFlags.Export) && // import clause without export isDeclarationVisible(anyImportSyntax.parent)) { return addVisibleAlias(declaration, anyImportSyntax); } else if (isVariableDeclaration(declaration) && isVariableStatement(declaration.parent.parent) && - !hasModifier(declaration.parent.parent, ModifierFlags.Export) && // unexported variable statement + !hasSyntacticModifier(declaration.parent.parent, ModifierFlags.Export) && // unexported variable statement isDeclarationVisible(declaration.parent.parent.parent)) { return addVisibleAlias(declaration, declaration.parent.parent); } else if (isLateVisibilityPaintedStatement(declaration) // unexported top-level statement - && !hasModifier(declaration, ModifierFlags.Export) + && !hasSyntacticModifier(declaration, ModifierFlags.Export) && isDeclarationVisible(declaration.parent)) { return addVisibleAlias(declaration, declaration); } @@ -4466,7 +4466,7 @@ namespace ts { } function shouldWriteTypeOfFunctionSymbol() { const isStaticMethodSymbol = !!(symbol.flags & SymbolFlags.Method) && // typeof static method - some(symbol.declarations, declaration => hasModifier(declaration, ModifierFlags.Static)); + some(symbol.declarations, declaration => hasSyntacticModifier(declaration, ModifierFlags.Static)); const isNonLocalFunctionSymbol = !!(symbol.flags & SymbolFlags.Function) && (symbol.parent || // is exported function symbol forEach(symbol.declarations, declaration => @@ -5771,7 +5771,7 @@ namespace ts { ns.body && isModuleBlock(ns.body)) { // Pass 0: Correct situations where a module has both an `export = ns` and multiple top-level exports by stripping the export modifiers from // the top-level exports and exporting them in the targeted ns, as can occur when a js file has both typedefs and `module.export` assignments - const excessExports = filter(statements, s => !!(getModifierFlags(s) & ModifierFlags.Export)); + const excessExports = filter(statements, s => !!(getEffectiveModifierFlags(s) & ModifierFlags.Export)); if (length(excessExports)) { ns.body.statements = createNodeArray([...ns.body.statements, createExportDeclaration( /*decorators*/ undefined, @@ -5884,7 +5884,7 @@ namespace ts { } function addExportModifier(statement: Statement) { - const flags = (getModifierFlags(statement) | ModifierFlags.Export) & ~ModifierFlags.Ambient; + const flags = (getEffectiveModifierFlags(statement) | ModifierFlags.Export) & ~ModifierFlags.Ambient; statement.modifiers = createNodeArray(createModifiersFromModifierFlags(flags)); statement.modifierFlagsCache = 0; } @@ -6046,7 +6046,7 @@ namespace ts { newModifierFlags |= ModifierFlags.Default; } if (newModifierFlags) { - node.modifiers = createNodeArray(createModifiersFromModifierFlags(newModifierFlags | getModifierFlags(node))); + node.modifiers = createNodeArray(createModifiersFromModifierFlags(newModifierFlags | getEffectiveModifierFlags(node))); node.modifierFlagsCache = 0; // Reset computed flags cache } results.push(node); @@ -6730,7 +6730,7 @@ namespace ts { let privateProtected: ModifierFlags = 0; for (const s of signatures) { if (s.declaration) { - privateProtected |= getSelectedModifierFlags(s.declaration, ModifierFlags.Private | ModifierFlags.Protected); + privateProtected |= getSelectedEffectiveModifierFlags(s.declaration, ModifierFlags.Private | ModifierFlags.Protected); } } if (privateProtected) { @@ -7073,7 +7073,7 @@ namespace ts { case SyntaxKind.SetAccessor: case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: - if (hasModifier(node, ModifierFlags.Private | ModifierFlags.Protected)) { + if (hasEffectiveModifier(node, ModifierFlags.Private | ModifierFlags.Protected)) { // Private/protected properties/methods are not visible return false; } @@ -7575,7 +7575,7 @@ namespace ts { // Use control flow analysis of this.xxx assignments the constructor to determine the type of the property. const constructor = findConstructorDeclaration(declaration.parent); const type = constructor ? getFlowTypeInConstructor(declaration.symbol, constructor) : - getModifierFlags(declaration) & ModifierFlags.Ambient ? getTypeOfPropertyInBaseClass(declaration.symbol) : + getEffectiveModifierFlags(declaration) & ModifierFlags.Ambient ? getTypeOfPropertyInBaseClass(declaration.symbol) : undefined; return type && addOptionality(type, isOptional); } @@ -7645,7 +7645,7 @@ namespace ts { } function getFlowTypeOfProperty(reference: Node, prop: Symbol | undefined) { - const initialType = prop && (!isAutoTypedProperty(prop) || getModifierFlags(prop.valueDeclaration) & ModifierFlags.Ambient) && getTypeOfPropertyInBaseClass(prop) || undefinedType; + const initialType = prop && (!isAutoTypedProperty(prop) || getEffectiveModifierFlags(prop.valueDeclaration) & ModifierFlags.Ambient) && getTypeOfPropertyInBaseClass(prop) || undefinedType; return getFlowTypeOfReference(reference, autoType, initialType); } @@ -9105,7 +9105,7 @@ namespace ts { } function isStaticPrivateIdentifierProperty(s: Symbol): boolean { - return !!s.valueDeclaration && isPrivateIdentifierPropertyDeclaration(s.valueDeclaration) && hasModifier(s.valueDeclaration, ModifierFlags.Static); + return !!s.valueDeclaration && isPrivateIdentifierPropertyDeclaration(s.valueDeclaration) && hasSyntacticModifier(s.valueDeclaration, ModifierFlags.Static); } function resolveDeclaredMembers(type: InterfaceType): InterfaceTypeWithDeclaredMembers { @@ -11387,7 +11387,7 @@ namespace ts { const declaration = getIndexDeclarationOfSymbol(symbol, kind); if (declaration) { return createIndexInfo(declaration.type ? getTypeFromTypeNode(declaration.type) : anyType, - hasModifier(declaration, ModifierFlags.Readonly), declaration); + hasEffectiveModifier(declaration, ModifierFlags.Readonly), declaration); } return undefined; } @@ -13782,7 +13782,7 @@ namespace ts { const container = getThisContainer(node, /*includeArrowFunctions*/ false); const parent = container && container.parent; if (parent && (isClassLike(parent) || parent.kind === SyntaxKind.InterfaceDeclaration)) { - if (!hasModifier(container, ModifierFlags.Static) && + if (!hasSyntacticModifier(container, ModifierFlags.Static) && (!isConstructorDeclaration(container) || isNodeDescendantOf(node, container.body))) { return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(parent as ClassLikeDeclaration | InterfaceDeclaration)).thisType!; } @@ -17224,8 +17224,8 @@ namespace ts { return true; } - const sourceAccessibility = getSelectedModifierFlags(sourceSignature.declaration, ModifierFlags.NonPublicAccessibilityModifier); - const targetAccessibility = getSelectedModifierFlags(targetSignature.declaration, ModifierFlags.NonPublicAccessibilityModifier); + const sourceAccessibility = getSelectedEffectiveModifierFlags(sourceSignature.declaration, ModifierFlags.NonPublicAccessibilityModifier); + const targetAccessibility = getSelectedEffectiveModifierFlags(targetSignature.declaration, ModifierFlags.NonPublicAccessibilityModifier); // A public, protected and private signature is assignable to a private signature. if (targetAccessibility === ModifierFlags.Private) { @@ -21287,7 +21287,7 @@ namespace ts { if (container.kind === SyntaxKind.ArrowFunction) { error(node, Diagnostics.The_arguments_object_cannot_be_referenced_in_an_arrow_function_in_ES3_and_ES5_Consider_using_a_standard_function_expression); } - else if (hasModifier(container, ModifierFlags.Async)) { + else if (hasSyntacticModifier(container, ModifierFlags.Async)) { error(node, Diagnostics.The_arguments_object_cannot_be_referenced_in_an_async_function_or_method_in_ES3_and_ES5_Consider_using_a_standard_function_or_method); } } @@ -21329,7 +21329,7 @@ namespace ts { let container = getThisContainer(node, /*includeArrowFunctions*/ false); while (container.kind !== SyntaxKind.SourceFile) { if (container.parent === declaration) { - if (container.kind === SyntaxKind.PropertyDeclaration && hasModifier(container, ModifierFlags.Static)) { + if (container.kind === SyntaxKind.PropertyDeclaration && hasSyntacticModifier(container, ModifierFlags.Static)) { getNodeLinks(declaration).flags |= NodeCheckFlags.ClassWithConstructorReference; getNodeLinks(node).flags |= NodeCheckFlags.ConstructorReferenceInClass; } @@ -21649,7 +21649,7 @@ namespace ts { break; case SyntaxKind.PropertyDeclaration: case SyntaxKind.PropertySignature: - if (hasModifier(container, ModifierFlags.Static) && !(compilerOptions.target === ScriptTarget.ESNext && compilerOptions.useDefineForClassFields)) { + if (hasSyntacticModifier(container, ModifierFlags.Static) && !(compilerOptions.target === ScriptTarget.ESNext && compilerOptions.useDefineForClassFields)) { error(node, Diagnostics.this_cannot_be_referenced_in_a_static_property_initializer); // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks } @@ -21719,7 +21719,7 @@ namespace ts { if (isClassLike(container.parent)) { const symbol = getSymbolOfNode(container.parent); - const type = hasModifier(container, ModifierFlags.Static) ? getTypeOfSymbol(symbol) : (getDeclaredTypeOfSymbol(symbol) as InterfaceType).thisType!; + const type = hasSyntacticModifier(container, ModifierFlags.Static) ? getTypeOfSymbol(symbol) : (getDeclaredTypeOfSymbol(symbol) as InterfaceType).thisType!; return getFlowTypeOfReference(node, type); } @@ -21755,7 +21755,7 @@ namespace ts { } if (isClassLike(container.parent)) { const symbol = getSymbolOfNode(container.parent); - return hasModifier(container, ModifierFlags.Static) ? getTypeOfSymbol(symbol) : (getDeclaredTypeOfSymbol(symbol) as InterfaceType).thisType!; + return hasSyntacticModifier(container, ModifierFlags.Static) ? getTypeOfSymbol(symbol) : (getDeclaredTypeOfSymbol(symbol) as InterfaceType).thisType!; } } @@ -21875,7 +21875,7 @@ namespace ts { checkThisBeforeSuper(node, container, Diagnostics.super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class); } - if (hasModifier(container, ModifierFlags.Static) || isCallExpression) { + if (hasSyntacticModifier(container, ModifierFlags.Static) || isCallExpression) { nodeCheckFlag = NodeCheckFlags.SuperStatic; } else { @@ -21943,7 +21943,7 @@ namespace ts { // as a call expression cannot be used as the target of a destructuring assignment while a property access can. // // For element access expressions (`super[x]`), we emit a generic helper that forwards the element access in both situations. - if (container.kind === SyntaxKind.MethodDeclaration && hasModifier(container, ModifierFlags.Async)) { + if (container.kind === SyntaxKind.MethodDeclaration && hasSyntacticModifier(container, ModifierFlags.Async)) { if (isSuperProperty(node.parent) && isAssignmentTarget(node.parent)) { getNodeLinks(container).flags |= NodeCheckFlags.AsyncMethodWithSuperBinding; } @@ -22011,7 +22011,7 @@ namespace ts { // topmost container must be something that is directly nested in the class declaration\object literal expression if (isClassLike(container.parent) || container.parent.kind === SyntaxKind.ObjectLiteralExpression) { - if (hasModifier(container, ModifierFlags.Static)) { + if (hasSyntacticModifier(container, ModifierFlags.Static)) { return container.kind === SyntaxKind.MethodDeclaration || container.kind === SyntaxKind.MethodSignature || container.kind === SyntaxKind.GetAccessor || @@ -24477,7 +24477,7 @@ namespace ts { function typeHasStaticProperty(propName: __String, containingType: Type): boolean { const prop = containingType.symbol && getPropertyOfType(getTypeOfSymbol(containingType.symbol), propName); - return prop !== undefined && prop.valueDeclaration && hasModifier(prop.valueDeclaration, ModifierFlags.Static); + return prop !== undefined && prop.valueDeclaration && hasSyntacticModifier(prop.valueDeclaration, ModifierFlags.Static); } function getSuggestedSymbolForNonexistentProperty(name: Identifier | PrivateIdentifier | string, containingType: Type): Symbol | undefined { @@ -24586,7 +24586,7 @@ namespace ts { if (!valueDeclaration) { return; } - const hasPrivateModifier = hasModifier(valueDeclaration, ModifierFlags.Private); + const hasPrivateModifier = hasEffectiveModifier(valueDeclaration, ModifierFlags.Private); const hasPrivateIdentifier = isNamedDeclaration(prop.valueDeclaration) && isPrivateIdentifier(prop.valueDeclaration.name); if (!hasPrivateModifier && !hasPrivateIdentifier) { return; @@ -26154,7 +26154,7 @@ namespace ts { // In the case of a merged class-module or class-interface declaration, // only the class declaration node will have the Abstract flag set. const valueDecl = expressionType.symbol && getClassLikeDeclarationOfSymbol(expressionType.symbol); - if (valueDecl && hasModifier(valueDecl, ModifierFlags.Abstract)) { + if (valueDecl && hasSyntacticModifier(valueDecl, ModifierFlags.Abstract)) { error(node, Diagnostics.Cannot_create_an_instance_of_an_abstract_class); return resolveErrorCall(node); } @@ -26222,7 +26222,7 @@ namespace ts { } const declaration = signature.declaration; - const modifiers = getSelectedModifierFlags(declaration, ModifierFlags.NonPublicAccessibilityModifier); + const modifiers = getSelectedEffectiveModifierFlags(declaration, ModifierFlags.NonPublicAccessibilityModifier); // (1) Public constructors and (2) constructor functions are always accessible. if (!modifiers || declaration.kind !== SyntaxKind.Constructor) { @@ -29405,7 +29405,7 @@ namespace ts { checkVariableLikeDeclaration(node); const func = getContainingFunction(node)!; - if (hasModifier(node, ModifierFlags.ParameterPropertyModifier)) { + if (hasSyntacticModifier(node, ModifierFlags.ParameterPropertyModifier)) { if (!(func.kind === SyntaxKind.Constructor && nodeIsPresent(func.body))) { error(node, Diagnostics.A_parameter_property_is_only_allowed_in_a_constructor_implementation); } @@ -29632,7 +29632,7 @@ namespace ts { } } else { - const isStatic = hasModifier(member, ModifierFlags.Static); + const isStatic = hasSyntacticModifier(member, ModifierFlags.Static); const name = member.name; if (!name) { return; @@ -29699,7 +29699,7 @@ namespace ts { function checkClassForStaticPropertyNameConflicts(node: ClassLikeDeclaration) { for (const member of node.members) { const memberNameNode = member.name; - const isStatic = hasModifier(member, ModifierFlags.Static); + const isStatic = hasSyntacticModifier(member, ModifierFlags.Static); if (isStatic && memberNameNode) { const memberName = getPropertyNameForPropertyNameNode(memberNameNode); switch (memberName) { @@ -29822,7 +29822,7 @@ namespace ts { // Abstract methods cannot have an implementation. // Extra checks are to avoid reporting multiple errors relating to the "abstractness" of the node. - if (hasModifier(node, ModifierFlags.Abstract) && node.kind === SyntaxKind.MethodDeclaration && node.body) { + if (hasSyntacticModifier(node, ModifierFlags.Abstract) && node.kind === SyntaxKind.MethodDeclaration && node.body) { error(node, Diagnostics.Method_0_cannot_have_an_implementation_because_it_is_marked_abstract, declarationNameToString(node.name)); } } @@ -29857,7 +29857,7 @@ namespace ts { return true; } return n.kind === SyntaxKind.PropertyDeclaration && - !hasModifier(n, ModifierFlags.Static) && + !hasSyntacticModifier(n, ModifierFlags.Static) && !!(n).initializer; } @@ -29882,7 +29882,7 @@ namespace ts { const superCallShouldBeFirst = (compilerOptions.target !== ScriptTarget.ESNext || !compilerOptions.useDefineForClassFields) && (some((node.parent).members, isInstancePropertyWithInitializerOrPrivateIdentifierProperty) || - some(node.parameters, p => hasModifier(p, ModifierFlags.ParameterPropertyModifier))); + some(node.parameters, p => hasSyntacticModifier(p, ModifierFlags.ParameterPropertyModifier))); // Skip past any prologue directives to find the first statement // to ensure that it was a super call. @@ -29939,8 +29939,8 @@ namespace ts { const otherKind = node.kind === SyntaxKind.GetAccessor ? SyntaxKind.SetAccessor : SyntaxKind.GetAccessor; const otherAccessor = getDeclarationOfKind(getSymbolOfNode(node), otherKind); if (otherAccessor) { - const nodeFlags = getModifierFlags(node); - const otherFlags = getModifierFlags(otherAccessor); + const nodeFlags = getEffectiveModifierFlags(node); + const otherFlags = getEffectiveModifierFlags(otherAccessor); if ((nodeFlags & ModifierFlags.AccessibilityModifier) !== (otherFlags & ModifierFlags.AccessibilityModifier)) { error(node.name, Diagnostics.Getter_and_setter_accessors_do_not_agree_in_visibility); } @@ -30167,7 +30167,7 @@ namespace ts { } function isPrivateWithinAmbient(node: Node): boolean { - return (hasModifier(node, ModifierFlags.Private) || isPrivateIdentifierPropertyDeclaration(node)) && !!(node.flags & NodeFlags.Ambient); + return (hasEffectiveModifier(node, ModifierFlags.Private) || isPrivateIdentifierPropertyDeclaration(node)) && !!(node.flags & NodeFlags.Ambient); } function getEffectiveDeclarationFlags(n: Declaration, flagsToCheck: ModifierFlags): ModifierFlags { @@ -30286,13 +30286,13 @@ namespace ts { )) { const reportError = (node.kind === SyntaxKind.MethodDeclaration || node.kind === SyntaxKind.MethodSignature) && - hasModifier(node, ModifierFlags.Static) !== hasModifier(subsequentNode, ModifierFlags.Static); + hasSyntacticModifier(node, ModifierFlags.Static) !== hasSyntacticModifier(subsequentNode, ModifierFlags.Static); // we can get here in two cases // 1. mixed static and instance class members // 2. something with the same name was defined before the set of overloads that prevents them from merging // here we'll report error only for the first case since for second we should already report error in binder if (reportError) { - const diagnostic = hasModifier(node, ModifierFlags.Static) ? Diagnostics.Function_overload_must_be_static : Diagnostics.Function_overload_must_not_be_static; + const diagnostic = hasSyntacticModifier(node, ModifierFlags.Static) ? Diagnostics.Function_overload_must_be_static : Diagnostics.Function_overload_must_not_be_static; error(errorNode, diagnostic); } return; @@ -30310,7 +30310,7 @@ namespace ts { else { // Report different errors regarding non-consecutive blocks of declarations depending on whether // the node in question is abstract. - if (hasModifier(node, ModifierFlags.Abstract)) { + if (hasSyntacticModifier(node, ModifierFlags.Abstract)) { error(errorNode, Diagnostics.All_declarations_of_an_abstract_method_must_be_consecutive); } else { @@ -30401,7 +30401,7 @@ namespace ts { // Abstract methods can't have an implementation -- in particular, they don't need one. if (lastSeenNonAmbientDeclaration && !lastSeenNonAmbientDeclaration.body && - !hasModifier(lastSeenNonAmbientDeclaration, ModifierFlags.Abstract) && !lastSeenNonAmbientDeclaration.questionToken) { + !hasSyntacticModifier(lastSeenNonAmbientDeclaration, ModifierFlags.Abstract) && !lastSeenNonAmbientDeclaration.questionToken) { reportImplementationExpectedError(lastSeenNonAmbientDeclaration); } @@ -31345,14 +31345,14 @@ namespace ts { } const symbol = getSymbolOfNode(member); if (!symbol.isReferenced - && (hasModifier(member, ModifierFlags.Private) || isNamedDeclaration(member) && isPrivateIdentifier(member.name)) + && (hasEffectiveModifier(member, ModifierFlags.Private) || isNamedDeclaration(member) && isPrivateIdentifier(member.name)) && !(member.flags & NodeFlags.Ambient)) { addDiagnostic(member, UnusedKind.Local, createDiagnosticForNode(member.name!, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolToString(symbol))); } break; case SyntaxKind.Constructor: for (const parameter of (member).parameters) { - if (!parameter.symbol.isReferenced && hasModifier(parameter, ModifierFlags.Private)) { + if (!parameter.symbol.isReferenced && hasSyntacticModifier(parameter, ModifierFlags.Private)) { addDiagnostic(parameter, UnusedKind.Local, createDiagnosticForNode(parameter.name, Diagnostics.Property_0_is_declared_but_its_value_is_never_read, symbolName(parameter.symbol))); } } @@ -31947,7 +31947,7 @@ namespace ts { ModifierFlags.Readonly | ModifierFlags.Static; - return getSelectedModifierFlags(left, interestingFlags) === getSelectedModifierFlags(right, interestingFlags); + return getSelectedEffectiveModifierFlags(left, interestingFlags) === getSelectedEffectiveModifierFlags(right, interestingFlags); } function checkVariableDeclaration(node: VariableDeclaration) { @@ -33136,7 +33136,7 @@ namespace ts { // Only process instance properties with computed names here. // Static properties cannot be in conflict with indexers, // and properties with literal names were already checked. - if (!hasModifier(member, ModifierFlags.Static) && hasNonBindableDynamicName(member)) { + if (!hasSyntacticModifier(member, ModifierFlags.Static) && hasNonBindableDynamicName(member)) { const symbol = getSymbolOfNode(member); const propType = getTypeOfSymbol(symbol); checkIndexConstraintForProperty(symbol, propType, type, declaredStringIndexer, stringIndexType, IndexKind.String); @@ -33372,7 +33372,7 @@ namespace ts { } function checkClassDeclaration(node: ClassDeclaration) { - if (!node.name && !hasModifier(node, ModifierFlags.Default)) { + if (!node.name && !hasSyntacticModifier(node, ModifierFlags.Default)) { grammarErrorOnFirstToken(node, Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name); } checkClassLikeDeclaration(node); @@ -33527,7 +33527,7 @@ namespace ts { const signatures = getSignaturesOfType(type, SignatureKind.Construct); if (signatures.length) { const declaration = signatures[0].declaration; - if (declaration && hasModifier(declaration, ModifierFlags.Private)) { + if (declaration && hasEffectiveModifier(declaration, ModifierFlags.Private)) { const typeClassDeclaration = getClassLikeDeclarationOfSymbol(type.symbol)!; if (!isNodeWithinClass(node, typeClassDeclaration)) { error(node, Diagnostics.Cannot_extend_a_class_0_Class_constructor_is_marked_as_private, getFullyQualifiedName(type.symbol)); @@ -33589,7 +33589,7 @@ namespace ts { // It is an error to inherit an abstract member without implementing it or being declared abstract. // If there is no declaration for the derived class (as in the case of class expressions), // then the class cannot be declared abstract. - if (baseDeclarationFlags & ModifierFlags.Abstract && (!derivedClassDecl || !hasModifier(derivedClassDecl, ModifierFlags.Abstract))) { + if (baseDeclarationFlags & ModifierFlags.Abstract && (!derivedClassDecl || !hasSyntacticModifier(derivedClassDecl, ModifierFlags.Abstract))) { // Searches other base types for a declaration that would satisfy the inherited abstract member. // (The class may have more than one base type via declaration merging with an interface with the // same name.) @@ -33750,7 +33750,7 @@ namespace ts { } const constructor = findConstructorDeclaration(node); for (const member of node.members) { - if (getModifierFlags(member) & ModifierFlags.Ambient) { + if (getEffectiveModifierFlags(member) & ModifierFlags.Ambient) { continue; } if (isInstancePropertyWithoutInitializer(member)) { @@ -33769,7 +33769,7 @@ namespace ts { function isInstancePropertyWithoutInitializer(node: Node) { return node.kind === SyntaxKind.PropertyDeclaration && - !hasModifier(node, ModifierFlags.Static | ModifierFlags.Abstract) && + !hasSyntacticModifier(node, ModifierFlags.Static | ModifierFlags.Abstract) && !(node).exclamationToken && !(node).initializer; } @@ -34349,7 +34349,7 @@ namespace ts { // If we hit an import declaration in an illegal context, just bail out to avoid cascading errors. return; } - if (!checkGrammarDecoratorsAndModifiers(node) && hasModifiers(node)) { + if (!checkGrammarDecoratorsAndModifiers(node) && hasEffectiveModifiers(node)) { grammarErrorOnFirstToken(node, Diagnostics.An_import_declaration_cannot_have_modifiers); } if (checkExternalImportOrExportDeclaration(node)) { @@ -34382,7 +34382,7 @@ namespace ts { checkGrammarDecoratorsAndModifiers(node); if (isInternalModuleImportEqualsDeclaration(node) || checkExternalImportOrExportDeclaration(node)) { checkImportBinding(node); - if (hasModifier(node, ModifierFlags.Export)) { + if (hasSyntacticModifier(node, ModifierFlags.Export)) { markExportAsReferenced(node); } if (node.moduleReference.kind !== SyntaxKind.ExternalModuleReference) { @@ -34415,7 +34415,7 @@ namespace ts { return; } - if (!checkGrammarDecoratorsAndModifiers(node) && hasModifiers(node)) { + if (!checkGrammarDecoratorsAndModifiers(node) && hasEffectiveModifiers(node)) { grammarErrorOnFirstToken(node, Diagnostics.An_export_declaration_cannot_have_modifiers); } @@ -34538,7 +34538,7 @@ namespace ts { return; } // Grammar checking - if (!checkGrammarDecoratorsAndModifiers(node) && hasModifiers(node)) { + if (!checkGrammarDecoratorsAndModifiers(node) && hasEffectiveModifiers(node)) { grammarErrorOnFirstToken(node, Diagnostics.An_export_assignment_cannot_have_modifiers); } if (node.expression.kind === SyntaxKind.Identifier) { @@ -35155,7 +35155,7 @@ namespace ts { copySymbol(argumentsSymbol, meaning); } - isStatic = hasModifier(location, ModifierFlags.Static); + isStatic = hasSyntacticModifier(location, ModifierFlags.Static); location = location.parent; } @@ -35680,7 +35680,7 @@ namespace ts { */ function getParentTypeOfClassElement(node: ClassElement) { const classSymbol = getSymbolOfNode(node.parent)!; - return hasModifier(node, ModifierFlags.Static) + return hasSyntacticModifier(node, ModifierFlags.Static) ? getTypeOfSymbol(classSymbol) : getDeclaredTypeOfSymbol(classSymbol); } @@ -35983,7 +35983,7 @@ namespace ts { return true; } const target = getSymbolLinks(symbol!).target; // TODO: GH#18217 - if (target && getModifierFlags(node) & ModifierFlags.Export && + if (target && getEffectiveModifierFlags(node) & ModifierFlags.Export && target.flags & SymbolFlags.Value && (compilerOptions.preserveConstEnums || !isConstEnumOrConstEnumOnlyModule(target))) { // An `export import ... =` of a value symbol is always considered referenced @@ -36024,14 +36024,14 @@ namespace ts { !isOptionalParameter(parameter) && !isJSDocParameterTag(parameter) && !!parameter.initializer && - !hasModifier(parameter, ModifierFlags.ParameterPropertyModifier); + !hasSyntacticModifier(parameter, ModifierFlags.ParameterPropertyModifier); } function isOptionalUninitializedParameterProperty(parameter: ParameterDeclaration) { return strictNullChecks && isOptionalParameter(parameter) && !parameter.initializer && - hasModifier(parameter, ModifierFlags.ParameterPropertyModifier); + hasSyntacticModifier(parameter, ModifierFlags.ParameterPropertyModifier); } function isExpandoFunctionDeclaration(node: Declaration): boolean { @@ -36867,7 +36867,7 @@ namespace ts { node.kind !== SyntaxKind.SetAccessor) { return grammarErrorOnNode(modifier, Diagnostics.abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration); } - if (!(node.parent.kind === SyntaxKind.ClassDeclaration && hasModifier(node.parent, ModifierFlags.Abstract))) { + if (!(node.parent.kind === SyntaxKind.ClassDeclaration && hasSyntacticModifier(node.parent, ModifierFlags.Abstract))) { return grammarErrorOnNode(modifier, Diagnostics.Abstract_methods_can_only_appear_within_an_abstract_class); } if (flags & ModifierFlags.Static) { @@ -37113,7 +37113,7 @@ namespace ts { if (parameter.dotDotDotToken) { return grammarErrorOnNode(parameter.dotDotDotToken, Diagnostics.An_index_signature_cannot_have_a_rest_parameter); } - if (hasModifiers(parameter)) { + if (hasEffectiveModifiers(parameter)) { return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_cannot_have_an_accessibility_modifier); } if (parameter.questionToken) { @@ -37507,11 +37507,11 @@ namespace ts { if (languageVersion < ScriptTarget.ES5) { return grammarErrorOnNode(accessor.name, Diagnostics.Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher); } - if (accessor.body === undefined && !hasModifier(accessor, ModifierFlags.Abstract)) { + if (accessor.body === undefined && !hasSyntacticModifier(accessor, ModifierFlags.Abstract)) { return grammarErrorAtPos(accessor, accessor.end - 1, ";".length, Diagnostics._0_expected, "{"); } } - if (accessor.body && hasModifier(accessor, ModifierFlags.Abstract)) { + if (accessor.body && hasSyntacticModifier(accessor, ModifierFlags.Abstract)) { return grammarErrorOnNode(accessor, Diagnostics.An_abstract_accessor_cannot_have_an_implementation); } if (accessor.typeParameters) { @@ -37561,7 +37561,14 @@ namespace ts { return grammarErrorOnNode(node.type, Diagnostics._0_expected, tokenToString(SyntaxKind.SymbolKeyword)); } - const parent = walkUpParenthesizedTypes(node.parent); + let parent = walkUpParenthesizedTypes(node.parent); + if (isInJSFile(parent) && isJSDocTypeExpression(parent)) { + parent = parent.parent; + if (isJSDocTypeTag(parent)) { + // walk up past JSDoc comment node + parent = parent.parent.parent; + } + } switch (parent.kind) { case SyntaxKind.VariableDeclaration: const decl = parent as VariableDeclaration; @@ -37577,14 +37584,14 @@ namespace ts { break; case SyntaxKind.PropertyDeclaration: - if (!hasModifier(parent, ModifierFlags.Static) || - !hasModifier(parent, ModifierFlags.Readonly)) { + if (!hasSyntacticModifier(parent, ModifierFlags.Static) || + !hasEffectiveModifier(parent, ModifierFlags.Readonly)) { return grammarErrorOnNode((parent).name, Diagnostics.A_property_of_a_class_whose_type_is_a_unique_symbol_type_must_be_both_static_and_readonly); } break; case SyntaxKind.PropertySignature: - if (!hasModifier(parent, ModifierFlags.Readonly)) { + if (!hasSyntacticModifier(parent, ModifierFlags.Readonly)) { return grammarErrorOnNode((parent).name, Diagnostics.A_property_of_an_interface_or_type_literal_whose_type_is_a_unique_symbol_type_must_be_readonly); } break; @@ -37791,7 +37798,7 @@ namespace ts { const moduleKind = getEmitModuleKind(compilerOptions); if (moduleKind < ModuleKind.ES2015 && moduleKind !== ModuleKind.System && !compilerOptions.noEmit && - !(node.parent.parent.flags & NodeFlags.Ambient) && hasModifier(node.parent.parent, ModifierFlags.Export)) { + !(node.parent.parent.flags & NodeFlags.Ambient) && hasSyntacticModifier(node.parent.parent, ModifierFlags.Export)) { checkESModuleMarker(node.name); } @@ -37979,7 +37986,7 @@ namespace ts { } if (isPropertyDeclaration(node) && node.exclamationToken && (!isClassLike(node.parent) || !node.type || node.initializer || - node.flags & NodeFlags.Ambient || hasModifier(node, ModifierFlags.Static | ModifierFlags.Abstract))) { + node.flags & NodeFlags.Ambient || hasSyntacticModifier(node, ModifierFlags.Static | ModifierFlags.Abstract))) { return grammarErrorOnNode(node.exclamationToken, Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context); } } @@ -38004,7 +38011,7 @@ namespace ts { node.kind === SyntaxKind.ExportDeclaration || node.kind === SyntaxKind.ExportAssignment || node.kind === SyntaxKind.NamespaceExportDeclaration || - hasModifier(node, ModifierFlags.Ambient | ModifierFlags.Export | ModifierFlags.Default)) { + hasSyntacticModifier(node, ModifierFlags.Ambient | ModifierFlags.Export | ModifierFlags.Default)) { return false; } diff --git a/src/compiler/debug.ts b/src/compiler/debug.ts index 53e23b02acee5..37beb5225b540 100644 --- a/src/compiler/debug.ts +++ b/src/compiler/debug.ts @@ -376,7 +376,7 @@ namespace ts { Object.defineProperties(ctor.prototype, { __debugKind: { get(this: Node) { return formatSyntaxKind(this.kind); } }, __debugNodeFlags: { get(this: Node) { return formatNodeFlags(this.flags); } }, - __debugModifierFlags: { get(this: Node) { return formatModifierFlags(getModifierFlagsNoCache(this)); } }, + __debugModifierFlags: { get(this: Node) { return formatModifierFlags(getEffectiveModifierFlagsNoCache(this)); } }, __debugTransformFlags: { get(this: Node) { return formatTransformFlags(this.transformFlags); } }, __debugIsParseTreeNode: { get(this: Node) { return isParseTreeNode(this); } }, __debugEmitFlags: { get(this: Node) { return formatEmitFlags(getEmitFlags(this)); } }, diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index ed854342245cf..833da8c8a6a56 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -751,7 +751,7 @@ namespace ts { * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. */ export function getExternalModuleOrNamespaceExportName(ns: Identifier | undefined, node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean): Identifier | PropertyAccessExpression { - if (ns && hasModifier(node, ModifierFlags.Export)) { + if (ns && hasSyntacticModifier(node, ModifierFlags.Export)) { return getNamespaceMemberName(ns, getName(node), allowComments, allowSourceMaps); } return getExportName(node, allowComments, allowSourceMaps); diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 437ec09e8b8ce..c8847d0435896 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -2145,7 +2145,7 @@ namespace ts { } } else if (isModuleDeclaration(node)) { - if (isAmbientModule(node) && (inAmbientModule || hasModifier(node, ModifierFlags.Ambient) || file.isDeclarationFile)) { + if (isAmbientModule(node) && (inAmbientModule || hasSyntacticModifier(node, ModifierFlags.Ambient) || file.isDeclarationFile)) { const nameText = getTextOfIdentifierOrLiteral(node.name); // Ambient module declarations can be interpreted as augmentations for some existing external modules. // This will happen in two cases: diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 413ff8f8cd2e5..1e9aa130f682b 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -487,7 +487,7 @@ namespace ts { | PropertySignature; function ensureType(node: HasInferredType, type: TypeNode | undefined, ignorePrivate?: boolean): TypeNode | undefined { - if (!ignorePrivate && hasModifier(node, ModifierFlags.Private)) { + if (!ignorePrivate && hasEffectiveModifier(node, ModifierFlags.Private)) { // Private nodes emit no types (except private parameter properties, whose parameter types are actually visible) return; } @@ -571,7 +571,7 @@ namespace ts { } function updateParamsList(node: Node, params: NodeArray, modifierMask?: ModifierFlags) { - if (hasModifier(node, ModifierFlags.Private)) { + if (hasEffectiveModifier(node, ModifierFlags.Private)) { return undefined!; // TODO: GH#18217 } const newParams = map(params, p => ensureParameter(p, modifierMask)); @@ -612,7 +612,7 @@ namespace ts { } function ensureTypeParams(node: Node, params: NodeArray | undefined) { - return hasModifier(node, ModifierFlags.Private) ? undefined : visitNodes(params, visitDeclarationSubtree); + return hasEffectiveModifier(node, ModifierFlags.Private) ? undefined : visitNodes(params, visitDeclarationSubtree); } function isEnclosingDeclaration(node: Node) { @@ -825,7 +825,7 @@ namespace ts { // Emit methods which are private as properties with no type information if (isMethodDeclaration(input) || isMethodSignature(input)) { - if (hasModifier(input, ModifierFlags.Private)) { + if (hasEffectiveModifier(input, ModifierFlags.Private)) { if (input.symbol && input.symbol.declarations && input.symbol.declarations[0] !== input) return; // Elide all but the first overload return cleanup(createProperty(/*decorators*/undefined, ensureModifiers(input), input.name, /*questionToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined)); } @@ -901,7 +901,7 @@ namespace ts { /*decorators*/ undefined, ensureModifiers(input), input.name, - updateAccessorParamsList(input, hasModifier(input, ModifierFlags.Private)), + updateAccessorParamsList(input, hasEffectiveModifier(input, ModifierFlags.Private)), ensureType(input, accessorType), /*body*/ undefined)); } @@ -914,7 +914,7 @@ namespace ts { /*decorators*/ undefined, ensureModifiers(input), input.name, - updateAccessorParamsList(input, hasModifier(input, ModifierFlags.Private)), + updateAccessorParamsList(input, hasEffectiveModifier(input, ModifierFlags.Private)), /*body*/ undefined)); } case SyntaxKind.PropertyDeclaration: @@ -1041,7 +1041,7 @@ namespace ts { } function isPrivateMethodTypeParameter(node: TypeParameterDeclaration) { - return node.parent.kind === SyntaxKind.MethodDeclaration && hasModifier(node.parent, ModifierFlags.Private); + return node.parent.kind === SyntaxKind.MethodDeclaration && hasEffectiveModifier(node.parent, ModifierFlags.Private); } function visitDeclarationStatements(input: Node): VisitResult { @@ -1096,13 +1096,13 @@ namespace ts { } function stripExportModifiers(statement: Statement): Statement { - if (isImportEqualsDeclaration(statement) || hasModifier(statement, ModifierFlags.Default)) { + if (isImportEqualsDeclaration(statement) || hasEffectiveModifier(statement, ModifierFlags.Default)) { // `export import` statements should remain as-is, as imports are _not_ implicitly exported in an ambient namespace // Likewise, `export default` classes and the like and just be `default`, so we preserve their `export` modifiers, too return statement; } const clone = getMutableClone(statement); - const modifiers = createModifiersFromModifierFlags(getModifierFlags(statement) & (ModifierFlags.All ^ ModifierFlags.Export)); + const modifiers = createModifiersFromModifierFlags(getEffectiveModifierFlags(statement) & (ModifierFlags.All ^ ModifierFlags.Export)); clone.modifiers = modifiers.length ? createNodeArray(modifiers) : undefined; return clone; } @@ -1188,11 +1188,11 @@ namespace ts { }); const namespaceDecl = createModuleDeclaration(/*decorators*/ undefined, ensureModifiers(input), input.name!, createModuleBlock(declarations), NodeFlags.Namespace); - if (!hasModifier(clean, ModifierFlags.Default)) { + if (!hasEffectiveModifier(clean, ModifierFlags.Default)) { return [clean, namespaceDecl]; } - const modifiers = createModifiersFromModifierFlags((getModifierFlags(clean) & ~ModifierFlags.ExportDefault) | ModifierFlags.Ambient); + const modifiers = createModifiersFromModifierFlags((getEffectiveModifierFlags(clean) & ~ModifierFlags.ExportDefault) | ModifierFlags.Ambient); const cleanDeclaration = updateFunctionDeclaration( clean, /*decorators*/ undefined, @@ -1295,7 +1295,7 @@ namespace ts { if (ctor) { const oldDiag = getSymbolAccessibilityDiagnostic; parameterProperties = compact(flatMap(ctor.parameters, (param) => { - if (!hasModifier(param, ModifierFlags.ParameterPropertyModifier) || shouldStripInternal(param)) return; + if (!hasSyntacticModifier(param, ModifierFlags.ParameterPropertyModifier) || shouldStripInternal(param)) return; getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(param); if (param.name.kind === SyntaxKind.Identifier) { return preserveJsDoc(createProperty( @@ -1482,7 +1482,7 @@ namespace ts { } function ensureModifiers(node: Node): readonly Modifier[] | undefined { - const currentFlags = getModifierFlags(node); + const currentFlags = getEffectiveModifierFlags(node); const newFlags = ensureModifierFlags(node); if (currentFlags === newFlags) { return node.modifiers; @@ -1536,7 +1536,7 @@ namespace ts { } function maskModifierFlags(node: Node, modifierMask: ModifierFlags = ModifierFlags.All ^ ModifierFlags.Public, modifierAdditions: ModifierFlags = ModifierFlags.None): ModifierFlags { - let flags = (getModifierFlags(node) & modifierMask) | modifierAdditions; + let flags = (getEffectiveModifierFlags(node) & modifierMask) | modifierAdditions; if (flags & ModifierFlags.Default && !(flags & ModifierFlags.Export)) { // A non-exported default is a nonsequitor - we usually try to remove all export modifiers // from statements in ambient declarations; but a default export must retain its export modifier to be syntactically valid @@ -1563,7 +1563,7 @@ namespace ts { switch (node.kind) { case SyntaxKind.PropertyDeclaration: case SyntaxKind.PropertySignature: - return !hasModifier(node, ModifierFlags.Private); + return !hasEffectiveModifier(node, ModifierFlags.Private); case SyntaxKind.Parameter: case SyntaxKind.VariableDeclaration: return true; diff --git a/src/compiler/transformers/declarations/diagnostics.ts b/src/compiler/transformers/declarations/diagnostics.ts index ac44f7efd15e5..1294739ef961b 100644 --- a/src/compiler/transformers/declarations/diagnostics.ts +++ b/src/compiler/transformers/declarations/diagnostics.ts @@ -71,7 +71,7 @@ namespace ts { } function getAccessorNameVisibilityDiagnosticMessage(symbolAccessibilityResult: SymbolAccessibilityResult) { - if (hasModifier(node, ModifierFlags.Static)) { + if (hasSyntacticModifier(node, ModifierFlags.Static)) { return symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : @@ -102,7 +102,7 @@ namespace ts { } function getMethodNameVisibilityDiagnosticMessage(symbolAccessibilityResult: SymbolAccessibilityResult) { - if (hasModifier(node, ModifierFlags.Static)) { + if (hasSyntacticModifier(node, ModifierFlags.Static)) { return symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? Diagnostics.Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : @@ -135,7 +135,7 @@ namespace ts { return getReturnTypeVisibilityError; } else if (isParameter(node)) { - if (isParameterPropertyDeclaration(node, node.parent) && hasModifier(node.parent, ModifierFlags.Private)) { + if (isParameterPropertyDeclaration(node, node.parent) && hasSyntacticModifier(node.parent, ModifierFlags.Private)) { return getVariableDeclarationTypeVisibilityError; } return getParameterDeclarationTypeVisibilityError; @@ -167,9 +167,9 @@ namespace ts { // This check is to ensure we don't report error on constructor parameter property as that error would be reported during parameter emit // The only exception here is if the constructor was marked as private. we are not emitting the constructor parameters at all. else if (node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertyAccessExpression || node.kind === SyntaxKind.PropertySignature || - (node.kind === SyntaxKind.Parameter && hasModifier(node.parent, ModifierFlags.Private))) { + (node.kind === SyntaxKind.Parameter && hasSyntacticModifier(node.parent, ModifierFlags.Private))) { // TODO(jfreeman): Deal with computed properties in error reporting. - if (hasModifier(node, ModifierFlags.Static)) { + if (hasSyntacticModifier(node, ModifierFlags.Static)) { return symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : @@ -206,7 +206,7 @@ namespace ts { if (node.kind === SyntaxKind.SetAccessor) { // Getters can infer the return type from the returned expression, but setters cannot, so the // "_from_external_module_1_but_cannot_be_named" case cannot occur. - if (hasModifier(node, ModifierFlags.Static)) { + if (hasSyntacticModifier(node, ModifierFlags.Static)) { diagnosticMessage = symbolAccessibilityResult.errorModuleName ? Diagnostics.Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_private_name_1; @@ -218,7 +218,7 @@ namespace ts { } } else { - if (hasModifier(node, ModifierFlags.Static)) { + if (hasSyntacticModifier(node, ModifierFlags.Static)) { diagnosticMessage = symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? Diagnostics.Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : @@ -266,7 +266,7 @@ namespace ts { case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: - if (hasModifier(node, ModifierFlags.Static)) { + if (hasSyntacticModifier(node, ModifierFlags.Static)) { diagnosticMessage = symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named : @@ -345,7 +345,7 @@ namespace ts { case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: - if (hasModifier(node.parent, ModifierFlags.Static)) { + if (hasSyntacticModifier(node.parent, ModifierFlags.Static)) { return symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : @@ -413,7 +413,7 @@ namespace ts { case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: - if (hasModifier(node.parent, ModifierFlags.Static)) { + if (hasSyntacticModifier(node.parent, ModifierFlags.Static)) { diagnosticMessage = Diagnostics.Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1; } else if (node.parent.parent.kind === SyntaxKind.ClassDeclaration) { diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 3e2e88d15c2d0..d4a42cfb18684 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -681,8 +681,8 @@ namespace ts { statements.push(statement); // Add an `export default` statement for default exports (for `--target es5 --module es6`) - if (hasModifier(node, ModifierFlags.Export)) { - const exportStatement = hasModifier(node, ModifierFlags.Default) + if (hasSyntacticModifier(node, ModifierFlags.Export)) { + const exportStatement = hasSyntacticModifier(node, ModifierFlags.Default) ? createExportDefault(getLocalName(node)) : createExternalModuleExport(getLocalName(node)); @@ -1804,7 +1804,7 @@ namespace ts { function transformFunctionLikeToExpression(node: FunctionLikeDeclaration, location: TextRange | undefined, name: Identifier | undefined, container: Node | undefined): FunctionExpression { const savedConvertedLoopState = convertedLoopState; convertedLoopState = undefined; - const ancestorFacts = container && isClassLike(container) && !hasModifier(node, ModifierFlags.Static) + const ancestorFacts = container && isClassLike(container) && !hasSyntacticModifier(node, ModifierFlags.Static) ? enterSubtree(HierarchyFacts.FunctionExcludes, HierarchyFacts.FunctionIncludes | HierarchyFacts.NonStaticClassElement) : enterSubtree(HierarchyFacts.FunctionExcludes, HierarchyFacts.FunctionIncludes); const parameters = visitParameterList(node.parameters, visitor, context); @@ -2011,7 +2011,7 @@ namespace ts { } function visitVariableStatement(node: VariableStatement): Statement | undefined { - const ancestorFacts = enterSubtree(HierarchyFacts.None, hasModifier(node, ModifierFlags.Export) ? HierarchyFacts.ExportedVariableStatement : HierarchyFacts.None); + const ancestorFacts = enterSubtree(HierarchyFacts.None, hasSyntacticModifier(node, ModifierFlags.Export) ? HierarchyFacts.ExportedVariableStatement : HierarchyFacts.None); let updated: Statement | undefined; if (convertedLoopState && (node.declarationList.flags & NodeFlags.BlockScoped) === 0 && !isVariableStatementOfTypeScriptClassWrapper(node)) { // we are inside a converted loop - hoist variable declarations @@ -4257,7 +4257,7 @@ namespace ts { } function getClassMemberPrefix(node: ClassExpression | ClassDeclaration, member: ClassElement) { - return hasModifier(member, ModifierFlags.Static) + return hasSyntacticModifier(member, ModifierFlags.Static) ? getInternalName(node) : createPropertyAccess(getInternalName(node), "prototype"); } diff --git a/src/compiler/transformers/es2018.ts b/src/compiler/transformers/es2018.ts index 16d67fcef380d..585ec59241e7d 100644 --- a/src/compiler/transformers/es2018.ts +++ b/src/compiler/transformers/es2018.ts @@ -486,7 +486,7 @@ namespace ts { } function visitVariableStatement(node: VariableStatement): VisitResult { - if (hasModifier(node, ModifierFlags.Export)) { + if (hasSyntacticModifier(node, ModifierFlags.Export)) { const savedExportedVariableStatement = exportedVariableStatement; exportedVariableStatement = true; const visited = visitEachChild(node, visitor, context); diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 2bb81ff255cc2..85b18b4f7b58b 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -895,7 +895,7 @@ namespace ts { let statements: Statement[] | undefined; if (moduleKind !== ModuleKind.AMD) { - if (hasModifier(node, ModifierFlags.Export)) { + if (hasSyntacticModifier(node, ModifierFlags.Export)) { statements = append(statements, setOriginalNode( setTextRange( @@ -934,7 +934,7 @@ namespace ts { } } else { - if (hasModifier(node, ModifierFlags.Export)) { + if (hasSyntacticModifier(node, ModifierFlags.Export)) { statements = append(statements, setOriginalNode( setTextRange( @@ -1095,7 +1095,7 @@ namespace ts { */ function visitFunctionDeclaration(node: FunctionDeclaration): VisitResult { let statements: Statement[] | undefined; - if (hasModifier(node, ModifierFlags.Export)) { + if (hasSyntacticModifier(node, ModifierFlags.Export)) { statements = append(statements, setOriginalNode( setTextRange( @@ -1138,7 +1138,7 @@ namespace ts { */ function visitClassDeclaration(node: ClassDeclaration): VisitResult { let statements: Statement[] | undefined; - if (hasModifier(node, ModifierFlags.Export)) { + if (hasSyntacticModifier(node, ModifierFlags.Export)) { statements = append(statements, setOriginalNode( setTextRange( @@ -1182,7 +1182,7 @@ namespace ts { let variables: VariableDeclaration[] | undefined; let expressions: Expression[] | undefined; - if (hasModifier(node, ModifierFlags.Export)) { + if (hasSyntacticModifier(node, ModifierFlags.Export)) { let modifiers: NodeArray | undefined; // If we're exporting these variables, then these just become assignments to 'exports.x'. @@ -1442,8 +1442,8 @@ namespace ts { return statements; } - if (hasModifier(decl, ModifierFlags.Export)) { - const exportName = hasModifier(decl, ModifierFlags.Default) ? createIdentifier("default") : getDeclarationName(decl); + if (hasSyntacticModifier(decl, ModifierFlags.Export)) { + const exportName = hasSyntacticModifier(decl, ModifierFlags.Default) ? createIdentifier("default") : getDeclarationName(decl); statements = appendExportStatement(statements, exportName, getLocalName(decl), /*location*/ decl); } diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index a198164078cec..6d0a7ee6b523b 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -693,7 +693,7 @@ namespace ts { * @param node The node to visit. */ function visitFunctionDeclaration(node: FunctionDeclaration): VisitResult { - if (hasModifier(node, ModifierFlags.Export)) { + if (hasSyntacticModifier(node, ModifierFlags.Export)) { hoistedStatements = append(hoistedStatements, updateFunctionDeclaration( node, @@ -780,7 +780,7 @@ namespace ts { } let expressions: Expression[] | undefined; - const isExportedDeclaration = hasModifier(node, ModifierFlags.Export); + const isExportedDeclaration = hasSyntacticModifier(node, ModifierFlags.Export); const isMarkedDeclaration = hasAssociatedEndOfDeclarationMarker(node); for (const variable of node.declarationList.declarations) { if (variable.initializer) { @@ -911,7 +911,7 @@ namespace ts { // statement until we visit this declaration's `EndOfDeclarationMarker`. if (hasAssociatedEndOfDeclarationMarker(node) && node.original!.kind === SyntaxKind.VariableStatement) { const id = getOriginalNodeId(node); - const isExportedDeclaration = hasModifier(node.original!, ModifierFlags.Export); + const isExportedDeclaration = hasSyntacticModifier(node.original!, ModifierFlags.Export); deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], node.original, isExportedDeclaration); } @@ -1087,8 +1087,8 @@ namespace ts { } let excludeName: string | undefined; - if (hasModifier(decl, ModifierFlags.Export)) { - const exportName = hasModifier(decl, ModifierFlags.Default) ? createLiteral("default") : decl.name!; + if (hasSyntacticModifier(decl, ModifierFlags.Export)) { + const exportName = hasSyntacticModifier(decl, ModifierFlags.Default) ? createLiteral("default") : decl.name!; statements = appendExportStatement(statements, exportName, getLocalName(decl)); excludeName = getTextOfIdentifierOrLiteral(exportName); } diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 0ef7db0627219..7f848685aec36 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -166,7 +166,7 @@ namespace ts { case SyntaxKind.ClassDeclaration: case SyntaxKind.FunctionDeclaration: - if (hasModifier(node, ModifierFlags.Ambient)) { + if (hasSyntacticModifier(node, ModifierFlags.Ambient)) { break; } @@ -178,7 +178,7 @@ namespace ts { // These nodes should always have names unless they are default-exports; // however, class declaration parsing allows for undefined names, so syntactically invalid // programs may also have an undefined name. - Debug.assert(node.kind === SyntaxKind.ClassDeclaration || hasModifier(node, ModifierFlags.Default)); + Debug.assert(node.kind === SyntaxKind.ClassDeclaration || hasSyntacticModifier(node, ModifierFlags.Default)); } if (isClassDeclaration(node)) { // XXX: should probably also cover interfaces and type aliases that can have type variables? @@ -287,7 +287,7 @@ namespace ts { // do not emit ES6 imports and exports since they are illegal inside a namespace return undefined; } - else if (node.transformFlags & TransformFlags.ContainsTypeScript || hasModifier(node, ModifierFlags.Export)) { + else if (node.transformFlags & TransformFlags.ContainsTypeScript || hasSyntacticModifier(node, ModifierFlags.Export)) { return visitTypeScript(node); } @@ -349,7 +349,7 @@ namespace ts { * @param node The node to visit. */ function visitTypeScript(node: Node): VisitResult { - if (isStatement(node) && hasModifier(node, ModifierFlags.Ambient)) { + if (isStatement(node) && hasSyntacticModifier(node, ModifierFlags.Ambient)) { // TypeScript ambient declarations are elided, but some comments may be preserved. // See the implementation of `getLeadingComments` in comments.ts for more details. return createNotEmittedStatement(node); @@ -610,7 +610,7 @@ namespace ts { } function visitClassDeclaration(node: ClassDeclaration): VisitResult { - if (!isClassLikeDeclarationWithTypeScriptSyntax(node) && !(currentNamespace && hasModifier(node, ModifierFlags.Export))) { + if (!isClassLikeDeclarationWithTypeScriptSyntax(node) && !(currentNamespace && hasSyntacticModifier(node, ModifierFlags.Export))) { return visitEachChild(node, visitor, context); } @@ -966,7 +966,7 @@ namespace ts { */ function isDecoratedClassElement(member: ClassElement, isStatic: boolean, parent: ClassLikeDeclaration) { return nodeOrChildIsDecorated(member, parent) - && isStatic === hasModifier(member, ModifierFlags.Static); + && isStatic === hasSyntacticModifier(member, ModifierFlags.Static); } /** @@ -2045,7 +2045,7 @@ namespace ts { * @param node The declaration node. */ function shouldEmitAccessorDeclaration(node: AccessorDeclaration) { - return !(nodeIsMissing(node.body) && hasModifier(node, ModifierFlags.Abstract)); + return !(nodeIsMissing(node.body) && hasSyntacticModifier(node, ModifierFlags.Abstract)); } function visitGetAccessor(node: GetAccessorDeclaration) { @@ -2352,7 +2352,7 @@ namespace ts { const containerName = getNamespaceContainerName(node); // `exportName` is the expression used within this node's container for any exported references. - const exportName = hasModifier(node, ModifierFlags.Export) + const exportName = hasSyntacticModifier(node, ModifierFlags.Export) ? getExternalModuleOrNamespaceExportName(currentNamespaceContainerName, node, /*allowComments*/ false, /*allowSourceMaps*/ true) : getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true); @@ -2653,7 +2653,7 @@ namespace ts { const containerName = getNamespaceContainerName(node); // `exportName` is the expression used within this node's container for any exported references. - const exportName = hasModifier(node, ModifierFlags.Export) + const exportName = hasSyntacticModifier(node, ModifierFlags.Export) ? getExternalModuleOrNamespaceExportName(currentNamespaceContainerName, node, /*allowComments*/ false, /*allowSourceMaps*/ true) : getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true); @@ -3039,7 +3039,7 @@ namespace ts { * @param node The node to test. */ function isExportOfNamespace(node: Node) { - return currentNamespace !== undefined && hasModifier(node, ModifierFlags.Export); + return currentNamespace !== undefined && hasSyntacticModifier(node, ModifierFlags.Export); } /** @@ -3048,7 +3048,7 @@ namespace ts { * @param node The node to test. */ function isExternalModuleExport(node: Node) { - return currentNamespace === undefined && hasModifier(node, ModifierFlags.Export); + return currentNamespace === undefined && hasSyntacticModifier(node, ModifierFlags.Export); } /** @@ -3058,7 +3058,7 @@ namespace ts { */ function isNamedExternalModuleExport(node: Node) { return isExternalModuleExport(node) - && !hasModifier(node, ModifierFlags.Default); + && !hasSyntacticModifier(node, ModifierFlags.Default); } /** @@ -3068,7 +3068,7 @@ namespace ts { */ function isDefaultExternalModuleExport(node: Node) { return isExternalModuleExport(node) - && hasModifier(node, ModifierFlags.Default); + && hasSyntacticModifier(node, ModifierFlags.Default); } /** @@ -3147,7 +3147,7 @@ namespace ts { } function getClassMemberPrefix(node: ClassExpression | ClassDeclaration, member: ClassElement) { - return hasModifier(member, ModifierFlags.Static) + return hasSyntacticModifier(member, ModifierFlags.Static) ? getDeclarationName(node) : getClassPrototype(node); } diff --git a/src/compiler/transformers/utilities.ts b/src/compiler/transformers/utilities.ts index a602d6c04868b..4a4dc05de76a7 100644 --- a/src/compiler/transformers/utilities.ts +++ b/src/compiler/transformers/utilities.ts @@ -143,7 +143,7 @@ namespace ts { break; case SyntaxKind.VariableStatement: - if (hasModifier(node, ModifierFlags.Export)) { + if (hasSyntacticModifier(node, ModifierFlags.Export)) { for (const decl of (node).declarationList.declarations) { exportedNames = collectExportedVariableInfo(decl, uniqueExports, exportedNames); } @@ -151,8 +151,8 @@ namespace ts { break; case SyntaxKind.FunctionDeclaration: - if (hasModifier(node, ModifierFlags.Export)) { - if (hasModifier(node, ModifierFlags.Default)) { + if (hasSyntacticModifier(node, ModifierFlags.Export)) { + if (hasSyntacticModifier(node, ModifierFlags.Default)) { // export default function() { } if (!hasExportDefault) { multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), getDeclarationName(node)); @@ -172,8 +172,8 @@ namespace ts { break; case SyntaxKind.ClassDeclaration: - if (hasModifier(node, ModifierFlags.Export)) { - if (hasModifier(node, ModifierFlags.Default)) { + if (hasSyntacticModifier(node, ModifierFlags.Export)) { + if (hasSyntacticModifier(node, ModifierFlags.Default)) { // export default class { } if (!hasExportDefault) { multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), getDeclarationName(node)); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 72c6dcfd79fb6..54d889b2ff4fc 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -609,6 +609,7 @@ namespace ts { Async = 1 << 8, // Property/Method/Function Default = 1 << 9, // Function/Class (export default declaration) Const = 1 << 11, // Const enum + HasComputedJSDocModifiers = 1 << 12, // Indicates the computed modifier flags include modifiers from JSDoc. HasComputedFlags = 1 << 29, // Modifier flags have been computed AccessibilityModifier = Public | Private | Protected, diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 07613e301fa38..17ce0562122e0 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1370,8 +1370,8 @@ namespace ts { export function isValidESSymbolDeclaration(node: Node): node is VariableDeclaration | PropertyDeclaration | SignatureDeclaration { return isVariableDeclaration(node) ? isVarConst(node) && isIdentifier(node.name) && isVariableDeclarationInVariableStatement(node) : - isPropertyDeclaration(node) ? hasReadonlyModifier(node) && hasStaticModifier(node) : - isPropertySignature(node) && hasReadonlyModifier(node); + isPropertyDeclaration(node) ? hasEffectiveReadonlyModifier(node) && hasStaticModifier(node) : + isPropertySignature(node) && hasEffectiveReadonlyModifier(node); } export function introducesArgumentsExoticObject(node: Node) { @@ -2471,7 +2471,7 @@ namespace ts { : undefined; } - export function getJSDocCommentsAndTags(hostNode: Node): readonly (JSDoc | JSDocTag)[] { + export function getJSDocCommentsAndTags(hostNode: Node, noCache?: boolean): readonly (JSDoc | JSDocTag)[] { let result: (JSDoc | JSDocTag)[] | undefined; // Pull parameter comments from declaring function as well if (isVariableLike(hostNode) && hasInitializer(hostNode) && hasJSDocNodes(hostNode.initializer!)) { @@ -2485,11 +2485,11 @@ namespace ts { } if (node.kind === SyntaxKind.Parameter) { - result = addRange(result, getJSDocParameterTags(node as ParameterDeclaration)); + result = addRange(result, (noCache ? getJSDocParameterTagsNoCache : getJSDocParameterTags)(node as ParameterDeclaration)); break; } if (node.kind === SyntaxKind.TypeParameter) { - result = addRange(result, getJSDocTypeParameterTags(node as TypeParameterDeclaration)); + result = addRange(result, (noCache ? getJSDocTypeParameterTagsNoCache : getJSDocTypeParameterTags)(node as TypeParameterDeclaration)); break; } node = getNextJSDocCommentLocation(node); @@ -3007,7 +3007,7 @@ namespace ts { // falls through case SyntaxKind.ArrowFunction: - if (hasModifier(node, ModifierFlags.Async)) { + if (hasSyntacticModifier(node, ModifierFlags.Async)) { flags |= FunctionFlags.Async; } break; @@ -3028,7 +3028,7 @@ namespace ts { case SyntaxKind.MethodDeclaration: return (node).body !== undefined && (node).asteriskToken === undefined - && hasModifier(node, ModifierFlags.Async); + && hasSyntacticModifier(node, ModifierFlags.Async); } return false; } @@ -4017,7 +4017,7 @@ namespace ts { else { forEach(declarations, member => { if (isAccessor(member) - && hasModifier(member, ModifierFlags.Static) === hasModifier(accessor, ModifierFlags.Static)) { + && hasSyntacticModifier(member, ModifierFlags.Static) === hasSyntacticModifier(accessor, ModifierFlags.Static)) { const memberName = getPropertyNameForPropertyNameNode(member.name); const accessorName = getPropertyNameForPropertyNameNode(accessor.name); if (memberName === accessorName) { @@ -4312,61 +4312,112 @@ namespace ts { return currentLineIndent; } - export function hasModifiers(node: Node) { - return getModifierFlags(node) !== ModifierFlags.None; + export function hasEffectiveModifiers(node: Node) { + return getEffectiveModifierFlags(node) !== ModifierFlags.None; } - export function hasModifier(node: Node, flags: ModifierFlags): boolean { - return !!getSelectedModifierFlags(node, flags); + export function hasSyntacticModifiers(node: Node) { + return getSyntacticModifierFlags(node) !== ModifierFlags.None; + } + + export function hasEffectiveModifier(node: Node, flags: ModifierFlags): boolean { + return !!getSelectedEffectiveModifierFlags(node, flags); + } + + export function hasSyntacticModifier(node: Node, flags: ModifierFlags): boolean { + return !!getSelectedSyntacticModifierFlags(node, flags); } export function hasStaticModifier(node: Node): boolean { - return hasModifier(node, ModifierFlags.Static); + return hasSyntacticModifier(node, ModifierFlags.Static); + } + + export function hasEffectiveReadonlyModifier(node: Node): boolean { + return hasEffectiveModifier(node, ModifierFlags.Readonly); } - export function hasReadonlyModifier(node: Node): boolean { - return hasModifier(node, ModifierFlags.Readonly); + export function getSelectedEffectiveModifierFlags(node: Node, flags: ModifierFlags): ModifierFlags { + return getEffectiveModifierFlags(node) & flags; } - export function getSelectedModifierFlags(node: Node, flags: ModifierFlags): ModifierFlags { - return getModifierFlags(node) & flags; + export function getSelectedSyntacticModifierFlags(node: Node, flags: ModifierFlags): ModifierFlags { + return getSyntacticModifierFlags(node) & flags; } - export function getModifierFlags(node: Node): ModifierFlags { + function getModifierFlagsWorker(node: Node, includeJSDoc: boolean): ModifierFlags { if (node.kind >= SyntaxKind.FirstToken && node.kind <= SyntaxKind.LastToken) { return ModifierFlags.None; } - if (node.modifierFlagsCache & ModifierFlags.HasComputedFlags) { - return node.modifierFlagsCache & ~ModifierFlags.HasComputedFlags; + + if (!(node.modifierFlagsCache & ModifierFlags.HasComputedFlags)) { + node.modifierFlagsCache = getSyntacticModifierFlagsNoCache(node) | ModifierFlags.HasComputedFlags; } - const flags = getModifierFlagsNoCache(node); - node.modifierFlagsCache = flags | ModifierFlags.HasComputedFlags; - return flags; + if (includeJSDoc && !(node.modifierFlagsCache & ModifierFlags.HasComputedJSDocModifiers) && isInJSFile(node) && node.parent) { + node.modifierFlagsCache |= getJSDocModifierFlagsNoCache(node) | ModifierFlags.HasComputedJSDocModifiers; + } + + return node.modifierFlagsCache & ~(ModifierFlags.HasComputedFlags | ModifierFlags.HasComputedJSDocModifiers); + } + + /** + * Gets the effective ModifierFlags for the provided node, including JSDoc modifiers. The modifiers will be cached on the node to improve performance. + * + * NOTE: This function may use `parent` pointers. + */ + export function getEffectiveModifierFlags(node: Node): ModifierFlags { + return getModifierFlagsWorker(node, /*includeJSDoc*/ true); + } + + /** + * Gets the ModifierFlags for syntactic modifiers on the provided node. The modifiers will be cached on the node to improve performance. + * + * NOTE: This function does not use `parent` pointers and will not include modifiers from JSDoc. + */ + export function getSyntacticModifierFlags(node: Node): ModifierFlags { + return getModifierFlagsWorker(node, /*includeJSDoc*/ false); } - export function getModifierFlagsNoCache(node: Node): ModifierFlags { + function getJSDocModifierFlagsNoCache(node: Node): ModifierFlags { let flags = ModifierFlags.None; - if (node.modifiers) { - for (const modifier of node.modifiers) { - flags |= modifierToFlag(modifier.kind); - } + if (isInJSFile(node) && !!node.parent && !isParameter(node)) { + if (getJSDocPublicTagNoCache(node)) flags |= ModifierFlags.Public; + if (getJSDocPrivateTagNoCache(node)) flags |= ModifierFlags.Private; + if (getJSDocProtectedTagNoCache(node)) flags |= ModifierFlags.Protected; + if (getJSDocReadonlyTagNoCache(node)) flags |= ModifierFlags.Readonly; } + return flags; + } - if (isInJSFile(node) && !!node.parent) { - // getModifierFlagsNoCache should only be called when parent pointers are set, - // or when !(node.flags & NodeFlags.Synthesized) && node.kind !== SyntaxKind.SourceFile) - const tags = (getJSDocPublicTag(node) ? ModifierFlags.Public : ModifierFlags.None) - | (getJSDocPrivateTag(node) ? ModifierFlags.Private : ModifierFlags.None) - | (getJSDocProtectedTag(node) ? ModifierFlags.Protected : ModifierFlags.None) - | (getJSDocReadonlyTag(node) ? ModifierFlags.Readonly : ModifierFlags.None); - flags |= tags; - } + /** + * Gets the effective ModifierFlags for the provided node, including JSDoc modifiers. The modifier flags cache on the node is ignored. + * + * NOTE: This function may use `parent` pointers. + */ + export function getEffectiveModifierFlagsNoCache(node: Node): ModifierFlags { + return getSyntacticModifierFlagsNoCache(node) | getJSDocModifierFlagsNoCache(node); + } + /** + * Gets the ModifierFlags for syntactic modifiers on the provided node. The modifier flags cache on the node is ignored. + * + * NOTE: This function does not use `parent` pointers and will not include modifiers from JSDoc. + */ + export function getSyntacticModifierFlagsNoCache(node: Node): ModifierFlags { + let flags = modifiersToFlags(node.modifiers); if (node.flags & NodeFlags.NestedNamespace || (node.kind === SyntaxKind.Identifier && (node).isInJSDocNamespace)) { flags |= ModifierFlags.Export; } + return flags; + } + export function modifiersToFlags(modifiers: NodeArray | undefined) { + let flags = ModifierFlags.None; + if (modifiers) { + for (const modifier of modifiers) { + flags |= modifierToFlag(modifier.kind); + } + } return flags; } @@ -4507,7 +4558,7 @@ namespace ts { } function isExportDefaultSymbol(symbol: Symbol): boolean { - return symbol && length(symbol.declarations) > 0 && hasModifier(symbol.declarations[0], ModifierFlags.Default); + return symbol && length(symbol.declarations) > 0 && hasSyntacticModifier(symbol.declarations[0], ModifierFlags.Default); } /** Return ".ts", ".d.ts", or ".tsx", if that is the extension. */ @@ -5055,7 +5106,7 @@ namespace ts { export function isAbstractConstructorSymbol(symbol: Symbol): boolean { if (symbol.flags & SymbolFlags.Class) { const declaration = getClassLikeDeclarationOfSymbol(symbol); - return !!declaration && hasModifier(declaration, ModifierFlags.Abstract); + return !!declaration && hasSyntacticModifier(declaration, ModifierFlags.Abstract); } return false; } @@ -6365,7 +6416,7 @@ namespace ts { if (node.kind !== SyntaxKind.ComputedPropertyName) { return false; } - if (hasModifier(node.parent, ModifierFlags.Abstract)) { + if (hasSyntacticModifier(node.parent, ModifierFlags.Abstract)) { return true; } const containerKind = node.parent.parent.kind; diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index d38187b406a5d..0da9f34ecec82 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -255,7 +255,7 @@ namespace ts { export type ParameterPropertyDeclaration = ParameterDeclaration & { parent: ConstructorDeclaration, name: Identifier }; export function isParameterPropertyDeclaration(node: Node, parent: Node): node is ParameterPropertyDeclaration { - return hasModifier(node, ModifierFlags.ParameterPropertyModifier) && parent.kind === SyntaxKind.Constructor; + return hasSyntacticModifier(node, ModifierFlags.ParameterPropertyModifier) && parent.kind === SyntaxKind.Constructor; } export function isEmptyBindingPattern(node: BindingName): node is BindingPattern { @@ -299,7 +299,7 @@ namespace ts { } export function getCombinedModifierFlags(node: Declaration): ModifierFlags { - return getCombinedFlags(node, getModifierFlags); + return getCombinedFlags(node, getEffectiveModifierFlags); } // Returns the node flags for this node and all relevant parent nodes. This is done so that @@ -609,28 +609,16 @@ namespace ts { } } - /** - * Gets the JSDoc parameter tags for the node if present. - * - * @remarks Returns any JSDoc param tag whose name matches the provided - * parameter, whether a param tag on a containing function - * expression, or a param tag on a variable declaration whose - * initializer is the containing function. The tags closest to the - * node are returned first, so in the previous example, the param - * tag on the containing function expression would be first. - * - * For binding patterns, parameter tags are matched by position. - */ - export function getJSDocParameterTags(param: ParameterDeclaration): readonly JSDocParameterTag[] { + function getJSDocParameterTagsWorker(param: ParameterDeclaration, noCache?: boolean): readonly JSDocParameterTag[] { if (param.name) { if (isIdentifier(param.name)) { const name = param.name.escapedText; - return getJSDocTags(param.parent).filter((tag): tag is JSDocParameterTag => isJSDocParameterTag(tag) && isIdentifier(tag.name) && tag.name.escapedText === name); + return getJSDocTagsWorker(param.parent, noCache).filter((tag): tag is JSDocParameterTag => isJSDocParameterTag(tag) && isIdentifier(tag.name) && tag.name.escapedText === name); } else { const i = param.parent.parameters.indexOf(param); Debug.assert(i > -1, "Parameters should always be in their parents' parameter list"); - const paramTags = getJSDocTags(param.parent).filter(isJSDocParameterTag); + const paramTags = getJSDocTagsWorker(param.parent, noCache).filter(isJSDocParameterTag); if (i < paramTags.length) { return [paramTags[i]]; } @@ -640,6 +628,33 @@ namespace ts { return emptyArray; } + /** + * Gets the JSDoc parameter tags for the node if present. + * + * @remarks Returns any JSDoc param tag whose name matches the provided + * parameter, whether a param tag on a containing function + * expression, or a param tag on a variable declaration whose + * initializer is the containing function. The tags closest to the + * node are returned first, so in the previous example, the param + * tag on the containing function expression would be first. + * + * For binding patterns, parameter tags are matched by position. + */ + export function getJSDocParameterTags(param: ParameterDeclaration): readonly JSDocParameterTag[] { + return getJSDocParameterTagsWorker(param, /*noCache*/ false); + } + + /* @internal */ + export function getJSDocParameterTagsNoCache(param: ParameterDeclaration): readonly JSDocParameterTag[] { + return getJSDocParameterTagsWorker(param, /*noCache*/ true); + } + + function getJSDocTypeParameterTagsWorker(param: TypeParameterDeclaration, noCache?: boolean): readonly JSDocTemplateTag[] { + const name = param.name.escapedText; + return getJSDocTagsWorker(param.parent, noCache).filter((tag): tag is JSDocTemplateTag => + isJSDocTemplateTag(tag) && tag.typeParameters.some(tp => tp.name.escapedText === name)); + } + /** * Gets the JSDoc type parameter tags for the node if present. * @@ -651,9 +666,12 @@ namespace ts { * tag on the containing function expression would be first. */ export function getJSDocTypeParameterTags(param: TypeParameterDeclaration): readonly JSDocTemplateTag[] { - const name = param.name.escapedText; - return getJSDocTags(param.parent).filter((tag): tag is JSDocTemplateTag => - isJSDocTemplateTag(tag) && tag.typeParameters.some(tp => tp.name.escapedText === name)); + return getJSDocTypeParameterTagsWorker(param, /*noCache*/ false); + } + + /* @internal */ + export function getJSDocTypeParameterTagsNoCache(param: TypeParameterDeclaration): readonly JSDocTemplateTag[] { + return getJSDocTypeParameterTagsWorker(param, /*noCache*/ true); } /** @@ -686,21 +704,41 @@ namespace ts { return getFirstJSDocTag(node, isJSDocPublicTag); } + /*@internal*/ + export function getJSDocPublicTagNoCache(node: Node): JSDocPublicTag | undefined { + return getFirstJSDocTag(node, isJSDocPublicTag, /*noCache*/ true); + } + /** Gets the JSDoc private tag for the node if present */ export function getJSDocPrivateTag(node: Node): JSDocPrivateTag | undefined { return getFirstJSDocTag(node, isJSDocPrivateTag); } + /*@internal*/ + export function getJSDocPrivateTagNoCache(node: Node): JSDocPrivateTag | undefined { + return getFirstJSDocTag(node, isJSDocPrivateTag, /*noCache*/ true); + } + /** Gets the JSDoc protected tag for the node if present */ export function getJSDocProtectedTag(node: Node): JSDocProtectedTag | undefined { return getFirstJSDocTag(node, isJSDocProtectedTag); } + /*@internal*/ + export function getJSDocProtectedTagNoCache(node: Node): JSDocProtectedTag | undefined { + return getFirstJSDocTag(node, isJSDocProtectedTag, /*noCache*/ true); + } + /** Gets the JSDoc protected tag for the node if present */ export function getJSDocReadonlyTag(node: Node): JSDocReadonlyTag | undefined { return getFirstJSDocTag(node, isJSDocReadonlyTag); } + /*@internal*/ + export function getJSDocReadonlyTagNoCache(node: Node): JSDocReadonlyTag | undefined { + return getFirstJSDocTag(node, isJSDocReadonlyTag, /*noCache*/ true); + } + /** Gets the JSDoc enum tag for the node if present */ export function getJSDocEnumTag(node: Node): JSDocEnumTag | undefined { return getFirstJSDocTag(node, isJSDocEnumTag); @@ -775,21 +813,33 @@ namespace ts { } } - /** Get all JSDoc tags related to a node, including those on parent nodes. */ - export function getJSDocTags(node: Node): readonly JSDocTag[] { + function getJSDocTagsWorker(node: Node, noCache?: boolean): readonly JSDocTag[] { let tags = (node as JSDocContainer).jsDocCache; // If cache is 'null', that means we did the work of searching for JSDoc tags and came up with nothing. - if (tags === undefined) { - const comments = getJSDocCommentsAndTags(node); + if (tags === undefined || noCache) { + const comments = getJSDocCommentsAndTags(node, noCache); Debug.assert(comments.length < 2 || comments[0] !== comments[1]); - (node as JSDocContainer).jsDocCache = tags = flatMap(comments, j => isJSDoc(j) ? j.tags : j); + tags = flatMap(comments, j => isJSDoc(j) ? j.tags : j); + if (!noCache) { + (node as JSDocContainer).jsDocCache = tags; + } } return tags; } + /** Get all JSDoc tags related to a node, including those on parent nodes. */ + export function getJSDocTags(node: Node): readonly JSDocTag[] { + return getJSDocTagsWorker(node, /*noCache*/ false); + } + + /* @internal */ + export function getJSDocTagsNoCache(node: Node): readonly JSDocTag[] { + return getJSDocTagsWorker(node, /*noCache*/ true); + } + /** Get the first JSDoc tag of a specified kind, or undefined if not present. */ - function getFirstJSDocTag(node: Node, predicate: (tag: JSDocTag) => tag is T): T | undefined { - return find(getJSDocTags(node), predicate); + function getFirstJSDocTag(node: Node, predicate: (tag: JSDocTag) => tag is T, noCache?: boolean): T | undefined { + return find(getJSDocTagsWorker(node, noCache), predicate); } /** Gets all JSDoc tags that match a specified predicate */ @@ -2235,13 +2285,13 @@ namespace ts { /* @internal */ export function needsScopeMarker(result: Statement) { - return !isAnyImportOrReExport(result) && !isExportAssignment(result) && !hasModifier(result, ModifierFlags.Export) && !isAmbientModule(result); + return !isAnyImportOrReExport(result) && !isExportAssignment(result) && !hasSyntacticModifier(result, ModifierFlags.Export) && !isAmbientModule(result); } /* @internal */ export function isExternalModuleIndicator(result: Statement) { // Exported top-level member indicates moduleness - return isAnyImportOrReExport(result) || isExportAssignment(result) || hasModifier(result, ModifierFlags.Export); + return isAnyImportOrReExport(result) || isExportAssignment(result) || hasSyntacticModifier(result, ModifierFlags.Export); } /* @internal */ diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index c119eff97dee1..f1144b3eb3530 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -684,7 +684,7 @@ namespace ts { function aggregateTransformFlagsForSubtree(node: Node): TransformFlags { // We do not transform ambient declarations or types, so there is no need to // recursively aggregate transform flags. - if (hasModifier(node, ModifierFlags.Ambient) || (isTypeNode(node) && node.kind !== SyntaxKind.ExpressionWithTypeArguments)) { + if (hasSyntacticModifier(node, ModifierFlags.Ambient) || (isTypeNode(node) && node.kind !== SyntaxKind.ExpressionWithTypeArguments)) { return TransformFlags.None; } diff --git a/src/services/breakpoints.ts b/src/services/breakpoints.ts index 81e76a939d761..eee180ffe144f 100644 --- a/src/services/breakpoints.ts +++ b/src/services/breakpoints.ts @@ -392,7 +392,7 @@ namespace ts.BreakpointResolver { // Breakpoint is possible in variableDeclaration only if there is initialization // or its declaration from 'for of' if (variableDeclaration.initializer || - hasModifier(variableDeclaration, ModifierFlags.Export) || + hasSyntacticModifier(variableDeclaration, ModifierFlags.Export) || parent.parent.kind === SyntaxKind.ForOfStatement) { return textSpanFromVariableDeclaration(variableDeclaration); } @@ -410,7 +410,7 @@ namespace ts.BreakpointResolver { function canHaveSpanInParameterDeclaration(parameter: ParameterDeclaration): boolean { // Breakpoint is possible on parameter only if it has initializer, is a rest parameter, or has public or private modifier return !!parameter.initializer || parameter.dotDotDotToken !== undefined || - hasModifier(parameter, ModifierFlags.Public | ModifierFlags.Private); + hasSyntacticModifier(parameter, ModifierFlags.Public | ModifierFlags.Private); } function spanInParameterDeclaration(parameter: ParameterDeclaration): TextSpan | undefined { @@ -437,7 +437,7 @@ namespace ts.BreakpointResolver { } function canFunctionHaveSpanInWholeDeclaration(functionDeclaration: FunctionLikeDeclaration) { - return hasModifier(functionDeclaration, ModifierFlags.Export) || + return hasSyntacticModifier(functionDeclaration, ModifierFlags.Export) || (functionDeclaration.parent.kind === SyntaxKind.ClassDeclaration && functionDeclaration.kind !== SyntaxKind.Constructor); } diff --git a/src/services/callHierarchy.ts b/src/services/callHierarchy.ts index 3a114af16ef13..bbf28ac8f1101 100644 --- a/src/services/callHierarchy.ts +++ b/src/services/callHierarchy.ts @@ -410,7 +410,7 @@ namespace ts.CallHierarchy { } function collectCallSitesOfModuleDeclaration(node: ModuleDeclaration, collect: (node: Node | undefined) => void) { - if (!hasModifier(node, ModifierFlags.Ambient) && node.body && isModuleBlock(node.body)) { + if (!hasSyntacticModifier(node, ModifierFlags.Ambient) && node.body && isModuleBlock(node.body)) { forEach(node.body.statements, collect); } } diff --git a/src/services/codefixes/addMissingAsync.ts b/src/services/codefixes/addMissingAsync.ts index 59b0f2f279da4..2f2ceba35703e 100644 --- a/src/services/codefixes/addMissingAsync.ts +++ b/src/services/codefixes/addMissingAsync.ts @@ -53,7 +53,7 @@ namespace ts.codefix { } fixedDeclarations?.set(getNodeId(insertionSite).toString(), true); const cloneWithModifier = getSynthesizedDeepClone(insertionSite, /*includeTrivia*/ true); - cloneWithModifier.modifiers = createNodeArray(createModifiersFromModifierFlags(getModifierFlags(insertionSite) | ModifierFlags.Async)); + cloneWithModifier.modifiers = createNodeArray(createModifiersFromModifierFlags(getSyntacticModifierFlags(insertionSite) | ModifierFlags.Async)); cloneWithModifier.modifierFlagsCache = 0; changeTracker.replaceNode( sourceFile, diff --git a/src/services/codefixes/addMissingAwait.ts b/src/services/codefixes/addMissingAwait.ts index fa562d77e8d49..89c6e6d267fb9 100644 --- a/src/services/codefixes/addMissingAwait.ts +++ b/src/services/codefixes/addMissingAwait.ts @@ -148,7 +148,7 @@ namespace ts.codefix { declaration.type || !declaration.initializer || variableStatement.getSourceFile() !== sourceFile || - hasModifier(variableStatement, ModifierFlags.Export) || + hasSyntacticModifier(variableStatement, ModifierFlags.Export) || !variableName || !isInsideAwaitableBody(declaration.initializer)) { isCompleteFix = false; diff --git a/src/services/codefixes/convertToMappedObjectType.ts b/src/services/codefixes/convertToMappedObjectType.ts index 0d79d6363c0ae..04de31faabf67 100644 --- a/src/services/codefixes/convertToMappedObjectType.ts +++ b/src/services/codefixes/convertToMappedObjectType.ts @@ -42,7 +42,7 @@ namespace ts.codefix { const parameter = first(indexSignature.parameters); const mappedTypeParameter = createTypeParameterDeclaration(cast(parameter.name, isIdentifier), parameter.type); const mappedIntersectionType = createMappedTypeNode( - hasReadonlyModifier(indexSignature) ? createModifier(SyntaxKind.ReadonlyKeyword) : undefined, + hasEffectiveReadonlyModifier(indexSignature) ? createModifier(SyntaxKind.ReadonlyKeyword) : undefined, mappedTypeParameter, indexSignature.questionToken, indexSignature.type); diff --git a/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts b/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts index a27ded9d403f8..eac02f0d7135a 100644 --- a/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts +++ b/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts @@ -49,7 +49,7 @@ namespace ts.codefix { function symbolPointsToNonPrivateAndAbstractMember(symbol: Symbol): boolean { // See `codeFixClassExtendAbstractProtectedProperty.ts` in https://github.com/Microsoft/TypeScript/pull/11547/files // (now named `codeFixClassExtendAbstractPrivateProperty.ts`) - const flags = getModifierFlags(first(symbol.getDeclarations()!)); + const flags = getSyntacticModifierFlags(first(symbol.getDeclarations()!)); return !(flags & ModifierFlags.Private) && !!(flags & ModifierFlags.Abstract); } } diff --git a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts index 4059ee03ca7bd..954a64ef53dcd 100644 --- a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts +++ b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts @@ -34,7 +34,7 @@ namespace ts.codefix { } function symbolPointsToNonPrivateMember(symbol: Symbol) { - return !symbol.valueDeclaration || !(getModifierFlags(symbol.valueDeclaration) & ModifierFlags.Private); + return !symbol.valueDeclaration || !(getEffectiveModifierFlags(symbol.valueDeclaration) & ModifierFlags.Private); } function addMissingDeclarations( diff --git a/src/services/codefixes/fixStrictClassInitialization.ts b/src/services/codefixes/fixStrictClassInitialization.ts index f3286246e164b..a4b0134853a30 100644 --- a/src/services/codefixes/fixStrictClassInitialization.ts +++ b/src/services/codefixes/fixStrictClassInitialization.ts @@ -120,7 +120,7 @@ namespace ts.codefix { } else if (type.isClass()) { const classDeclaration = getClassLikeDeclarationOfSymbol(type.symbol); - if (!classDeclaration || hasModifier(classDeclaration, ModifierFlags.Abstract)) return undefined; + if (!classDeclaration || hasSyntacticModifier(classDeclaration, ModifierFlags.Abstract)) return undefined; const constructorDeclaration = getFirstConstructorWithBody(classDeclaration); if (constructorDeclaration && constructorDeclaration.parameters.length) return undefined; diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 4e9c3a9c5a7b7..7e879b96ba6d6 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -40,7 +40,7 @@ namespace ts.codefix { const scriptTarget = getEmitScriptTarget(context.program.getCompilerOptions()); const declaration = declarations[0]; const name = getSynthesizedDeepClone(getNameOfDeclaration(declaration), /*includeTrivia*/ false) as PropertyName; - const visibilityModifier = createVisibilityModifier(getModifierFlags(declaration)); + const visibilityModifier = createVisibilityModifier(getEffectiveModifierFlags(declaration)); const modifiers = visibilityModifier ? createNodeArray([visibilityModifier]) : undefined; const type = checker.getWidenedType(checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration)); const optional = !!(symbol.flags & SymbolFlags.Optional); diff --git a/src/services/completions.ts b/src/services/completions.ts index a1e98a03d8708..5224e90d2ea8f 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1990,7 +1990,7 @@ namespace ts.Completions { if (!isClassLike(decl)) return GlobalsSearch.Success; const classElement = contextToken.kind === SyntaxKind.SemicolonToken ? contextToken.parent.parent : contextToken.parent; - let classElementModifierFlags = isClassElement(classElement) ? getModifierFlags(classElement) : ModifierFlags.None; + let classElementModifierFlags = isClassElement(classElement) ? getEffectiveModifierFlags(classElement) : ModifierFlags.None; // If this is context token is not something we are editing now, consider if this would lead to be modifier if (contextToken.kind === SyntaxKind.Identifier && !isCurrentlyEditingNode(contextToken)) { switch (contextToken.getText()) { @@ -2409,12 +2409,12 @@ namespace ts.Completions { } // Dont filter member even if the name matches if it is declared private in the list - if (hasModifier(m, ModifierFlags.Private)) { + if (hasEffectiveModifier(m, ModifierFlags.Private)) { continue; } // do not filter it out if the static presence doesnt match - if (hasModifier(m, ModifierFlags.Static) !== !!(currentClassElementModifierFlags & ModifierFlags.Static)) { + if (hasEffectiveModifier(m, ModifierFlags.Static) !== !!(currentClassElementModifierFlags & ModifierFlags.Static)) { continue; } diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index f79abf7343774..74dffc3b00b11 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -102,7 +102,7 @@ namespace ts.FindAllReferences { ((isImportOrExportSpecifier(node.parent) || isBindingElement(node.parent)) && node.parent.propertyName === node) || // Is default export - (node.kind === SyntaxKind.DefaultKeyword && hasModifier(node.parent, ModifierFlags.ExportDefault))) { + (node.kind === SyntaxKind.DefaultKeyword && hasSyntacticModifier(node.parent, ModifierFlags.ExportDefault))) { return getContextNode(node.parent); } @@ -1146,7 +1146,7 @@ namespace ts.FindAllReferences { // If this is private property or method, the scope is the containing class if (flags & (SymbolFlags.Property | SymbolFlags.Method)) { - const privateDeclaration = find(declarations, d => hasModifier(d, ModifierFlags.Private) || isPrivateIdentifierPropertyDeclaration(d)); + const privateDeclaration = find(declarations, d => hasEffectiveModifier(d, ModifierFlags.Private) || isPrivateIdentifierPropertyDeclaration(d)); if (privateDeclaration) { return getAncestor(privateDeclaration, SyntaxKind.ClassDeclaration); } @@ -1561,7 +1561,7 @@ namespace ts.FindAllReferences { Debug.assert(classLike.name === referenceLocation); const addRef = state.referenceAdder(search.symbol); for (const member of classLike.members) { - if (!(isMethodOrAccessor(member) && hasModifier(member, ModifierFlags.Static))) { + if (!(isMethodOrAccessor(member) && hasSyntacticModifier(member, ModifierFlags.Static))) { continue; } if (member.body) { @@ -1776,7 +1776,7 @@ namespace ts.FindAllReferences { case SyntaxKind.Constructor: case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: - staticFlag &= getModifierFlags(searchSpaceNode); + staticFlag &= getSyntacticModifierFlags(searchSpaceNode); searchSpaceNode = searchSpaceNode.parent; // re-assign to be the owning class break; default: @@ -1794,7 +1794,7 @@ namespace ts.FindAllReferences { // If we have a 'super' container, we must have an enclosing class. // Now make sure the owning class is the same as the search-space // and has the same static qualifier as the original 'super's owner. - return container && (ModifierFlags.Static & getModifierFlags(container)) === staticFlag && container.parent.symbol === searchSpaceNode.symbol ? nodeEntry(node) : undefined; + return container && (ModifierFlags.Static & getSyntacticModifierFlags(container)) === staticFlag && container.parent.symbol === searchSpaceNode.symbol ? nodeEntry(node) : undefined; }); return [{ definition: { type: DefinitionKind.Symbol, symbol: searchSpaceNode.symbol }, references }]; @@ -1822,7 +1822,7 @@ namespace ts.FindAllReferences { case SyntaxKind.Constructor: case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: - staticFlag &= getModifierFlags(searchSpaceNode); + staticFlag &= getSyntacticModifierFlags(searchSpaceNode); searchSpaceNode = searchSpaceNode.parent; // re-assign to be the owning class break; case SyntaxKind.SourceFile: @@ -1857,7 +1857,7 @@ namespace ts.FindAllReferences { case SyntaxKind.ClassDeclaration: // Make sure the container belongs to the same class // and has the appropriate static modifier from the original container. - return container.parent && searchSpaceNode.symbol === container.parent.symbol && (getModifierFlags(container) & ModifierFlags.Static) === staticFlag; + return container.parent && searchSpaceNode.symbol === container.parent.symbol && (getSyntacticModifierFlags(container) & ModifierFlags.Static) === staticFlag; case SyntaxKind.SourceFile: return container.kind === SyntaxKind.SourceFile && !isExternalModule(container) && !isParameterName(node); } diff --git a/src/services/importTracker.ts b/src/services/importTracker.ts index 91b53ea418a19..6b3da6edc8936 100644 --- a/src/services/importTracker.ts +++ b/src/services/importTracker.ts @@ -103,7 +103,7 @@ namespace ts.FindAllReferences { break; // TODO: GH#23879 case SyntaxKind.ImportEqualsDeclaration: - handleNamespaceImport(direct, direct.name, hasModifier(direct, ModifierFlags.Export), /*alreadyAddedDirect*/ false); + handleNamespaceImport(direct, direct.name, hasSyntacticModifier(direct, ModifierFlags.Export), /*alreadyAddedDirect*/ false); break; case SyntaxKind.ImportDeclaration: @@ -463,7 +463,7 @@ namespace ts.FindAllReferences { } else { const exportNode = getExportNode(parent, node); - if (exportNode && hasModifier(exportNode, ModifierFlags.Export)) { + if (exportNode && hasSyntacticModifier(exportNode, ModifierFlags.Export)) { if (isImportEqualsDeclaration(exportNode) && exportNode.moduleReference === node) { // We're at `Y` in `export import X = Y`. This is not the exported symbol, the left-hand-side is. So treat this as an import statement. if (comingFromExport) { @@ -553,7 +553,7 @@ namespace ts.FindAllReferences { // Not meant for use with export specifiers or export assignment. function getExportKindForDeclaration(node: Node): ExportKind { - return hasModifier(node, ModifierFlags.Default) ? ExportKind.Default : ExportKind.Named; + return hasSyntacticModifier(node, ModifierFlags.Default) ? ExportKind.Default : ExportKind.Named; } } diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 38faf25da7f99..b74da7fd8dabc 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -590,7 +590,7 @@ namespace ts.NavigationBar { case SyntaxKind.MethodDeclaration: case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: - return hasModifier(a, ModifierFlags.Static) === hasModifier(b, ModifierFlags.Static); + return hasSyntacticModifier(a, ModifierFlags.Static) === hasSyntacticModifier(b, ModifierFlags.Static); case SyntaxKind.ModuleDeclaration: return areSameModule(a, b); default: @@ -690,7 +690,7 @@ namespace ts.NavigationBar { case SyntaxKind.FunctionExpression: case SyntaxKind.ClassDeclaration: case SyntaxKind.ClassExpression: - if (getModifierFlags(node) & ModifierFlags.Default) { + if (getSyntacticModifierFlags(node) & ModifierFlags.Default) { return "default"; } // We may get a string with newlines or other whitespace in the case of an object dereference @@ -883,7 +883,7 @@ namespace ts.NavigationBar { return nodeText(parent.name); } // Default exports are named "default" - else if (getModifierFlags(node) & ModifierFlags.Default) { + else if (getSyntacticModifierFlags(node) & ModifierFlags.Default) { return "default"; } else if (isClassLike(node)) { diff --git a/src/services/refactors/convertExport.ts b/src/services/refactors/convertExport.ts index c08ae05bce8af..18de048ac6c3e 100644 --- a/src/services/refactors/convertExport.ts +++ b/src/services/refactors/convertExport.ts @@ -38,7 +38,7 @@ namespace ts.refactor { const exportingModuleSymbol = isSourceFile(exportNode.parent) ? exportNode.parent.symbol : exportNode.parent.parent.symbol; - const flags = getModifierFlags(exportNode); + const flags = getSyntacticModifierFlags(exportNode); const wasDefault = !!(flags & ModifierFlags.Default); // If source file already has a default export, don't offer refactor. if (!(flags & ModifierFlags.Export) || !wasDefault && exportingModuleSymbol.exports!.has(InternalSymbolName.Default)) { diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index 64e9bb6f3a2c8..9df13e93d7e92 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -309,7 +309,7 @@ namespace ts.refactor.extractSymbol { let current: Node = nodeToCheck; while (current !== containingClass) { if (current.kind === SyntaxKind.PropertyDeclaration) { - if (hasModifier(current, ModifierFlags.Static)) { + if (hasSyntacticModifier(current, ModifierFlags.Static)) { rangeFacts |= RangeFacts.InStaticRegion; } break; @@ -322,7 +322,7 @@ namespace ts.refactor.extractSymbol { break; } else if (current.kind === SyntaxKind.MethodDeclaration) { - if (hasModifier(current, ModifierFlags.Static)) { + if (hasSyntacticModifier(current, ModifierFlags.Static)) { rangeFacts |= RangeFacts.InStaticRegion; } } @@ -375,7 +375,7 @@ namespace ts.refactor.extractSymbol { if (isDeclaration(node)) { const declaringNode = (node.kind === SyntaxKind.VariableDeclaration) ? node.parent.parent : node; - if (hasModifier(declaringNode, ModifierFlags.Export)) { + if (hasSyntacticModifier(declaringNode, ModifierFlags.Export)) { // TODO: GH#18217 Silly to use `errors ||` since it's definitely not defined (see top of `visit`) // Also, if we're only pushing one error, just use `let error: Diagnostic | undefined`! // Also TODO: GH#19956 @@ -1584,7 +1584,7 @@ namespace ts.refactor.extractSymbol { hasWrite = true; if (value.symbol.flags & SymbolFlags.ClassMember && value.symbol.valueDeclaration && - hasModifier(value.symbol.valueDeclaration, ModifierFlags.Readonly)) { + hasEffectiveModifier(value.symbol.valueDeclaration, ModifierFlags.Readonly)) { readonlyClassPropertyWrite = value.symbol.valueDeclaration; } } diff --git a/src/services/refactors/generateGetAccessorAndSetAccessor.ts b/src/services/refactors/generateGetAccessorAndSetAccessor.ts index 038cd04cdeb45..df1799e336adb 100644 --- a/src/services/refactors/generateGetAccessorAndSetAccessor.ts +++ b/src/services/refactors/generateGetAccessorAndSetAccessor.ts @@ -52,7 +52,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { const isInClassLike = isClassLike(container); // avoid Readonly modifier because it will convert to get accessor - const modifierFlags = getModifierFlags(declaration) & ~ModifierFlags.Readonly; + const modifierFlags = getEffectiveModifierFlags(declaration) & ~ModifierFlags.Readonly; const accessorModifiers = isInClassLike ? !modifierFlags || modifierFlags & ModifierFlags.Private ? getModifiers(isJS, isStatic, SyntaxKind.PublicKeyword) @@ -121,7 +121,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { // make sure declaration have AccessibilityModifier or Static Modifier or Readonly Modifier const meaning = ModifierFlags.AccessibilityModifier | ModifierFlags.Static | ModifierFlags.Readonly; if (!declaration || !nodeOverlapsWithStartEnd(declaration.name, file, startPosition, endPosition!) // TODO: GH#18217 - || !isConvertibleName(declaration.name) || (getModifierFlags(declaration) | meaning) !== meaning) return undefined; + || !isConvertibleName(declaration.name) || (getEffectiveModifierFlags(declaration) | meaning) !== meaning) return undefined; const name = declaration.name.text; const startWithUnderscore = startsWithUnderscore(name); @@ -129,7 +129,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { const accessorName = createPropertyName(startWithUnderscore ? getUniqueName(name.substring(1), file) : name, declaration.name); return { isStatic: hasStaticModifier(declaration), - isReadonly: hasReadonlyModifier(declaration), + isReadonly: hasEffectiveReadonlyModifier(declaration), type: getTypeAnnotationNode(declaration), container: declaration.kind === SyntaxKind.Parameter ? declaration.parent.parent : declaration.parent, originalName: (declaration.name).text, diff --git a/src/services/refactors/moveToNewFile.ts b/src/services/refactors/moveToNewFile.ts index e714315f31395..7737a5cc8dfa4 100644 --- a/src/services/refactors/moveToNewFile.ts +++ b/src/services/refactors/moveToNewFile.ts @@ -84,7 +84,7 @@ namespace ts.refactor { case SyntaxKind.ImportDeclaration: return true; case SyntaxKind.ImportEqualsDeclaration: - return !hasModifier(node, ModifierFlags.Export); + return !hasSyntacticModifier(node, ModifierFlags.Export); case SyntaxKind.VariableStatement: return (node as VariableStatement).declarationList.declarations.every(d => !!d.initializer && isRequireCall(d.initializer, /*checkArgumentIsStringLiteralLike*/ true)); default: @@ -420,7 +420,7 @@ namespace ts.refactor { if (markSeenTop(top)) { addExportToChanges(oldFile, top, changes, useEs6ModuleSyntax); } - if (hasModifier(decl, ModifierFlags.Default)) { + if (hasSyntacticModifier(decl, ModifierFlags.Default)) { oldFileDefault = name; } else { @@ -737,7 +737,7 @@ namespace ts.refactor { function isExported(sourceFile: SourceFile, decl: TopLevelDeclarationStatement, useEs6Exports: boolean): boolean { if (useEs6Exports) { - return !isExpressionStatement(decl) && hasModifier(decl, ModifierFlags.Export); + return !isExpressionStatement(decl) && hasSyntacticModifier(decl, ModifierFlags.Export); } else { return getNamesToExportInCommonJS(decl).some(name => sourceFile.symbol.exports!.has(escapeLeadingUnderscores(name))); diff --git a/src/services/services.ts b/src/services/services.ts index 0ad6ea996e7e5..f50d99e55d1a3 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -763,7 +763,7 @@ namespace ts { case SyntaxKind.Parameter: // Only consider parameter properties - if (!hasModifier(node, ModifierFlags.ParameterPropertyModifier)) { + if (!hasSyntacticModifier(node, ModifierFlags.ParameterPropertyModifier)) { break; } // falls through diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index c9af01faef896..138ed53c50d0b 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -389,7 +389,7 @@ namespace ts.SymbolDisplay { if (declarationName) { const isExternalModuleDeclaration = isModuleWithStringLiteralName(resolvedNode) && - hasModifier(resolvedNode, ModifierFlags.Ambient); + hasSyntacticModifier(resolvedNode, ModifierFlags.Ambient); const shouldUseAliasName = symbol.name !== "default" && !isExternalModuleDeclaration; const resolvedInfo = getSymbolDisplayPartsDocumentationAndSymbolKind( typeChecker, diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 58f53198f7905..617855c584a92 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -407,7 +407,7 @@ namespace ts { case SyntaxKind.Constructor: return ScriptElementKind.constructorImplementationElement; case SyntaxKind.TypeParameter: return ScriptElementKind.typeParameterElement; case SyntaxKind.EnumMember: return ScriptElementKind.enumMemberElement; - case SyntaxKind.Parameter: return hasModifier(node, ModifierFlags.ParameterPropertyModifier) ? ScriptElementKind.memberVariableElement : ScriptElementKind.parameterElement; + case SyntaxKind.Parameter: return hasSyntacticModifier(node, ModifierFlags.ParameterPropertyModifier) ? ScriptElementKind.memberVariableElement : ScriptElementKind.parameterElement; case SyntaxKind.ImportEqualsDeclaration: case SyntaxKind.ImportSpecifier: case SyntaxKind.ExportSpecifier: diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index b898d160f4845..4e2ef188c6b39 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -482,6 +482,7 @@ declare namespace ts { Async = 256, Default = 512, Const = 2048, + HasComputedJSDocModifiers = 4096, HasComputedFlags = 536870912, AccessibilityModifier = 28, ParameterPropertyModifier = 92, diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index f1a808da72863..c901f86e38499 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -482,6 +482,7 @@ declare namespace ts { Async = 256, Default = 512, Const = 2048, + HasComputedJSDocModifiers = 4096, HasComputedFlags = 536870912, AccessibilityModifier = 28, ParameterPropertyModifier = 92, diff --git a/tests/baselines/reference/jsdocAccessibilityTagsDeclarations.js b/tests/baselines/reference/jsdocAccessibilityTagsDeclarations.js index 18031abf9cafc..b7e4cd93941e7 100644 --- a/tests/baselines/reference/jsdocAccessibilityTagsDeclarations.js +++ b/tests/baselines/reference/jsdocAccessibilityTagsDeclarations.js @@ -30,7 +30,12 @@ class Private { /** @private */ set p(value) { this.c = value } } - + +// https://github.com/microsoft/TypeScript/issues/38401 +class C { + constructor(/** @public */ x, /** @protected */ y, /** @private */ z) { + } +} //// [foo.js] class Protected { @@ -63,6 +68,11 @@ class Private { /** @private */ set p(value) { this.c = value; } } +// https://github.com/microsoft/TypeScript/issues/38401 +class C { + constructor(/** @public */ x, /** @protected */ y, /** @private */ z) { + } +} //// [foo.d.ts] @@ -90,3 +100,6 @@ declare class Private { /** @private */ private get p(); } +declare class C { + constructor(x: any, y: any, z: any); +} diff --git a/tests/baselines/reference/jsdocAccessibilityTagsDeclarations.symbols b/tests/baselines/reference/jsdocAccessibilityTagsDeclarations.symbols index 0316e157d31fa..d9961837e7a67 100644 --- a/tests/baselines/reference/jsdocAccessibilityTagsDeclarations.symbols +++ b/tests/baselines/reference/jsdocAccessibilityTagsDeclarations.symbols @@ -79,3 +79,13 @@ class Private { >value : Symbol(value, Decl(jsdocAccessibilityTagDeclarations.js, 29, 10)) } +// https://github.com/microsoft/TypeScript/issues/38401 +class C { +>C : Symbol(C, Decl(jsdocAccessibilityTagDeclarations.js, 30, 1)) + + constructor(/** @public */ x, /** @protected */ y, /** @private */ z) { +>x : Symbol(x, Decl(jsdocAccessibilityTagDeclarations.js, 34, 16)) +>y : Symbol(y, Decl(jsdocAccessibilityTagDeclarations.js, 34, 33)) +>z : Symbol(z, Decl(jsdocAccessibilityTagDeclarations.js, 34, 54)) + } +} diff --git a/tests/baselines/reference/jsdocAccessibilityTagsDeclarations.types b/tests/baselines/reference/jsdocAccessibilityTagsDeclarations.types index 88c6acd855d4e..3db28ea64d98f 100644 --- a/tests/baselines/reference/jsdocAccessibilityTagsDeclarations.types +++ b/tests/baselines/reference/jsdocAccessibilityTagsDeclarations.types @@ -83,3 +83,13 @@ class Private { >value : any } +// https://github.com/microsoft/TypeScript/issues/38401 +class C { +>C : C + + constructor(/** @public */ x, /** @protected */ y, /** @private */ z) { +>x : any +>y : any +>z : any + } +} diff --git a/tests/baselines/reference/jsdocReadonlyDeclarations.js b/tests/baselines/reference/jsdocReadonlyDeclarations.js index 09568ef6b196f..e4ed7a7df4e0a 100644 --- a/tests/baselines/reference/jsdocReadonlyDeclarations.js +++ b/tests/baselines/reference/jsdocReadonlyDeclarations.js @@ -18,7 +18,11 @@ function F() { /** @readonly */ this.z = 1 } - + +// https://github.com/microsoft/TypeScript/issues/38401 +class D { + constructor(/** @readonly */ x) {} +} //// [foo.js] class C { @@ -39,6 +43,10 @@ function F() { /** @readonly */ this.z = 1; } +// https://github.com/microsoft/TypeScript/issues/38401 +class D { + constructor(/** @readonly */ x) { } +} //// [foo.d.ts] @@ -58,3 +66,6 @@ declare class C { */ readonly y: number; } +declare class D { + constructor(x: any); +} diff --git a/tests/baselines/reference/jsdocReadonlyDeclarations.symbols b/tests/baselines/reference/jsdocReadonlyDeclarations.symbols index 29ac14063dc86..97c9d3d3ef3b8 100644 --- a/tests/baselines/reference/jsdocReadonlyDeclarations.symbols +++ b/tests/baselines/reference/jsdocReadonlyDeclarations.symbols @@ -40,3 +40,10 @@ function F() { >z : Symbol(F.z, Decl(jsdocReadonlyDeclarations.js, 15, 14)) } +// https://github.com/microsoft/TypeScript/issues/38401 +class D { +>D : Symbol(D, Decl(jsdocReadonlyDeclarations.js, 18, 1)) + + constructor(/** @readonly */ x) {} +>x : Symbol(x, Decl(jsdocReadonlyDeclarations.js, 22, 16)) +} diff --git a/tests/baselines/reference/jsdocReadonlyDeclarations.types b/tests/baselines/reference/jsdocReadonlyDeclarations.types index ebb5fd00ff14c..10e0a99c05e21 100644 --- a/tests/baselines/reference/jsdocReadonlyDeclarations.types +++ b/tests/baselines/reference/jsdocReadonlyDeclarations.types @@ -48,3 +48,10 @@ function F() { >1 : 1 } +// https://github.com/microsoft/TypeScript/issues/38401 +class D { +>D : D + + constructor(/** @readonly */ x) {} +>x : any +} diff --git a/tests/baselines/reference/uniqueSymbolsDeclarationsInJs.js b/tests/baselines/reference/uniqueSymbolsDeclarationsInJs.js new file mode 100644 index 0000000000000..2ff4da1f22acc --- /dev/null +++ b/tests/baselines/reference/uniqueSymbolsDeclarationsInJs.js @@ -0,0 +1,76 @@ +//// [uniqueSymbolsDeclarationsInJs.js] +// classes +class C { + /** + * @readonly + */ + static readonlyStaticCall = Symbol(); + /** + * @type {unique symbol} + * @readonly + */ + static readonlyStaticType; + /** + * @type {unique symbol} + * @readonly + */ + static readonlyStaticTypeAndCall = Symbol(); + static readwriteStaticCall = Symbol(); + + /** + * @readonly + */ + readonlyCall = Symbol(); + readwriteCall = Symbol(); +} + + +//// [uniqueSymbolsDeclarationsInJs-out.js] +// classes +let C = /** @class */ (() => { + class C { + constructor() { + /** + * @readonly + */ + this.readonlyCall = Symbol(); + this.readwriteCall = Symbol(); + } + } + /** + * @readonly + */ + C.readonlyStaticCall = Symbol(); + /** + * @type {unique symbol} + * @readonly + */ + C.readonlyStaticTypeAndCall = Symbol(); + C.readwriteStaticCall = Symbol(); + return C; +})(); + + +//// [uniqueSymbolsDeclarationsInJs-out.d.ts] +declare class C { + /** + * @readonly + */ + static readonly readonlyStaticCall: unique symbol; + /** + * @type {unique symbol} + * @readonly + */ + static readonly readonlyStaticType: unique symbol; + /** + * @type {unique symbol} + * @readonly + */ + static readonly readonlyStaticTypeAndCall: unique symbol; + static readwriteStaticCall: symbol; + /** + * @readonly + */ + readonly readonlyCall: symbol; + readwriteCall: symbol; +} diff --git a/tests/baselines/reference/uniqueSymbolsDeclarationsInJs.symbols b/tests/baselines/reference/uniqueSymbolsDeclarationsInJs.symbols new file mode 100644 index 0000000000000..b48c5cc6c58cc --- /dev/null +++ b/tests/baselines/reference/uniqueSymbolsDeclarationsInJs.symbols @@ -0,0 +1,43 @@ +=== tests/cases/conformance/types/uniqueSymbol/uniqueSymbolsDeclarationsInJs.js === +// classes +class C { +>C : Symbol(C, Decl(uniqueSymbolsDeclarationsInJs.js, 0, 0)) + + /** + * @readonly + */ + static readonlyStaticCall = Symbol(); +>readonlyStaticCall : Symbol(C.readonlyStaticCall, Decl(uniqueSymbolsDeclarationsInJs.js, 1, 9)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) + + /** + * @type {unique symbol} + * @readonly + */ + static readonlyStaticType; +>readonlyStaticType : Symbol(C.readonlyStaticType, Decl(uniqueSymbolsDeclarationsInJs.js, 5, 41)) + + /** + * @type {unique symbol} + * @readonly + */ + static readonlyStaticTypeAndCall = Symbol(); +>readonlyStaticTypeAndCall : Symbol(C.readonlyStaticTypeAndCall, Decl(uniqueSymbolsDeclarationsInJs.js, 10, 30)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) + + static readwriteStaticCall = Symbol(); +>readwriteStaticCall : Symbol(C.readwriteStaticCall, Decl(uniqueSymbolsDeclarationsInJs.js, 15, 48)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) + + /** + * @readonly + */ + readonlyCall = Symbol(); +>readonlyCall : Symbol(C.readonlyCall, Decl(uniqueSymbolsDeclarationsInJs.js, 16, 42)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) + + readwriteCall = Symbol(); +>readwriteCall : Symbol(C.readwriteCall, Decl(uniqueSymbolsDeclarationsInJs.js, 21, 28)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) +} + diff --git a/tests/baselines/reference/uniqueSymbolsDeclarationsInJs.types b/tests/baselines/reference/uniqueSymbolsDeclarationsInJs.types new file mode 100644 index 0000000000000..a51ba3c324dcf --- /dev/null +++ b/tests/baselines/reference/uniqueSymbolsDeclarationsInJs.types @@ -0,0 +1,48 @@ +=== tests/cases/conformance/types/uniqueSymbol/uniqueSymbolsDeclarationsInJs.js === +// classes +class C { +>C : C + + /** + * @readonly + */ + static readonlyStaticCall = Symbol(); +>readonlyStaticCall : unique symbol +>Symbol() : unique symbol +>Symbol : SymbolConstructor + + /** + * @type {unique symbol} + * @readonly + */ + static readonlyStaticType; +>readonlyStaticType : symbol + + /** + * @type {unique symbol} + * @readonly + */ + static readonlyStaticTypeAndCall = Symbol(); +>readonlyStaticTypeAndCall : symbol +>Symbol() : unique symbol +>Symbol : SymbolConstructor + + static readwriteStaticCall = Symbol(); +>readwriteStaticCall : symbol +>Symbol() : symbol +>Symbol : SymbolConstructor + + /** + * @readonly + */ + readonlyCall = Symbol(); +>readonlyCall : symbol +>Symbol() : symbol +>Symbol : SymbolConstructor + + readwriteCall = Symbol(); +>readwriteCall : symbol +>Symbol() : symbol +>Symbol : SymbolConstructor +} + diff --git a/tests/baselines/reference/uniqueSymbolsDeclarationsInJsErrors.errors.txt b/tests/baselines/reference/uniqueSymbolsDeclarationsInJsErrors.errors.txt new file mode 100644 index 0000000000000..16120be782ba0 --- /dev/null +++ b/tests/baselines/reference/uniqueSymbolsDeclarationsInJsErrors.errors.txt @@ -0,0 +1,24 @@ +tests/cases/conformance/types/uniqueSymbol/uniqueSymbolsDeclarationsInJsErrors.js(5,12): error TS1331: A property of a class whose type is a 'unique symbol' type must be both 'static' and 'readonly'. +tests/cases/conformance/types/uniqueSymbol/uniqueSymbolsDeclarationsInJsErrors.js(14,12): error TS1331: A property of a class whose type is a 'unique symbol' type must be both 'static' and 'readonly'. + + +==== tests/cases/conformance/types/uniqueSymbol/uniqueSymbolsDeclarationsInJsErrors.js (2 errors) ==== + class C { + /** + * @type {unique symbol} + */ + static readwriteStaticType; + ~~~~~~~~~~~~~~~~~~~ +!!! error TS1331: A property of a class whose type is a 'unique symbol' type must be both 'static' and 'readonly'. + /** + * @type {unique symbol} + * @readonly + */ + static readonlyType; + /** + * @type {unique symbol} + */ + static readwriteType; + ~~~~~~~~~~~~~ +!!! error TS1331: A property of a class whose type is a 'unique symbol' type must be both 'static' and 'readonly'. + } \ No newline at end of file diff --git a/tests/baselines/reference/uniqueSymbolsDeclarationsInJsErrors.js b/tests/baselines/reference/uniqueSymbolsDeclarationsInJsErrors.js new file mode 100644 index 0000000000000..65019a88efd51 --- /dev/null +++ b/tests/baselines/reference/uniqueSymbolsDeclarationsInJsErrors.js @@ -0,0 +1,38 @@ +//// [uniqueSymbolsDeclarationsInJsErrors.js] +class C { + /** + * @type {unique symbol} + */ + static readwriteStaticType; + /** + * @type {unique symbol} + * @readonly + */ + static readonlyType; + /** + * @type {unique symbol} + */ + static readwriteType; +} + +//// [uniqueSymbolsDeclarationsInJsErrors-out.js] +class C { +} + + +//// [uniqueSymbolsDeclarationsInJsErrors-out.d.ts] +declare class C { + /** + * @type {unique symbol} + */ + static readwriteStaticType: unique symbol; + /** + * @type {unique symbol} + * @readonly + */ + static readonly readonlyType: unique symbol; + /** + * @type {unique symbol} + */ + static readwriteType: unique symbol; +} diff --git a/tests/baselines/reference/uniqueSymbolsDeclarationsInJsErrors.symbols b/tests/baselines/reference/uniqueSymbolsDeclarationsInJsErrors.symbols new file mode 100644 index 0000000000000..6ac6e495d7777 --- /dev/null +++ b/tests/baselines/reference/uniqueSymbolsDeclarationsInJsErrors.symbols @@ -0,0 +1,23 @@ +=== tests/cases/conformance/types/uniqueSymbol/uniqueSymbolsDeclarationsInJsErrors.js === +class C { +>C : Symbol(C, Decl(uniqueSymbolsDeclarationsInJsErrors.js, 0, 0)) + + /** + * @type {unique symbol} + */ + static readwriteStaticType; +>readwriteStaticType : Symbol(C.readwriteStaticType, Decl(uniqueSymbolsDeclarationsInJsErrors.js, 0, 9)) + + /** + * @type {unique symbol} + * @readonly + */ + static readonlyType; +>readonlyType : Symbol(C.readonlyType, Decl(uniqueSymbolsDeclarationsInJsErrors.js, 4, 31)) + + /** + * @type {unique symbol} + */ + static readwriteType; +>readwriteType : Symbol(C.readwriteType, Decl(uniqueSymbolsDeclarationsInJsErrors.js, 9, 24)) +} diff --git a/tests/baselines/reference/uniqueSymbolsDeclarationsInJsErrors.types b/tests/baselines/reference/uniqueSymbolsDeclarationsInJsErrors.types new file mode 100644 index 0000000000000..4571b2c3825e3 --- /dev/null +++ b/tests/baselines/reference/uniqueSymbolsDeclarationsInJsErrors.types @@ -0,0 +1,23 @@ +=== tests/cases/conformance/types/uniqueSymbol/uniqueSymbolsDeclarationsInJsErrors.js === +class C { +>C : C + + /** + * @type {unique symbol} + */ + static readwriteStaticType; +>readwriteStaticType : symbol + + /** + * @type {unique symbol} + * @readonly + */ + static readonlyType; +>readonlyType : symbol + + /** + * @type {unique symbol} + */ + static readwriteType; +>readwriteType : symbol +} diff --git a/tests/cases/conformance/jsdoc/jsdocAccessibilityTagsDeclarations.ts b/tests/cases/conformance/jsdoc/jsdocAccessibilityTagsDeclarations.ts index cfc488a972e4d..8890dbf92475a 100644 --- a/tests/cases/conformance/jsdoc/jsdocAccessibilityTagsDeclarations.ts +++ b/tests/cases/conformance/jsdoc/jsdocAccessibilityTagsDeclarations.ts @@ -35,3 +35,9 @@ class Private { /** @private */ set p(value) { this.c = value } } + +// https://github.com/microsoft/TypeScript/issues/38401 +class C { + constructor(/** @public */ x, /** @protected */ y, /** @private */ z) { + } +} \ No newline at end of file diff --git a/tests/cases/conformance/jsdoc/jsdocReadonlyDeclarations.ts b/tests/cases/conformance/jsdoc/jsdocReadonlyDeclarations.ts index a9a3f0d16e00b..854a67989c3a3 100644 --- a/tests/cases/conformance/jsdoc/jsdocReadonlyDeclarations.ts +++ b/tests/cases/conformance/jsdoc/jsdocReadonlyDeclarations.ts @@ -23,3 +23,8 @@ function F() { /** @readonly */ this.z = 1 } + +// https://github.com/microsoft/TypeScript/issues/38401 +class D { + constructor(/** @readonly */ x) {} +} \ No newline at end of file diff --git a/tests/cases/conformance/types/uniqueSymbol/uniqueSymbolsDeclarationsInJs.ts b/tests/cases/conformance/types/uniqueSymbol/uniqueSymbolsDeclarationsInJs.ts new file mode 100644 index 0000000000000..ff32ca4393d99 --- /dev/null +++ b/tests/cases/conformance/types/uniqueSymbol/uniqueSymbolsDeclarationsInJs.ts @@ -0,0 +1,32 @@ +// @target: esnext +// @lib: esnext +// @declaration: true +// @allowJs: true +// @checkJs: true +// @filename: uniqueSymbolsDeclarationsInJs.js +// @out: uniqueSymbolsDeclarationsInJs-out.js + +// classes +class C { + /** + * @readonly + */ + static readonlyStaticCall = Symbol(); + /** + * @type {unique symbol} + * @readonly + */ + static readonlyStaticType; + /** + * @type {unique symbol} + * @readonly + */ + static readonlyStaticTypeAndCall = Symbol(); + static readwriteStaticCall = Symbol(); + + /** + * @readonly + */ + readonlyCall = Symbol(); + readwriteCall = Symbol(); +} diff --git a/tests/cases/conformance/types/uniqueSymbol/uniqueSymbolsDeclarationsInJsErrors.ts b/tests/cases/conformance/types/uniqueSymbol/uniqueSymbolsDeclarationsInJsErrors.ts new file mode 100644 index 0000000000000..52d9afd5d6331 --- /dev/null +++ b/tests/cases/conformance/types/uniqueSymbol/uniqueSymbolsDeclarationsInJsErrors.ts @@ -0,0 +1,23 @@ +// @target: esnext +// @lib: esnext +// @declaration: true +// @allowJs: true +// @checkJs: true +// @filename: uniqueSymbolsDeclarationsInJsErrors.js +// @out: uniqueSymbolsDeclarationsInJsErrors-out.js + +class C { + /** + * @type {unique symbol} + */ + static readwriteStaticType; + /** + * @type {unique symbol} + * @readonly + */ + static readonlyType; + /** + * @type {unique symbol} + */ + static readwriteType; +} \ No newline at end of file