You've already forked linux-packaging-mono
Imported Upstream version 4.3.2.467
Former-commit-id: 9c2cb47f45fa221e661ab616387c9cda183f283d
This commit is contained in:
@ -139,6 +139,45 @@ namespace System.ServiceModel.Description
|
||||
return ret;
|
||||
}
|
||||
|
||||
internal static Type GetContractAssignableToInterfaces(Type given, Type [] givenInterfaces)
|
||||
{
|
||||
if ((given != null) && (givenInterfaces.Count() < 1))
|
||||
return null;
|
||||
Dictionary<Type,int> interfaceGraph = new Dictionary<Type,int> ();
|
||||
foreach (var smaller in givenInterfaces) {
|
||||
interfaceGraph [smaller] = 0;
|
||||
foreach (var bigger in givenInterfaces) {
|
||||
if (smaller.IsAssignableFrom (bigger)) {
|
||||
interfaceGraph [smaller]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<Type> possibleInterfaces = new List<Type> ();
|
||||
foreach (var node in interfaceGraph) {
|
||||
if (node.Value == 1) {
|
||||
possibleInterfaces.Add(node.Key);
|
||||
}
|
||||
}
|
||||
// For this purpose a contract is a set of interfaces. it is necessary to find the interface representative of rest of the set. It will be assignable to all of
|
||||
// the others but can only be assigned to by itself. This will give it count of ! in its slot in the interfaceGraph. To be a valid set there can be only one with a count of one
|
||||
// in its slot. More results in InvalidOperation exceptioni with ambigours error message, less means that the interface we want is the one passed in by the parameter given
|
||||
// and by returning null we give the callign method permission to use it..
|
||||
switch (possibleInterfaces.Count())
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
return possibleInterfaces [0];
|
||||
break;
|
||||
default:
|
||||
if (!given.IsInterface)
|
||||
throw new InvalidOperationException ("The contract type of " + given + " is ambiguous: can be either " + possibleInterfaces[0] + " or " + possibleInterfaces[1]);
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
internal static ContractDescription GetContractInternal (Type givenContractType, Type givenServiceType, Type serviceTypeForCallback)
|
||||
{
|
||||
if (givenContractType == null)
|
||||
@ -153,16 +192,12 @@ namespace System.ServiceModel.Description
|
||||
exactContractType = givenContractType;
|
||||
sca = contracts [givenContractType];
|
||||
} else {
|
||||
foreach (Type t in contracts.Keys)
|
||||
if (t.IsAssignableFrom(givenContractType)) {
|
||||
if (t.IsAssignableFrom (exactContractType)) // exact = IDerived, t = IBase
|
||||
continue;
|
||||
if (sca != null && (exactContractType == null || !exactContractType.IsAssignableFrom (t))) // t = IDerived, exact = IBase
|
||||
throw new InvalidOperationException ("The contract type of " + givenContractType + " is ambiguous: can be either " + exactContractType + " or " + t);
|
||||
exactContractType = t;
|
||||
sca = contracts [t];
|
||||
}
|
||||
Type[] contractTypes = contracts.Keys.ToArray() as Type [];
|
||||
exactContractType = GetContractAssignableToInterfaces(givenContractType, contractTypes);
|
||||
if (exactContractType != null)
|
||||
sca = contracts[exactContractType];
|
||||
}
|
||||
|
||||
if (exactContractType == null)
|
||||
exactContractType = givenContractType;
|
||||
if (sca == null) {
|
||||
@ -171,6 +206,7 @@ namespace System.ServiceModel.Description
|
||||
else
|
||||
return null; // no contract
|
||||
}
|
||||
|
||||
string name = sca.Name ?? exactContractType.Name;
|
||||
string ns = sca.Namespace ?? "http://tempuri.org/";
|
||||
|
||||
@ -197,17 +233,18 @@ namespace System.ServiceModel.Description
|
||||
*/
|
||||
|
||||
var inherited = new Collection<ContractDescription> ();
|
||||
foreach (var it in cd.ContractType.GetInterfaces ()) {
|
||||
var interfaces = cd.ContractType.GetInterfaces ();
|
||||
foreach (var it in interfaces ) {
|
||||
var icd = GetContractInternal (it, givenServiceType, null);
|
||||
if (icd != null)
|
||||
inherited.Add (icd);
|
||||
}
|
||||
|
||||
foreach (var icd in inherited) {
|
||||
foreach (var od in icd.Operations)
|
||||
if (!cd.Operations.Any(o => o.Name == od.Name && o.SyncMethod == od.SyncMethod &&
|
||||
o.BeginMethod == od.BeginMethod && o.InCallbackContract == od.InCallbackContract))
|
||||
foreach (var od in icd.Operations) {
|
||||
if (!cd.Operations.Any (o => o.Name == od.Name && o.SyncMethod == od.SyncMethod && o.BeginMethod == od.BeginMethod && o.InCallbackContract == od.InCallbackContract))
|
||||
cd.Operations.Add (od);
|
||||
}
|
||||
}
|
||||
|
||||
FillOperationsForInterface (cd, cd.ContractType, givenServiceType, false);
|
||||
|
Reference in New Issue
Block a user