@@ -756,7 +756,7 @@ module ts {
756756 //
757757 // x is an optional parameter, but it is a required property.
758758 return propertySymbol . valueDeclaration &&
759- propertySymbol . valueDeclaration . flags & NodeFlags . QuestionMark &&
759+ hasQuestionToken ( propertySymbol . valueDeclaration ) &&
760760 propertySymbol . valueDeclaration . kind !== SyntaxKind . Parameter ;
761761 }
762762
@@ -1441,7 +1441,7 @@ module ts {
14411441 writePunctuation ( writer , SyntaxKind . DotDotDotToken ) ;
14421442 }
14431443 appendSymbolNameOnly ( p , writer ) ;
1444- if ( p . valueDeclaration . flags & NodeFlags . QuestionMark || ( < VariableDeclaration > p . valueDeclaration ) . initializer ) {
1444+ if ( hasQuestionToken ( p . valueDeclaration ) || ( < VariableDeclaration > p . valueDeclaration ) . initializer ) {
14451445 writePunctuation ( writer , SyntaxKind . QuestionToken ) ;
14461446 }
14471447 writePunctuation ( writer , SyntaxKind . ColonToken ) ;
@@ -2527,7 +2527,7 @@ module ts {
25272527 hasStringLiterals = true ;
25282528 }
25292529 if ( minArgumentCount < 0 ) {
2530- if ( param . initializer || param . flags & NodeFlags . QuestionMark || param . dotDotDotToken ) {
2530+ if ( param . initializer || param . questionToken || param . dotDotDotToken ) {
25312531 minArgumentCount = i ;
25322532 }
25332533 }
@@ -7020,20 +7020,23 @@ module ts {
70207020 return ;
70217021 }
70227022
7023+ function getCanonicalOverload ( overloads : Declaration [ ] , implementation : FunctionLikeDeclaration ) {
7024+ // Consider the canonical set of flags to be the flags of the bodyDeclaration or the first declaration
7025+ // Error on all deviations from this canonical set of flags
7026+ // The caveat is that if some overloads are defined in lib.d.ts, we don't want to
7027+ // report the errors on those. To achieve this, we will say that the implementation is
7028+ // the canonical signature only if it is in the same container as the first overload
7029+ var implementationSharesContainerWithFirstOverload = implementation !== undefined && implementation . parent === overloads [ 0 ] . parent ;
7030+ return implementationSharesContainerWithFirstOverload ? implementation : overloads [ 0 ] ;
7031+ }
7032+
70237033 function checkFlagAgreementBetweenOverloads ( overloads : Declaration [ ] , implementation : FunctionLikeDeclaration , flagsToCheck : NodeFlags , someOverloadFlags : NodeFlags , allOverloadFlags : NodeFlags ) : void {
70247034 // Error if some overloads have a flag that is not shared by all overloads. To find the
70257035 // deviations, we XOR someOverloadFlags with allOverloadFlags
70267036 var someButNotAllOverloadFlags = someOverloadFlags ^ allOverloadFlags ;
70277037 if ( someButNotAllOverloadFlags !== 0 ) {
7028- // Consider the canonical set of flags to be the flags of the bodyDeclaration or the first declaration
7029- // Error on all deviations from this canonical set of flags
7030- // The caveat is that if some overloads are defined in lib.d.ts, we don't want to
7031- // report the errors on those. To achieve this, we will say that the implementation is
7032- // the canonical signature only if it is in the same container as the first overload
7033- var implementationSharesContainerWithFirstOverload = implementation !== undefined && implementation . parent === overloads [ 0 ] . parent ;
7034- var canonicalFlags = implementationSharesContainerWithFirstOverload
7035- ? getEffectiveDeclarationFlags ( implementation , flagsToCheck )
7036- : getEffectiveDeclarationFlags ( overloads [ 0 ] , flagsToCheck ) ;
7038+ var canonicalFlags = getEffectiveDeclarationFlags ( getCanonicalOverload ( overloads , implementation ) , flagsToCheck ) ;
7039+
70377040 forEach ( overloads , o => {
70387041 var deviation = getEffectiveDeclarationFlags ( o , flagsToCheck ) ^ canonicalFlags ;
70397042 if ( deviation & NodeFlags . Export ) {
@@ -7045,16 +7048,27 @@ module ts {
70457048 else if ( deviation & ( NodeFlags . Private | NodeFlags . Protected ) ) {
70467049 error ( o . name , Diagnostics . Overload_signatures_must_all_be_public_private_or_protected ) ;
70477050 }
7048- else if ( deviation & NodeFlags . QuestionMark ) {
7051+ } ) ;
7052+ }
7053+ }
7054+
7055+ function checkQuestionTokenAgreementBetweenOverloads ( overloads : Declaration [ ] , implementation : FunctionLikeDeclaration , someHaveQuestionToken : boolean , allHaveQuestionToken : boolean ) : void {
7056+ if ( someHaveQuestionToken !== allHaveQuestionToken ) {
7057+ var canonicalHasQuestionToken = hasQuestionToken ( getCanonicalOverload ( overloads , implementation ) ) ;
7058+ forEach ( overloads , o => {
7059+ var deviation = hasQuestionToken ( o ) !== canonicalHasQuestionToken ;
7060+ if ( deviation ) {
70497061 error ( o . name , Diagnostics . Overload_signatures_must_all_be_optional_or_required ) ;
70507062 }
70517063 } ) ;
70527064 }
70537065 }
70547066
7055- var flagsToCheck : NodeFlags = NodeFlags . Export | NodeFlags . Ambient | NodeFlags . Private | NodeFlags . Protected | NodeFlags . QuestionMark ;
7067+ var flagsToCheck : NodeFlags = NodeFlags . Export | NodeFlags . Ambient | NodeFlags . Private | NodeFlags . Protected ;
70567068 var someNodeFlags : NodeFlags = 0 ;
70577069 var allNodeFlags = flagsToCheck ;
7070+ var someHaveQuestionToken = false ;
7071+ var allHaveQuestionToken = true ;
70587072 var hasOverloads = false ;
70597073 var bodyDeclaration : FunctionLikeDeclaration ;
70607074 var lastSeenNonAmbientDeclaration : FunctionLikeDeclaration ;
@@ -7128,6 +7142,8 @@ module ts {
71287142 var currentNodeFlags = getEffectiveDeclarationFlags ( node , flagsToCheck ) ;
71297143 someNodeFlags |= currentNodeFlags ;
71307144 allNodeFlags &= currentNodeFlags ;
7145+ someHaveQuestionToken = someHaveQuestionToken || hasQuestionToken ( node ) ;
7146+ allHaveQuestionToken = allHaveQuestionToken && hasQuestionToken ( node ) ;
71317147
71327148 if ( node . body && bodyDeclaration ) {
71337149 if ( isConstructor ) {
@@ -7176,6 +7192,8 @@ module ts {
71767192
71777193 if ( hasOverloads ) {
71787194 checkFlagAgreementBetweenOverloads ( declarations , bodyDeclaration , flagsToCheck , someNodeFlags , allNodeFlags ) ;
7195+ checkQuestionTokenAgreementBetweenOverloads ( declarations , bodyDeclaration , someHaveQuestionToken , allHaveQuestionToken ) ;
7196+
71797197 if ( bodyDeclaration ) {
71807198 var signatures = getSignaturesOfSymbol ( symbol ) ;
71817199 var bodySignature = getSignatureFromDeclaration ( bodyDeclaration ) ;
0 commit comments