/// <summary> /// Returns a list of CfgBlock that are handlers of the current block, handling an exception /// of the given type, or a subtype thereof. /// </summary> /// <param name="exception">Type of exception thrown. It is assumed that any actual subtype could be thrown</param> /// <returns>All handlers that could apply directly to this exception. /// In addition, if the method might not handle it, then the ExceptionExit block is /// part of this list.</returns> public System.Collections.IEnumerable/*CfgBlock*/ HandlersMatching(TypeNode exception) { ArrayList handlers = new ArrayList(); CfgBlock currentBlock = this; while (currentBlock != null) { CfgBlock handler = this.cfg.ExceptionHandler(currentBlock); if (handler == null || handler.Statements == null || handler.Statements.Count < 1) break; Catch stat = handler.Statements[0] as Catch; if (stat != null) { if (exception.IsAssignableTo(stat.Type)) { // handles exceptions completely handlers.Add(handler); break; } if (stat.Type.IsAssignableTo(exception)) { // handles part of it handlers.Add(handler); } currentBlock = handler; } else { // must be the Unwind block handlers.Add(handler); break; } } return handlers; }
private static bool IsSubclassOf(TypeNode t1, TypeNode t2) { Contract.Requires(t1 != null); if (t2 == null) return false; return t1.IsAssignableTo(t2); }
private static Method FindImplementedMethod(MethodList candidates, TypeNode targetTypeInstance) { if (candidates != null) { for (int i = 0; i < candidates.Count; i++) { var candidate = candidates[i]; if (candidate == null) continue; if (targetTypeInstance.IsAssignableTo(candidate.DeclaringType)) return candidate; } } return null; }
public static TypeNode LeastCommonAncestor(TypeNode t1, TypeNode t2) { if (t1.IsAssignableTo(t2)) { return t2; } // walk up t1 until assignable to t2 TypeNode frame = t1; while (frame != null) { if (t2.IsAssignableTo(frame)) { return frame; } frame = frame.BaseType; } // if we get here, we haven't found a common basetype. Return object return Cci.SystemTypes.Object; }
public bool TypeMatches(TypeNode t) { if (types == null || t == null) return true; foreach (TypeNode a in types) { if (a == null) return true; if (t.IsAssignableTo(a)) return true; } return false; }
/// <summary> /// This is used to see if a type and parameter are valid template arguments /// </summary> /// <param name="type">The type to check</param> /// <param name="parameter">The parameter to check</param> /// <returns>True if it is valid, false if not</returns> private static bool IsValidTemplateArgument(TypeNode type, TypeNode parameter) { if(type == null) throw new ArgumentNullException("type"); // Check that the parameter really is a type parameter ITypeParameter itp = parameter as ITypeParameter; if(itp == null) throw new ArgumentException("The 'parameter' argument is null or not an 'ITypeParameter'."); // Test constraints bool reference = ((itp.TypeParameterFlags & TypeParameterFlags.ReferenceTypeConstraint) > 0); if(reference && type.IsValueType) return (false); bool value = ((itp.TypeParameterFlags & TypeParameterFlags.ValueTypeConstraint) > 0); if(value && !type.IsValueType) return (false); InterfaceList contracts = parameter.Interfaces; if(contracts != null) foreach(Interface contract in contracts) if(!type.IsAssignableTo(contract)) return false; TypeNode parent = parameter.BaseType; if(parent != null && !type.IsAssignableTo(parent)) return false; // Okay, passed all tests return true; }