@@ -188,15 +188,13 @@ export class Resolver extends DiagnosticEmitter {
188188 }
189189 }
190190 if ( node . isNullable ) {
191- if ( ! type . is ( TypeFlags . REFERENCE ) ) {
192- if ( reportMode == ReportMode . REPORT ) {
193- this . error (
194- DiagnosticCode . Basic_type_0_cannot_be_nullable ,
195- node . range , type . toString ( )
196- ) ;
197- }
191+ if ( type . is ( TypeFlags . REFERENCE ) ) return type . asNullable ( ) ;
192+ if ( reportMode == ReportMode . REPORT ) {
193+ this . error (
194+ DiagnosticCode . Basic_type_0_cannot_be_nullable ,
195+ node . range , type . toString ( )
196+ ) ;
198197 }
199- return type . asNullable ( ) ;
200198 }
201199 return type ;
202200 }
@@ -692,21 +690,105 @@ export class Resolver extends DiagnosticEmitter {
692690 return typeArguments ;
693691 }
694692
695- /** Infers the generic type(s) of an argument expression and updates `ctxTypes`. */
696- inferGenericType (
697- /** The generic type being inferred. */
698- typeNode : TypeNode ,
699- /** The respective argument expression. */
700- exprNode : Expression ,
701- /** Contextual flow. */
693+ /** Resolves respectively infers the concrete instance of a function by call context. */
694+ maybeInferCall (
695+ node : CallExpression ,
696+ prototype : FunctionPrototype ,
702697 ctxFlow : Flow ,
703- /** Contextual types, i.e. `T`, with unknown types initialized to `auto`. */
704- ctxTypes : Map < string , Type > ,
705- /** The names of the type parameters being inferred. */
706- typeParameterNames : Set < string >
707- ) : void {
708- var type = this . resolveExpression ( exprNode , ctxFlow , Type . auto , ReportMode . SWALLOW ) ;
709- if ( type ) this . propagateInferredGenericTypes ( typeNode , type , ctxFlow , ctxTypes , typeParameterNames ) ;
698+ reportMode : ReportMode = ReportMode . REPORT
699+ ) : Function | null {
700+ var typeArguments = node . typeArguments ;
701+
702+ // resolve generic call if type arguments have been provided
703+ if ( typeArguments ) {
704+ if ( ! prototype . is ( CommonFlags . GENERIC ) ) {
705+ if ( reportMode == ReportMode . REPORT ) {
706+ this . error (
707+ DiagnosticCode . Type_0_is_not_generic ,
708+ node . expression . range , prototype . internalName
709+ ) ;
710+ }
711+ return null ;
712+ }
713+ return this . resolveFunctionInclTypeArguments (
714+ prototype ,
715+ node . typeArguments ,
716+ ctxFlow . actualFunction ,
717+ makeMap ( ctxFlow . contextualTypeArguments ) , // don't inherit
718+ node ,
719+ reportMode
720+ ) ;
721+ }
722+
723+ // infer generic call if type arguments have been omitted
724+ if ( prototype . is ( CommonFlags . GENERIC ) ) {
725+ let contextualTypeArguments = makeMap < string , Type > ( ctxFlow . contextualTypeArguments ) ;
726+
727+ // fill up contextual types with auto for each generic component
728+ let typeParameterNodes = assert ( prototype . typeParameterNodes ) ;
729+ let numTypeParameters = typeParameterNodes . length ;
730+ let typeParameterNames = new Set < string > ( ) ;
731+ for ( let i = 0 ; i < numTypeParameters ; ++ i ) {
732+ let name = typeParameterNodes [ i ] . name . text ;
733+ contextualTypeArguments . set ( name , Type . auto ) ;
734+ typeParameterNames . add ( name ) ;
735+ }
736+
737+ let parameterNodes = prototype . functionTypeNode . parameters ;
738+ let numParameters = parameterNodes . length ;
739+ let argumentNodes = node . arguments ;
740+ let numArguments = argumentNodes . length ;
741+
742+ // infer types with generic components while updating contextual types
743+ for ( let i = 0 ; i < numParameters ; ++ i ) {
744+ let argumentExpression = i < numArguments ? argumentNodes [ i ] : parameterNodes [ i ] . initializer ;
745+ if ( ! argumentExpression ) { // missing initializer -> too few arguments
746+ if ( reportMode == ReportMode . REPORT ) {
747+ this . error (
748+ DiagnosticCode . Expected_0_arguments_but_got_1 ,
749+ node . range , numParameters . toString ( 10 ) , numArguments . toString ( 10 )
750+ ) ;
751+ }
752+ return null ;
753+ }
754+ let typeNode = parameterNodes [ i ] . type ;
755+ if ( typeNode . hasGenericComponent ( typeParameterNodes ) ) {
756+ let type = this . resolveExpression ( argumentExpression , ctxFlow , Type . auto , ReportMode . SWALLOW ) ;
757+ if ( type ) this . propagateInferredGenericTypes ( typeNode , type , ctxFlow , contextualTypeArguments , typeParameterNames ) ;
758+ }
759+ }
760+
761+ // apply concrete types to the generic function signature
762+ let resolvedTypeArguments = new Array < Type > ( numTypeParameters ) ;
763+ for ( let i = 0 ; i < numTypeParameters ; ++ i ) {
764+ let name = typeParameterNodes [ i ] . name . text ;
765+ if ( contextualTypeArguments . has ( name ) ) {
766+ let inferredType = contextualTypeArguments . get ( name ) ! ;
767+ if ( inferredType != Type . auto ) {
768+ resolvedTypeArguments [ i ] = inferredType ;
769+ continue ;
770+ }
771+ }
772+ // unused template, e.g. `function test<T>(): void {...}` called as `test()`
773+ // invalid because the type is effectively unknown inside the function body
774+ if ( reportMode == ReportMode . REPORT ) {
775+ this . error (
776+ DiagnosticCode . Type_argument_expected ,
777+ node . expression . range . atEnd
778+ ) ;
779+ }
780+ return null ;
781+ }
782+ return this . resolveFunction (
783+ prototype ,
784+ resolvedTypeArguments ,
785+ makeMap < string , Type > ( ctxFlow . contextualTypeArguments ) ,
786+ reportMode
787+ ) ;
788+ }
789+
790+ // otherwise resolve the non-generic call as usual
791+ return this . resolveFunction ( prototype , null , makeMap < string , Type > ( ) , reportMode ) ;
710792 }
711793
712794 /** Updates contextual types with a possibly encapsulated inferred type. */
@@ -2185,31 +2267,20 @@ export class Resolver extends DiagnosticEmitter {
21852267 reportMode
21862268 ) ;
21872269 if ( ! target ) return null ;
2188-
21892270 switch ( target . kind ) {
21902271 case ElementKind . FUNCTION_PROTOTYPE : {
2191- // `unchecked(expr: *): *` is special
2272+ // `unchecked` behaves like parenthesized
21922273 if (
21932274 ( < FunctionPrototype > target ) . internalName == BuiltinSymbols . unchecked &&
21942275 node . arguments . length > 0
21952276 ) {
21962277 return this . resolveExpression ( node . arguments [ 0 ] , ctxFlow , ctxType , reportMode ) ;
21972278 }
2198- // otherwise resolve normally
2199- let instance = this . resolveFunctionInclTypeArguments (
2200- < FunctionPrototype > target ,
2201- node . typeArguments ,
2202- ctxFlow . actualFunction ,
2203- makeMap ( ctxFlow . contextualTypeArguments ) , // don't inherit
2204- node ,
2205- reportMode
2206- ) ;
2279+ let instance = this . maybeInferCall ( node , < FunctionPrototype > target , ctxFlow , reportMode ) ;
22072280 if ( ! instance ) return null ;
22082281 return instance . signature . returnType ;
22092282 }
2210- case ElementKind . FUNCTION_TARGET : {
2211- return ( < FunctionTarget > target ) . signature . returnType ;
2212- }
2283+ case ElementKind . FUNCTION_TARGET : return ( < FunctionTarget > target ) . signature . returnType ;
22132284 }
22142285 if ( reportMode == ReportMode . REPORT ) {
22152286 this . error (
0 commit comments