From b3f3f336ad1c68ebfceb9d0d0aff905f1b4f2a23 Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 11 Aug 2017 07:15:15 -0700 Subject: [PATCH] Use `hasModifier` and `hasModifiers` helper functions (#17724) --- src/compiler/binder.ts | 9 +-- src/compiler/checker.ts | 126 +++++++++++++++++++------------------- src/compiler/parser.ts | 6 +- src/compiler/utilities.ts | 8 ++- 4 files changed, 76 insertions(+), 73 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 6ca2f402ac2..a7e94da09d9 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2767,7 +2767,6 @@ namespace ts { function computeParameter(node: ParameterDeclaration, subtreeFlags: TransformFlags) { let transformFlags = subtreeFlags; - const modifierFlags = getModifierFlags(node); const name = node.name; const initializer = node.initializer; const dotDotDotToken = node.dotDotDotToken; @@ -2782,7 +2781,7 @@ namespace ts { } // If a parameter has an accessibility modifier, then it is TypeScript syntax. - if (modifierFlags & ModifierFlags.ParameterPropertyModifier) { + if (hasModifier(node, ModifierFlags.ParameterPropertyModifier)) { transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.ContainsParameterPropertyAssignments; } @@ -2827,9 +2826,8 @@ namespace ts { function computeClassDeclaration(node: ClassDeclaration, subtreeFlags: TransformFlags) { let transformFlags: TransformFlags; - const modifierFlags = getModifierFlags(node); - if (modifierFlags & ModifierFlags.Ambient) { + if (hasModifier(node, ModifierFlags.Ambient)) { // An ambient declaration is TypeScript syntax. transformFlags = TransformFlags.AssertTypeScript; } @@ -3173,11 +3171,10 @@ namespace ts { function computeVariableStatement(node: VariableStatement, subtreeFlags: TransformFlags) { let transformFlags: TransformFlags; - const modifierFlags = getModifierFlags(node); const declarationListTransformFlags = node.declarationList.transformFlags; // An ambient declaration is TypeScript syntax. - if (modifierFlags & ModifierFlags.Ambient) { + if (hasModifier(node, ModifierFlags.Ambient)) { transformFlags = TransformFlags.AssertTypeScript; } else { diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 07c94bd746e..22efe31930f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -835,13 +835,13 @@ namespace ts { (current.parent).initializer === current; if (initializerOfProperty) { - if (getModifierFlags(current.parent) & ModifierFlags.Static) { + if (hasModifier(current.parent, ModifierFlags.Static)) { if (declaration.kind === SyntaxKind.MethodDeclaration) { return true; } } else { - const isDeclarationInstanceProperty = declaration.kind === SyntaxKind.PropertyDeclaration && !(getModifierFlags(declaration) & ModifierFlags.Static); + const isDeclarationInstanceProperty = declaration.kind === SyntaxKind.PropertyDeclaration && !hasModifier(declaration, ModifierFlags.Static); if (!isDeclarationInstanceProperty || getContainingClass(usage) !== getContainingClass(declaration)) { return true; } @@ -978,7 +978,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 (isClassLike(location.parent) && !(getModifierFlags(location) & ModifierFlags.Static)) { + if (isClassLike(location.parent) && !hasModifier(location, ModifierFlags.Static)) { const ctor = findConstructorDeclaration(location.parent); if (ctor && ctor.locals) { if (lookup(ctor.locals, name, meaning & SymbolFlags.Value)) { @@ -997,7 +997,7 @@ namespace ts { result = undefined; break; } - if (lastLocation && getModifierFlags(lastLocation) & ModifierFlags.Static) { + if (lastLocation && hasModifier(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. @@ -1200,7 +1200,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 && !(getModifierFlags(location) & ModifierFlags.Static)) { + if (location === container && !hasModifier(location, ModifierFlags.Static)) { const instanceType = (getDeclaredTypeOfSymbol(classSymbol)).thisType; if (getPropertyOfType(instanceType, name)) { error(errorLocation, Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0, diagnosticName(nameArg)); @@ -2245,7 +2245,7 @@ namespace ts { const anyImportSyntax = getAnyImportSyntax(declaration); if (anyImportSyntax && - !(getModifierFlags(anyImportSyntax) & ModifierFlags.Export) && // import clause without export + !hasModifier(anyImportSyntax, ModifierFlags.Export) && // import clause without export isDeclarationVisible(anyImportSyntax.parent)) { // In function "buildTypeDisplay" where we decide whether to write type-alias or serialize types, // we want to just check if type- alias is accessible or not but we don't care about emitting those alias at that time @@ -2572,8 +2572,8 @@ namespace ts { } function shouldWriteTypeOfFunctionSymbol() { - const isStaticMethodSymbol = !!(symbol.flags & SymbolFlags.Method && // typeof static method - forEach(symbol.declarations, declaration => getModifierFlags(declaration) & ModifierFlags.Static)); + const isStaticMethodSymbol = !!(symbol.flags & SymbolFlags.Method) && // typeof static method + some(symbol.declarations, declaration => hasModifier(declaration, ModifierFlags.Static)); const isNonLocalFunctionSymbol = !!(symbol.flags & SymbolFlags.Function) && (symbol.parent || // is exported function symbol forEach(symbol.declarations, declaration => @@ -3437,16 +3437,16 @@ namespace ts { } function shouldWriteTypeOfFunctionSymbol() { - const isStaticMethodSymbol = !!(symbol.flags & SymbolFlags.Method && // typeof static method - forEach(symbol.declarations, declaration => getModifierFlags(declaration) & ModifierFlags.Static)); + const isStaticMethodSymbol = !!(symbol.flags & SymbolFlags.Method) && // typeof static method + some(symbol.declarations, declaration => hasModifier(declaration, ModifierFlags.Static)); const isNonLocalFunctionSymbol = !!(symbol.flags & SymbolFlags.Function) && (symbol.parent || // is exported function symbol - forEach(symbol.declarations, declaration => + some(symbol.declarations, declaration => declaration.parent.kind === SyntaxKind.SourceFile || declaration.parent.kind === SyntaxKind.ModuleBlock)); if (isStaticMethodSymbol || isNonLocalFunctionSymbol) { // typeof is allowed only for static/non local functions return !!(flags & TypeFormatFlags.UseTypeOfFunction) || // use typeof if format flags specify it - (contains(symbolStack, symbol)); // it is type of the symbol uses itself recursively + contains(symbolStack, symbol); // it is type of the symbol uses itself recursively } } } @@ -3892,7 +3892,7 @@ namespace ts { case SyntaxKind.SetAccessor: case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: - if (getModifierFlags(node) & (ModifierFlags.Private | ModifierFlags.Protected)) { + if (hasModifier(node, ModifierFlags.Private | ModifierFlags.Protected)) { // Private/protected properties/methods are not visible return false; } @@ -6657,7 +6657,7 @@ namespace ts { const declaration = getIndexDeclarationOfSymbol(symbol, kind); if (declaration) { return createIndexInfo(declaration.type ? getTypeFromTypeNode(declaration.type) : anyType, - (getModifierFlags(declaration) & ModifierFlags.Readonly) !== 0, declaration); + hasModifier(declaration, ModifierFlags.Readonly), declaration); } return undefined; } @@ -7909,7 +7909,7 @@ namespace ts { const container = getThisContainer(node, /*includeArrowFunctions*/ false); const parent = container && container.parent; if (parent && (isClassLike(parent) || parent.kind === SyntaxKind.InterfaceDeclaration)) { - if (!(getModifierFlags(container) & ModifierFlags.Static) && + if (!hasModifier(container, ModifierFlags.Static) && (container.kind !== SyntaxKind.Constructor || isNodeDescendantOf(node, (container).body))) { return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(parent)).thisType; } @@ -9729,8 +9729,8 @@ namespace ts { return true; } - const sourceAccessibility = getModifierFlags(sourceSignature.declaration) & ModifierFlags.NonPublicAccessibilityModifier; - const targetAccessibility = getModifierFlags(targetSignature.declaration) & ModifierFlags.NonPublicAccessibilityModifier; + const sourceAccessibility = getSelectedModifierFlags(sourceSignature.declaration, ModifierFlags.NonPublicAccessibilityModifier); + const targetAccessibility = getSelectedModifierFlags(targetSignature.declaration, ModifierFlags.NonPublicAccessibilityModifier); // A public, protected and private signature is assignable to a private signature. if (targetAccessibility === ModifierFlags.Private) { @@ -9804,7 +9804,7 @@ namespace ts { const symbol = type.symbol; if (symbol && symbol.flags & SymbolFlags.Class) { const declaration = getClassLikeDeclarationOfSymbol(symbol); - if (declaration && getModifierFlags(declaration) & ModifierFlags.Abstract) { + if (declaration && hasModifier(declaration, ModifierFlags.Abstract)) { return true; } } @@ -12471,7 +12471,7 @@ namespace ts { break; case SyntaxKind.PropertyDeclaration: case SyntaxKind.PropertySignature: - if (getModifierFlags(container) & ModifierFlags.Static) { + if (hasModifier(container, ModifierFlags.Static)) { 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 } @@ -12589,7 +12589,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 ((getModifierFlags(container) & ModifierFlags.Static) || isCallExpression) { + if (hasModifier(container, ModifierFlags.Static) || isCallExpression) { nodeCheckFlag = NodeCheckFlags.SuperStatic; } else { @@ -12654,7 +12654,7 @@ namespace ts { // This helper creates an object with a "value" property that wraps the `super` property or indexed access for both get and set. // This is required for destructuring assignments, as a call expression cannot be used as the target of a destructuring assignment // while a property access can. - if (container.kind === SyntaxKind.MethodDeclaration && getModifierFlags(container) & ModifierFlags.Async) { + if (container.kind === SyntaxKind.MethodDeclaration && hasModifier(container, ModifierFlags.Async)) { if (isSuperProperty(node.parent) && isAssignmentTarget(node.parent)) { getNodeLinks(container).flags |= NodeCheckFlags.AsyncMethodWithSuperBinding; } @@ -12720,7 +12720,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 (getModifierFlags(container) & ModifierFlags.Static) { + if (hasModifier(container, ModifierFlags.Static)) { return container.kind === SyntaxKind.MethodDeclaration || container.kind === SyntaxKind.MethodSignature || container.kind === SyntaxKind.GetAccessor || @@ -14765,7 +14765,7 @@ namespace ts { if (prop && noUnusedIdentifiers && (prop.flags & SymbolFlags.ClassMember) && - prop.valueDeclaration && (getModifierFlags(prop.valueDeclaration) & ModifierFlags.Private)) { + prop.valueDeclaration && hasModifier(prop.valueDeclaration, ModifierFlags.Private)) { if (getCheckFlags(prop) & CheckFlags.Instantiated) { getSymbolLinks(prop).target.isReferenced = true; } @@ -16058,7 +16058,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 && getModifierFlags(valueDecl) & ModifierFlags.Abstract) { + if (valueDecl && hasModifier(valueDecl, ModifierFlags.Abstract)) { error(node, Diagnostics.Cannot_create_an_instance_of_the_abstract_class_0, declarationNameToString(getNameOfDeclaration(valueDecl))); return resolveErrorCall(node); } @@ -16111,10 +16111,10 @@ namespace ts { } const declaration = signature.declaration; - const modifiers = getModifierFlags(declaration); + const modifiers = getSelectedModifierFlags(declaration, ModifierFlags.NonPublicAccessibilityModifier); // Public constructor is accessible. - if (!(modifiers & ModifierFlags.NonPublicAccessibilityModifier)) { + if (!modifiers) { return true; } @@ -18095,7 +18095,7 @@ namespace ts { checkVariableLikeDeclaration(node); let func = getContainingFunction(node); - if (getModifierFlags(node) & ModifierFlags.ParameterPropertyModifier) { + if (hasModifier(node, ModifierFlags.ParameterPropertyModifier)) { func = getContainingFunction(node); if (!(func.kind === SyntaxKind.Constructor && nodeIsPresent(func.body))) { error(node, Diagnostics.A_parameter_property_is_only_allowed_in_a_constructor_implementation); @@ -18330,7 +18330,7 @@ namespace ts { } } else { - const isStatic = getModifierFlags(member) & ModifierFlags.Static; + const isStatic = hasModifier(member, ModifierFlags.Static); const names = isStatic ? staticNames : instanceNames; const memberName = member.name && getPropertyNameForPropertyNameNode(member.name); @@ -18391,7 +18391,7 @@ namespace ts { function checkClassForStaticPropertyNameConflicts(node: ClassLikeDeclaration) { for (const member of node.members) { const memberNameNode = member.name; - const isStatic = getModifierFlags(member) & ModifierFlags.Static; + const isStatic = hasModifier(member, ModifierFlags.Static); if (isStatic && memberNameNode) { const memberName = getPropertyNameForPropertyNameNode(memberNameNode); switch (memberName) { @@ -18496,7 +18496,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 (getModifierFlags(node) & ModifierFlags.Abstract && node.body) { + if (hasModifier(node, ModifierFlags.Abstract) && node.body) { error(node, Diagnostics.Method_0_cannot_have_an_implementation_because_it_is_marked_abstract, declarationNameToString(node.name)); } } @@ -18547,7 +18547,7 @@ namespace ts { function isInstancePropertyWithInitializer(n: Node): boolean { return n.kind === SyntaxKind.PropertyDeclaration && - !(getModifierFlags(n) & ModifierFlags.Static) && + !hasModifier(n, ModifierFlags.Static) && !!(n).initializer; } @@ -18570,8 +18570,8 @@ namespace ts { // - The constructor declares parameter properties // or the containing class declares instance member variables with initializers. const superCallShouldBeFirst = - forEach((node.parent).members, isInstancePropertyWithInitializer) || - forEach(node.parameters, p => getModifierFlags(p) & ModifierFlags.ParameterPropertyModifier); + some((node.parent).members, isInstancePropertyWithInitializer) || + some(node.parameters, p => hasModifier(p, ModifierFlags.ParameterPropertyModifier)); // Skip past any prologue directives to find the first statement // to ensure that it was a super call. @@ -18625,10 +18625,12 @@ namespace ts { const otherKind = node.kind === SyntaxKind.GetAccessor ? SyntaxKind.SetAccessor : SyntaxKind.GetAccessor; const otherAccessor = getDeclarationOfKind(node.symbol, otherKind); if (otherAccessor) { - if ((getModifierFlags(node) & ModifierFlags.AccessibilityModifier) !== (getModifierFlags(otherAccessor) & ModifierFlags.AccessibilityModifier)) { + const nodeFlags = getModifierFlags(node); + const otherFlags = getModifierFlags(otherAccessor); + if ((nodeFlags & ModifierFlags.AccessibilityModifier) !== (otherFlags & ModifierFlags.AccessibilityModifier)) { error(node.name, Diagnostics.Getter_and_setter_accessors_do_not_agree_in_visibility); } - if (hasModifier(node, ModifierFlags.Abstract) !== hasModifier(otherAccessor, ModifierFlags.Abstract)) { + if ((nodeFlags & ModifierFlags.Abstract) !== (otherFlags & ModifierFlags.Abstract)) { error(node.name, Diagnostics.Accessors_must_both_be_abstract_or_non_abstract); } @@ -18784,7 +18786,7 @@ namespace ts { } function isPrivateWithinAmbient(node: Node): boolean { - return (getModifierFlags(node) & ModifierFlags.Private) && isInAmbientContext(node); + return hasModifier(node, ModifierFlags.Private) && isInAmbientContext(node); } function getEffectiveDeclarationFlags(n: Node, flagsToCheck: ModifierFlags): ModifierFlags { @@ -18897,13 +18899,13 @@ namespace ts { !isComputedPropertyName(node.name) && !isComputedPropertyName(subsequentName) && getEscapedTextOfIdentifierOrLiteral(node.name) === getEscapedTextOfIdentifierOrLiteral(subsequentName))) { const reportError = (node.kind === SyntaxKind.MethodDeclaration || node.kind === SyntaxKind.MethodSignature) && - (getModifierFlags(node) & ModifierFlags.Static) !== (getModifierFlags(subsequentNode) & ModifierFlags.Static); + hasModifier(node, ModifierFlags.Static) !== hasModifier(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 = getModifierFlags(node) & ModifierFlags.Static ? Diagnostics.Function_overload_must_be_static : Diagnostics.Function_overload_must_not_be_static; + const diagnostic = hasModifier(node, ModifierFlags.Static) ? Diagnostics.Function_overload_must_be_static : Diagnostics.Function_overload_must_not_be_static; error(errorNode, diagnostic); } return; @@ -18921,7 +18923,7 @@ namespace ts { else { // Report different errors regarding non-consecutive blocks of declarations depending on whether // the node in question is abstract. - if (getModifierFlags(node) & ModifierFlags.Abstract) { + if (hasModifier(node, ModifierFlags.Abstract)) { error(errorNode, Diagnostics.All_declarations_of_an_abstract_method_must_be_consecutive); } else { @@ -18997,7 +18999,7 @@ namespace ts { // Abstract methods can't have an implementation -- in particular, they don't need one. if (lastSeenNonAmbientDeclaration && !lastSeenNonAmbientDeclaration.body && - !(getModifierFlags(lastSeenNonAmbientDeclaration) & ModifierFlags.Abstract) && !lastSeenNonAmbientDeclaration.questionToken) { + !hasModifier(lastSeenNonAmbientDeclaration, ModifierFlags.Abstract) && !lastSeenNonAmbientDeclaration.questionToken) { reportImplementationExpectedError(lastSeenNonAmbientDeclaration); } @@ -19800,13 +19802,13 @@ namespace ts { if (node.members) { for (const member of node.members) { if (member.kind === SyntaxKind.MethodDeclaration || member.kind === SyntaxKind.PropertyDeclaration) { - if (!member.symbol.isReferenced && getModifierFlags(member) & ModifierFlags.Private) { + if (!member.symbol.isReferenced && hasModifier(member, ModifierFlags.Private)) { error(member.name, Diagnostics._0_is_declared_but_never_used, unescapeLeadingUnderscores(member.symbol.escapedName)); } } else if (member.kind === SyntaxKind.Constructor) { for (const parameter of (member).parameters) { - if (!parameter.symbol.isReferenced && getModifierFlags(parameter) & ModifierFlags.Private) { + if (!parameter.symbol.isReferenced && hasModifier(parameter, ModifierFlags.Private)) { error(parameter.name, Diagnostics.Property_0_is_declared_but_never_used, unescapeLeadingUnderscores(parameter.symbol.escapedName)); } } @@ -20276,7 +20278,7 @@ namespace ts { ModifierFlags.Readonly | ModifierFlags.Static; - return (getModifierFlags(left) & interestingFlags) === (getModifierFlags(right) & interestingFlags); + return getSelectedModifierFlags(left, interestingFlags) === getSelectedModifierFlags(right, interestingFlags); } function checkVariableDeclaration(node: VariableDeclaration) { @@ -21029,7 +21031,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 (!(getModifierFlags(member) & ModifierFlags.Static) && hasDynamicName(member)) { + if (!hasModifier(member, ModifierFlags.Static) && hasDynamicName(member)) { const propType = getTypeOfSymbol(member.symbol); checkIndexConstraintForProperty(member.symbol, propType, type, declaredStringIndexer, stringIndexType, IndexKind.String); checkIndexConstraintForProperty(member.symbol, propType, type, declaredNumberIndexer, numberIndexType, IndexKind.Number); @@ -21224,7 +21226,7 @@ namespace ts { } function checkClassDeclaration(node: ClassDeclaration) { - if (!node.name && !(getModifierFlags(node) & ModifierFlags.Default)) { + if (!node.name && !hasModifier(node, ModifierFlags.Default)) { grammarErrorOnFirstToken(node, Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name); } checkClassLikeDeclaration(node); @@ -21330,7 +21332,7 @@ namespace ts { const signatures = getSignaturesOfType(type, SignatureKind.Construct); if (signatures.length) { const declaration = signatures[0].declaration; - if (declaration && getModifierFlags(declaration) & ModifierFlags.Private) { + if (declaration && hasModifier(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)); @@ -21396,7 +21398,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 || !(getModifierFlags(derivedClassDecl) & ModifierFlags.Abstract))) { + if (baseDeclarationFlags & ModifierFlags.Abstract && (!derivedClassDecl || !hasModifier(derivedClassDecl, ModifierFlags.Abstract))) { if (derivedClassDecl.kind === SyntaxKind.ClassExpression) { error(derivedClassDecl, Diagnostics.Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1, symbolToString(baseProperty), typeToString(baseType)); @@ -22019,7 +22021,7 @@ namespace ts { // If we hit an import declaration in an illegal context, just bail out to avoid cascading errors. return; } - if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && getModifierFlags(node) !== 0) { + if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && hasModifiers(node)) { grammarErrorOnFirstToken(node, Diagnostics.An_import_declaration_cannot_have_modifiers); } if (checkExternalImportOrExportDeclaration(node)) { @@ -22049,7 +22051,7 @@ namespace ts { checkGrammarDecorators(node) || checkGrammarModifiers(node); if (isInternalModuleImportEqualsDeclaration(node) || checkExternalImportOrExportDeclaration(node)) { checkImportBinding(node); - if (getModifierFlags(node) & ModifierFlags.Export) { + if (hasModifier(node, ModifierFlags.Export)) { markExportAsReferenced(node); } if (isInternalModuleImportEqualsDeclaration(node)) { @@ -22082,7 +22084,7 @@ namespace ts { return; } - if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && getModifierFlags(node) !== 0) { + if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && hasModifiers(node)) { grammarErrorOnFirstToken(node, Diagnostics.An_export_declaration_cannot_have_modifiers); } @@ -22155,7 +22157,7 @@ namespace ts { return; } // Grammar checking - if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && getModifierFlags(node) !== 0) { + if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && hasModifiers(node)) { grammarErrorOnFirstToken(node, Diagnostics.An_export_assignment_cannot_have_modifiers); } if (node.expression.kind === SyntaxKind.Identifier) { @@ -22553,7 +22555,7 @@ namespace ts { } const symbols = createSymbolTable(); - let memberFlags: ModifierFlags = ModifierFlags.None; + let isStatic = false; populateSymbols(); @@ -22586,7 +22588,7 @@ namespace ts { // add the type parameters into the symbol table // (type parameters of classDeclaration/classExpression and interface are in member property of the symbol. // Note: that the memberFlags come from previous iteration. - if (!(memberFlags & ModifierFlags.Static)) { + if (!isStatic) { copySymbols(getSymbolOfNode(location).members, meaning & SymbolFlags.Type); } break; @@ -22602,7 +22604,7 @@ namespace ts { copySymbol(argumentsSymbol, meaning); } - memberFlags = getModifierFlags(location); + isStatic = hasModifier(location, ModifierFlags.Static); location = location.parent; } @@ -23063,7 +23065,7 @@ namespace ts { */ function getParentTypeOfClassElement(node: ClassElement) { const classSymbol = getSymbolOfNode(node.parent); - return getModifierFlags(node) & ModifierFlags.Static + return hasModifier(node, ModifierFlags.Static) ? getTypeOfSymbol(classSymbol) : getDeclaredTypeOfSymbol(classSymbol); } @@ -23375,14 +23377,14 @@ namespace ts { return strictNullChecks && !isOptionalParameter(parameter) && parameter.initializer && - !(getModifierFlags(parameter) & ModifierFlags.ParameterPropertyModifier); + !hasModifier(parameter, ModifierFlags.ParameterPropertyModifier); } function isOptionalUninitializedParameterProperty(parameter: ParameterDeclaration) { return strictNullChecks && isOptionalParameter(parameter) && !parameter.initializer && - !!(getModifierFlags(parameter) & ModifierFlags.ParameterPropertyModifier); + hasModifier(parameter, ModifierFlags.ParameterPropertyModifier); } function getNodeCheckFlags(node: Node): NodeCheckFlags { @@ -23997,7 +23999,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 && getModifierFlags(node.parent) & ModifierFlags.Abstract)) { + if (!(node.parent.kind === SyntaxKind.ClassDeclaration && hasModifier(node.parent, ModifierFlags.Abstract))) { return grammarErrorOnNode(modifier, Diagnostics.Abstract_methods_can_only_appear_within_an_abstract_class); } if (flags & ModifierFlags.Static) { @@ -24217,7 +24219,7 @@ namespace ts { if (parameter.dotDotDotToken) { return grammarErrorOnNode(parameter.dotDotDotToken, Diagnostics.An_index_signature_cannot_have_a_rest_parameter); } - if (getModifierFlags(parameter) !== 0) { + if (hasModifiers(parameter)) { return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_cannot_have_an_accessibility_modifier); } if (parameter.questionToken) { @@ -24556,10 +24558,10 @@ namespace ts { else if (isInAmbientContext(accessor)) { return grammarErrorOnNode(accessor.name, Diagnostics.An_accessor_cannot_be_declared_in_an_ambient_context); } - else if (accessor.body === undefined && !(getModifierFlags(accessor) & ModifierFlags.Abstract)) { + else if (accessor.body === undefined && !hasModifier(accessor, ModifierFlags.Abstract)) { return grammarErrorAtPos(getSourceFileOfNode(accessor), accessor.end - 1, ";".length, Diagnostics._0_expected, "{"); } - else if (accessor.body && getModifierFlags(accessor) & ModifierFlags.Abstract) { + else if (accessor.body && hasModifier(accessor, ModifierFlags.Abstract)) { return grammarErrorOnNode(accessor, Diagnostics.An_abstract_accessor_cannot_have_an_implementation); } else if (accessor.typeParameters) { @@ -24942,7 +24944,7 @@ namespace ts { node.kind === SyntaxKind.ExportDeclaration || node.kind === SyntaxKind.ExportAssignment || node.kind === SyntaxKind.NamespaceExportDeclaration || - getModifierFlags(node) & (ModifierFlags.Ambient | ModifierFlags.Export | ModifierFlags.Default)) { + hasModifier(node, ModifierFlags.Ambient | ModifierFlags.Export | ModifierFlags.Default)) { return false; } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 3ec652b215e..a2fe752ad18 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -3202,7 +3202,7 @@ namespace ts { return undefined; } - const isAsync = !!(getModifierFlags(arrowFunction) & ModifierFlags.Async); + const isAsync = hasModifier(arrowFunction, ModifierFlags.Async); // If we have an arrow, then try to parse the body. Even if not, try to parse if we // have an opening brace, just in case we're in an error state. @@ -3382,7 +3382,7 @@ namespace ts { function parseParenthesizedArrowFunctionExpressionHead(allowAmbiguity: boolean): ArrowFunction { const node = createNode(SyntaxKind.ArrowFunction); node.modifiers = parseModifiersForArrowFunction(); - const isAsync = (getModifierFlags(node) & ModifierFlags.Async) ? SignatureFlags.Await : SignatureFlags.None; + const isAsync = hasModifier(node, ModifierFlags.Async) ? SignatureFlags.Await : SignatureFlags.None; // Arrow functions are never generators. // @@ -4515,7 +4515,7 @@ namespace ts { node.asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken); const isGenerator = node.asteriskToken ? SignatureFlags.Yield : SignatureFlags.None; - const isAsync = (getModifierFlags(node) & ModifierFlags.Async) ? SignatureFlags.Await : SignatureFlags.None; + const isAsync = hasModifier(node, ModifierFlags.Async) ? SignatureFlags.Await : SignatureFlags.None; node.name = isGenerator && isAsync ? doInYieldAndAwaitContext(parseOptionalIdentifier) : isGenerator ? doInYieldContext(parseOptionalIdentifier) : diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 769b2ce3a93..ddcf6f90a0d 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2975,8 +2975,12 @@ namespace ts { return getModifierFlags(node) !== ModifierFlags.None; } - export function hasModifier(node: Node, flags: ModifierFlags) { - return (getModifierFlags(node) & flags) !== 0; + export function hasModifier(node: Node, flags: ModifierFlags): boolean { + return !!getSelectedModifierFlags(node, flags); + } + + export function getSelectedModifierFlags(node: Node, flags: ModifierFlags): ModifierFlags { + return getModifierFlags(node) & flags; } export function getModifierFlags(node: Node): ModifierFlags {