@@ -343,6 +343,8 @@ public override string ToString () {
343
343
}
344
344
345
345
public class JSFunctionExpression : JSExpression {
346
+ public readonly MethodTypeFactory MethodTypes ;
347
+
346
348
public readonly JSMethod Method ;
347
349
348
350
public readonly Dictionary < string , JSVariable > AllVariables ;
@@ -355,12 +357,14 @@ public class JSFunctionExpression : JSExpression {
355
357
356
358
public JSFunctionExpression (
357
359
JSMethod method , Dictionary < string , JSVariable > allVariables ,
358
- IEnumerable < JSVariable > parameters , JSBlockStatement body
360
+ IEnumerable < JSVariable > parameters , JSBlockStatement body ,
361
+ MethodTypeFactory methodTypes
359
362
) {
360
363
Method = method ;
361
364
AllVariables = allVariables ;
362
365
Parameters = parameters ;
363
366
Body = body ;
367
+ MethodTypes = methodTypes ;
364
368
}
365
369
366
370
public override IEnumerable < JSNode > Children {
@@ -390,7 +394,7 @@ public override bool Equals (object obj) {
390
394
391
395
public override TypeReference GetExpectedType ( TypeSystem typeSystem ) {
392
396
if ( Method != null ) {
393
- var delegateType = ConstructDelegateType ( Method . Reference , typeSystem ) ;
397
+ var delegateType = MethodTypes . Get ( Method . Reference , typeSystem ) ;
394
398
if ( delegateType == null )
395
399
return Method . Reference . ReturnType ;
396
400
else
@@ -895,59 +899,7 @@ public override void ReplaceChild (JSNode oldChild, JSNode newChild) {
895
899
}
896
900
897
901
public abstract class JSExpression : JSNode {
898
- protected struct MethodSignature {
899
- public readonly TypeReference ReturnType ;
900
- public readonly IEnumerable < TypeReference > ParameterTypes ;
901
- public readonly int ParameterCount ;
902
- private readonly int HashCode ;
903
-
904
- public MethodSignature ( TypeReference returnType , IEnumerable < TypeReference > parameterTypes ) {
905
- ReturnType = returnType ;
906
- ParameterTypes = parameterTypes ;
907
- ParameterCount = parameterTypes . Count ( ) ;
908
-
909
- HashCode = ReturnType . FullName . GetHashCode ( ) ^ ParameterCount ;
910
-
911
- int i = 0 ;
912
- foreach ( var p in ParameterTypes ) {
913
- HashCode ^= ( p . FullName . GetHashCode ( ) << i ) ;
914
- i += 1 ;
915
- }
916
- }
917
-
918
- public override int GetHashCode ( ) {
919
- return HashCode ;
920
- }
921
-
922
- public bool Equals ( MethodSignature rhs ) {
923
- if ( ! ILBlockTranslator . TypesAreEqual (
924
- ReturnType , rhs . ReturnType
925
- ) )
926
- return false ;
927
-
928
- if ( ParameterCount != rhs . ParameterCount )
929
- return false ;
930
-
931
- using ( var e1 = ParameterTypes . GetEnumerator ( ) )
932
- using ( var e2 = rhs . ParameterTypes . GetEnumerator ( ) )
933
- while ( e1 . MoveNext ( ) && e2 . MoveNext ( ) ) {
934
- if ( ! ILBlockTranslator . TypesAreEqual ( e1 . Current , e2 . Current ) )
935
- return false ;
936
- }
937
-
938
- return true ;
939
- }
940
-
941
- public override bool Equals ( object obj ) {
942
- if ( obj is MethodSignature )
943
- return Equals ( ( MethodSignature ) obj ) ;
944
- else
945
- return base . Equals ( obj ) ;
946
- }
947
- }
948
-
949
902
public static readonly JSNullExpression Null = new JSNullExpression ( ) ;
950
- protected static readonly ConcurrentCache < MethodSignature , TypeReference > MethodTypeCache = new ConcurrentCache < MethodSignature , TypeReference > ( ) ;
951
903
952
904
protected readonly IList < JSExpression > Values ;
953
905
@@ -1014,70 +966,6 @@ public static TypeReference SubstituteTypeArgs (ITypeInfoSource typeInfo, TypeRe
1014
966
return TypeAnalysis . SubstituteTypeArgs ( type , member ) ;
1015
967
}
1016
968
1017
- public static TypeReference ConstructDelegateType ( MethodReference method , TypeSystem typeSystem ) {
1018
- return ConstructDelegateType (
1019
- method . ReturnType ,
1020
- ( from p in method . Parameters select p . ParameterType ) ,
1021
- typeSystem
1022
- ) ;
1023
- }
1024
-
1025
- public static TypeReference ConstructDelegateType ( TypeReference returnType , IEnumerable < TypeReference > parameterTypes , TypeSystem typeSystem ) {
1026
- TypeReference result ;
1027
- var ptypes = parameterTypes . ToArray ( ) ;
1028
- var signature = new MethodSignature ( returnType , ptypes ) ;
1029
-
1030
- return MethodTypeCache . GetOrCreate (
1031
- signature , ( ) => {
1032
- TypeReference genericDelegateType ;
1033
-
1034
- var systemModule = typeSystem . Boolean . Resolve ( ) . Module ;
1035
- bool hasReturnType ;
1036
-
1037
- if ( ILBlockTranslator . TypesAreEqual ( typeSystem . Void , returnType ) ) {
1038
- hasReturnType = false ;
1039
- var name = String . Format ( "System.Action`{0}" , signature . ParameterCount ) ;
1040
- genericDelegateType = systemModule . GetType (
1041
- signature . ParameterCount == 0 ? "System.Action" : name
1042
- ) ;
1043
- } else {
1044
- hasReturnType = true ;
1045
- genericDelegateType = systemModule . GetType ( String . Format (
1046
- "System.Func`{0}" , signature . ParameterCount + 1
1047
- ) ) ;
1048
- }
1049
-
1050
- if ( genericDelegateType != null ) {
1051
- var git = new GenericInstanceType ( genericDelegateType ) ;
1052
- foreach ( var pt in ptypes )
1053
- git . GenericArguments . Add ( pt ) ;
1054
-
1055
- if ( hasReturnType )
1056
- git . GenericArguments . Add ( returnType ) ;
1057
-
1058
- return git ;
1059
- } else {
1060
- var baseType = systemModule . GetType ( "System.MulticastDelegate" ) ;
1061
-
1062
- var td = new TypeDefinition (
1063
- "JSIL.Meta" , "MethodSignature" , TypeAttributes . Class | TypeAttributes . NotPublic , baseType
1064
- ) ;
1065
- td . DeclaringType = baseType ;
1066
-
1067
- var invoke = new MethodDefinition (
1068
- "Invoke" , MethodAttributes . Public , returnType
1069
- ) ;
1070
- foreach ( var pt in ptypes )
1071
- invoke . Parameters . Add ( new ParameterDefinition ( pt ) ) ;
1072
-
1073
- td . Methods . Add ( invoke ) ;
1074
-
1075
- return td ;
1076
- }
1077
- }
1078
- ) ;
1079
- }
1080
-
1081
969
public override void ReplaceChild ( JSNode oldChild , JSNode newChild ) {
1082
970
if ( oldChild == null )
1083
971
throw new ArgumentNullException ( ) ;
@@ -1233,7 +1121,8 @@ public static bool TryMaterialize (JSILIdentifier jsil, JSExpression reference,
1233
1121
materialized = JSInvocationExpression . InvokeMethod (
1234
1122
invocation . JSType , new JSFakeMethod (
1235
1123
"GetReference" , new ByReferenceType ( jsm . Reference . ReturnType ) ,
1236
- ( from p in jsm . Reference . Parameters select p . ParameterType ) . ToArray ( )
1124
+ ( from p in jsm . Reference . Parameters select p . ParameterType ) . ToArray ( ) ,
1125
+ jsil . MethodTypes
1237
1126
) , invocation . ThisReference , invocation . Arguments . ToArray ( ) , true
1238
1127
) ;
1239
1128
return true ;
@@ -1501,10 +1390,6 @@ public override TypeReference GetExpectedType (TypeSystem typeSystem) {
1501
1390
if ( property != null )
1502
1391
return property . ReturnType ;
1503
1392
1504
- var method = Member as MethodInfo ;
1505
- if ( method != null )
1506
- return JSExpression . ConstructDelegateType ( method . Member , typeSystem ) ;
1507
-
1508
1393
return typeSystem . Void ;
1509
1394
}
1510
1395
}
@@ -2113,16 +1998,22 @@ public override bool IsConstant {
2113
1998
}
2114
1999
2115
2000
public class JSMethod : JSIdentifier {
2001
+ public readonly MethodTypeFactory MethodTypes ;
2002
+
2116
2003
public readonly IEnumerable < TypeReference > GenericArguments ;
2117
2004
public readonly MethodReference Reference ;
2118
2005
public readonly MethodInfo Method ;
2119
2006
2120
- public JSMethod ( MethodReference reference , MethodInfo method , IEnumerable < TypeReference > genericArguments = null ) {
2007
+ public JSMethod (
2008
+ MethodReference reference , MethodInfo method , MethodTypeFactory methodTypes ,
2009
+ IEnumerable < TypeReference > genericArguments = null
2010
+ ) {
2121
2011
if ( ( reference == null ) || ( method == null ) )
2122
2012
throw new ArgumentNullException ( ) ;
2123
2013
2124
2014
Reference = reference ;
2125
2015
Method = method ;
2016
+ MethodTypes = methodTypes ;
2126
2017
2127
2018
if ( genericArguments == null ) {
2128
2019
var gim = Reference as GenericInstanceMethod ;
@@ -2146,39 +2037,30 @@ public QualifiedMemberIdentifier QualifiedIdentifier {
2146
2037
}
2147
2038
2148
2039
public override TypeReference GetExpectedType ( TypeSystem typeSystem ) {
2149
- return ConstructDelegateType ( Reference , typeSystem ) ;
2040
+ return MethodTypes . Get ( Reference , typeSystem ) ;
2150
2041
}
2151
2042
}
2152
2043
2153
2044
public class JSFakeMethod : JSIdentifier {
2045
+ public readonly MethodTypeFactory MethodTypes ;
2046
+
2154
2047
public readonly string Name ;
2155
2048
public readonly TypeReference ReturnType ;
2156
2049
public readonly TypeReference [ ] ParameterTypes ;
2157
2050
2158
- public JSFakeMethod ( string name , TypeReference returnType , params TypeReference [ ] parameterTypes ) {
2051
+ public JSFakeMethod ( string name , TypeReference returnType , TypeReference [ ] parameterTypes , MethodTypeFactory methodTypes ) {
2159
2052
Name = name ;
2160
2053
ReturnType = returnType ;
2161
- ParameterTypes = parameterTypes ;
2162
-
2163
- /*
2164
- if (IsOpenGenericType(ReturnType))
2165
- throw new Exception("Open generic return type");
2166
- else if (parameterTypes.Any(IsOpenGenericType))
2167
- throw new Exception("Open generic parameter type");
2168
- */
2169
-
2170
- /*
2171
- if (ReturnType.IsGenericParameter || parameterTypes.Any((p) => p.IsGenericParameter))
2172
- throw new ArgumentException()
2173
- */
2054
+ ParameterTypes = parameterTypes ?? new TypeReference [ 0 ] ;
2055
+ MethodTypes = methodTypes ;
2174
2056
}
2175
2057
2176
2058
public override string Identifier {
2177
2059
get { return Name ; }
2178
2060
}
2179
2061
2180
2062
public override TypeReference GetExpectedType ( TypeSystem typeSystem ) {
2181
- return ConstructDelegateType (
2063
+ return MethodTypes . Get (
2182
2064
ReturnType , ParameterTypes , typeSystem
2183
2065
) ;
2184
2066
}
0 commit comments