@@ -8,7 +8,15 @@ module TypeResolution {
88
99 predicate trackType = TypeFlow:: TrackNode< TypeDefinition > :: track / 1 ;
1010
11- predicate trackFunctionType = TypeFlow:: TrackNode< Function > :: track / 1 ;
11+ Node trackFunctionType ( Function fun ) {
12+ result = fun
13+ or
14+ exists ( Node mid | mid = trackFunctionType ( fun ) |
15+ TypeFlow:: step ( mid , result )
16+ or
17+ UnderlyingTypes:: underlyingTypeStep ( mid , result )
18+ )
19+ }
1220
1321 predicate trackFunctionValue = ValueFlow:: TrackNode< Function > :: track / 1 ;
1422
@@ -47,6 +55,24 @@ module TypeResolution {
4755 content .isUnknownArrayElement ( )
4856 )
4957 or
58+ // Ad-hoc support for array types
59+ content .isUnknownArrayElement ( ) and
60+ (
61+ memberType = host .( ArrayTypeExpr ) .getElementType ( )
62+ or
63+ exists ( GenericTypeExpr type |
64+ host = type and
65+ type .getTypeAccess ( ) .( LocalTypeAccess ) .getName ( ) = [ "Array" , "ReadonlyArray" ] and
66+ memberType = type .getTypeArgument ( 0 )
67+ )
68+ or
69+ exists ( JSDocAppliedTypeExpr type |
70+ host = type and
71+ type .getHead ( ) .( JSDocLocalTypeAccess ) .getName ( ) = "Array" and
72+ memberType = type .getArgument ( 0 )
73+ )
74+ )
75+ or
5076 // Inherit members from base types
5177 exists ( ClassOrInterface baseType | typeMember ( baseType , content , memberType ) |
5278 host .( ClassDefinition ) .getSuperClass ( ) = trackClassValue ( baseType )
@@ -115,11 +141,38 @@ module TypeResolution {
115141 )
116142 }
117143
118- private predicate contextualType ( Node value , Node contextualType ) {
144+ private predicate contextualType ( Node value , Node type ) {
119145 exists ( InvokeExpr call , Function target , int i |
120146 callTarget ( call , target ) and
121147 value = call .getArgument ( i ) and
122- contextualType = target .getParameter ( i ) .getTypeAnnotation ( )
148+ type = target .getParameter ( i ) .getTypeAnnotation ( )
149+ )
150+ or
151+ exists ( Function lambda |
152+ not lambda .isAsyncOrGenerator ( ) and
153+ value = lambda .getAReturnedExpr ( )
154+ |
155+ type = lambda .getReturnTypeAnnotation ( )
156+ or
157+ not exists ( lambda .getReturnTypeAnnotation ( ) ) and
158+ exists ( Function functionType |
159+ contextualType ( lambda , trackFunctionType ( functionType ) ) and
160+ type = functionType .getReturnTypeAnnotation ( )
161+ )
162+ )
163+ or
164+ exists ( ObjectExpr object , Node objectType , Node host , string name |
165+ contextualType ( object , objectType ) and
166+ typeMemberHostReaches ( host , objectType ) and
167+ typeMember ( host , any ( DataFlow:: Content c | c .asPropertyName ( ) = name ) , type ) and
168+ value = object .getPropertyByName ( name ) .getInit ( )
169+ )
170+ or
171+ exists ( ArrayExpr array , Node arrayType , Node host |
172+ contextualType ( array , arrayType ) and
173+ typeMemberHostReaches ( host , arrayType ) and
174+ typeMember ( host , any ( DataFlow:: Content c | c .isUnknownArrayElement ( ) ) , type ) and
175+ value = array .getAnElement ( )
123176 )
124177 }
125178
0 commit comments