@@ -1008,6 +1008,100 @@ private Type resolveMethodCallExprType(MethodCallExpr mce, TypePath path) {
10081008 )
10091009}
10101010
1011+ private module FieldExprMatchingInput implements MatchingInputSig {
1012+ abstract class Decl extends AstNode {
1013+ TypeParameter getTypeParameter ( int i ) { none ( ) }
1014+
1015+ abstract TypeRepr getTypeRepr ( ) ;
1016+ }
1017+
1018+ private class RecordFieldDecl extends Decl instanceof RecordField {
1019+ override TypeRepr getTypeRepr ( ) { result = RecordField .super .getTypeRepr ( ) }
1020+ }
1021+
1022+ private class TupleFieldDecl extends Decl instanceof TupleField {
1023+ override TypeRepr getTypeRepr ( ) { result = TupleField .super .getTypeRepr ( ) }
1024+ }
1025+
1026+ class Access extends FieldExpr {
1027+ Type getTypeArgument ( int i , TypePath path ) { none ( ) }
1028+
1029+ predicate noExplicitTypeArguments ( ) { any ( ) }
1030+ }
1031+
1032+ predicate target ( Access a , Decl target ) {
1033+ exists ( Type t , Type lookupType , string name |
1034+ t = resolveType ( a .getExpr ( ) ) and
1035+ name = a .getNameRef ( ) .getText ( ) and
1036+ if t = TRefType ( )
1037+ then
1038+ // for reference types, lookup the field in the type being referenced
1039+ lookupType = resolveType ( a .getExpr ( ) , "0" )
1040+ else lookupType = t
1041+ |
1042+ target = lookupType .getRecordField ( name )
1043+ or
1044+ target = lookupType .getTupleField ( name .toInt ( ) )
1045+ )
1046+ }
1047+
1048+ class Pos = int ;
1049+
1050+ Pos getReturnPos ( ) { result = - 2 }
1051+
1052+ private AstNode getExplicitArgument ( Access a , Pos pos ) { result = a .getExpr ( ) and pos = - 1 }
1053+
1054+ private predicate explicitArgumentType ( Access a , Pos pos , TypePath path , Type t ) {
1055+ t = resolveType ( getExplicitArgument ( a , pos ) , path )
1056+ }
1057+
1058+ predicate argumentType ( Access a , Pos pos , TypePath path , Type t ) {
1059+ explicitArgumentType ( a , pos , path , t )
1060+ // or
1061+ // implicitThis(a, pos, path, t)
1062+ }
1063+
1064+ pragma [ nomagic]
1065+ predicate argumentIsTargetTyped ( Access a , Pos pos ) { isTargetTyped ( getExplicitArgument ( a , pos ) ) }
1066+
1067+ pragma [ nomagic]
1068+ predicate argumentIsNotTargetTyped ( Access a , Pos pos ) {
1069+ exists ( AstNode arg |
1070+ arg = getExplicitArgument ( a , pos ) and
1071+ not isTargetTyped ( arg )
1072+ )
1073+ // or
1074+ // implicitThis(a, pos, _, _)
1075+ }
1076+
1077+ predicate parameterType ( Decl decl , Pos pos , TypePath path , Type t ) {
1078+ pos = - 1 and
1079+ exists ( Struct s | s .getRecordField ( _) = decl or s .getTupleField ( _) = decl |
1080+ t = TStruct ( s ) and
1081+ path .isEmpty ( )
1082+ or
1083+ exists ( int i |
1084+ t = TTypeParameter ( s .getGenericParamList ( ) .getTypeParam ( i ) ) and
1085+ path = typePath ( i )
1086+ )
1087+ )
1088+ }
1089+
1090+ pragma [ nomagic]
1091+ predicate declType ( Decl decl , TypePath path , Type t ) {
1092+ t = decl .getTypeRepr ( ) .( TypeRepr_ ) .resolveTypeAt ( path )
1093+ }
1094+ }
1095+
1096+ private module FieldExprMatching = Matching< FieldExprMatchingInput > ;
1097+
1098+ private Type resolveFieldExprType ( FieldExpr fe , TypePath path ) {
1099+ result = resolveFieldExprType0 ( fe , path )
1100+ or
1101+ // result = resolveFunctionReturnType(call.getStaticTarget(), path)
1102+ result = FieldExprMatching:: resolveAccess ( fe , - 2 , path )
1103+ }
1104+
10111105pragma [ nomagic]
10121106RecordField resolveRecordFieldExpr ( FieldExpr fe ) {
10131107 exists ( Type t , string name |
@@ -1035,7 +1129,7 @@ TupleField resolveTupleFieldExpr(FieldExpr fe) {
10351129}
10361130
10371131pragma [ nomagic]
1038- private Type resolveFieldExprType ( FieldExpr fe , TypePath path ) {
1132+ private Type resolveFieldExprType0 ( FieldExpr fe , TypePath path ) {
10391133 exists ( RecordField f |
10401134 f = resolveRecordFieldExpr ( fe ) and
10411135 result = f .getTypeRepr ( ) .( TypeRepr_ ) .resolveTypeAt ( path ) and
0 commit comments