/// <summary> /// Scores the given constructor based on the number of dependencies we can fill. /// </summary> static int Rate(MethodBase constructor, TypeTracker typeTracker) { // Preserve the default behaviour of preferring explicitly marked constructors. if (constructor.IsDefined(typeof(InjectionConstructorAttribute), false)) return int.MaxValue; var score = 0; foreach (var parameter in constructor.GetParameters()) { if(parameter.IsOut || parameter.IsRetval) return -1; if (typeTracker.HasDependency(parameter.ParameterType)) { score++; } else { // We don't know how to fill this parameter so try a different constructor return -1; } } return score; }
/// <summary> /// Scores the given constructor based on the number of dependencies we can fill. /// </summary> static int Rate(MethodBase constructor, TypeTracker typeTracker) { // Preserve the default behaviour of preferring explicitly marked constructors. if (constructor.IsDefined(typeof(InjectionConstructorAttribute), false)) { return(int.MaxValue); } var score = 0; foreach (var parameter in constructor.GetParameters()) { if (parameter.IsOut || parameter.IsRetval) { return(-1); } if (typeTracker.HasDependency(parameter.ParameterType)) { score++; } else { // We don't know how to fill this parameter so try a different constructor return(-1); } } return(score); }
private static Type /*!*/ GetNonGenericType(TypeGroup /*!*/ self) { TypeTracker type = self.GetTypeForArity(0); if (type == null) { throw RubyExceptions.CreateTypeError("type group doesn't include non-generic type"); } return(type.Type); }
static ConstructorInfo SelectConstructor(Type target, TypeTracker typeTracker) { ConstructorInfo best = null; var bestScore = -1; foreach (var constructor in target.GetConstructors()) { var score = Rate(constructor, typeTracker); if(score > bestScore) { best = constructor; bestScore = score; } } return best; }
static ConstructorInfo SelectConstructor(Type target, TypeTracker typeTracker) { ConstructorInfo best = null; var bestScore = -1; foreach (var constructor in target.GetConstructors()) { var score = Rate(constructor, typeTracker); if (score > bestScore) { best = constructor; bestScore = score; } } return(best); }
// friend: RubyContext // tracker: non-null => show members declared on the tracker internal RubyClass(RubyContext /*!*/ context, string name, Type type, object singletonClassOf, Action <RubyModule> initializer, RubyClass superClass, TypeTracker tracker, bool isRubyClass, bool isSingletonClass) : base(context, name, initializer, null, tracker) { Debug.Assert((superClass == null) == (type == typeof(object)), "All classes have a superclass, except for Object"); Debug.Assert(!isRubyClass || tracker == null, "Ruby class cannot have a tracker"); Debug.Assert(singletonClassOf != null || !isSingletonClass, "Singleton classes don't have a type"); Debug.Assert(superClass != this); _underlyingSystemType = type; _superClass = superClass; _isSingletonClass = isSingletonClass; _isRubyClass = isRubyClass; _singletonClassOf = singletonClassOf; if (superClass != null) { superClass.AddDependentModule(this); _structInfo = superClass._structInfo; } }
public static RubyModule /*!*/ Of(RubyContext /*!*/ context, TypeGroup /*!*/ self, [NotNullItems] params object /*!*/[] /*!*/ typeArgs) { TypeTracker tracker = self.GetTypeForArity(typeArgs.Length); if (tracker == null) { throw RubyExceptions.CreateArgumentError("Invalid number of type arguments for `{0}'", self.Name); } Type concreteType; if (typeArgs.Length > 0) { concreteType = tracker.Type.MakeGenericType(Protocols.ToTypes(context, typeArgs)); } else { concreteType = tracker.Type; } return(context.GetModule(concreteType)); }
public TypeTrackerPolicy(TypeTracker typeTracker) { TypeTracker = typeTracker; }
private bool TryGetLazyValue(string name, bool publish, out object value) { if (!_cleared) { MemberInfo[] members = NonHiddenMembers(GetMember(name)); if (members.Length > 0) { // we only support fields, methods, and nested types in modules. switch (members[0].MemberType) { case MemberTypes.Field: Debug.Assert(members.Length == 1); value = ((FieldInfo)members[0]).GetValue(null); if (publish) { LazyAdd(name, value); } return(true); case MemberTypes.Method: if (!((MethodInfo)members[0]).IsSpecialName) { value = BuiltinFunction.MakeFunction( name, ArrayUtils.ConvertAll <MemberInfo, MethodInfo>(members, delegate(MemberInfo mi) { return((MethodInfo)mi); }), members[0].DeclaringType ); if (publish) { LazyAdd(name, value); } return(true); } break; case MemberTypes.Property: Debug.Assert(members.Length == 1); value = ((PropertyInfo)members[0]).GetValue(null, ArrayUtils.EmptyObjects); if (publish) { LazyAdd(name, value); } return(true); case MemberTypes.NestedType: if (members.Length == 1) { value = DynamicHelpers.GetPythonTypeFromType((Type)members[0]); } else { TypeTracker tt = (TypeTracker)MemberTracker.FromMemberInfo(members[0]); for (int i = 1; i < members.Length; i++) { tt = TypeGroup.UpdateTypeEntity(tt, (TypeTracker)MemberTracker.FromMemberInfo(members[i])); } value = tt; } if (publish) { LazyAdd(name, value); } return(true); } } } value = null; return(false); }
private static TacCompilation <Tin, TOut> Build <Tin, TOut>(IProject <Assembly, object> project) { var rootScope = project.RootScope; // I think we are actually not making an assembly, // just a type var extensionLookup = new WhoDefinedMemberByMethodlike(); var closureVisitor = new ClosureVisitor(extensionLookup, project.DependencyScope.Members.Values.Select(x => x.Value).ToHashSet()); rootScope.Convert(closureVisitor); var(memberKindVisitor, memberKindLookup) = MemberKindVisitor.Make(extensionLookup, project); rootScope.Convert(memberKindVisitor); memberKindVisitor.HandleDependencies(project.DependencyScope); var gens = new List <DebuggableILGenerator>(); var typeTracker = new TypePassTypeTracker(module.Value, gens); var typeVisitor = new TypeVisitor(typeTracker); rootScope.Convert(typeVisitor); typeVisitor.HandleDependencies(project); var typeTracker2 = typeTracker.CreateTypesAndProperties(); var dependenciesTypeBuider = module.Value.DefineType(AssemblerVisitor.GenerateName(), TypeAttributes.Public); foreach (var member in project.References) { dependenciesTypeBuider.DefineField(TypeTracker.ConvertName(member.Key.Name), typeTracker2.ResolvePossiblyPrimitive(member.Scope), FieldAttributes.Public); } var dependenciesType = dependenciesTypeBuider.CreateType() ?? throw new NullReferenceException("dependenciesTypeBuider.CreateType should not return null"); //var dependenciesType = typeTracker2.GetDependencyType(); var realizedMethodLookup = new RealizedMethodLookup(); var methodMakerVisitor = new MethodMakerVisitor(module.Value, extensionLookup, realizedMethodLookup, typeTracker2); rootScope.Convert(methodMakerVisitor); var conversionTypes = new ConcurrentIndexed <(System.Type, System.Type), TypeBuilder>(); var(assemblerVisitor, after) = AssemblerVisitor.Create( memberKindLookup, extensionLookup, typeTracker2, conversionTypes, module.Value, realizedMethodLookup, typeTracker2.ResolvePossiblyPrimitive(rootScope.EntryPoint.InputType), typeTracker2.ResolvePossiblyPrimitive(rootScope.EntryPoint.OutputType), gens, dependenciesType); rootScope.Convert(assemblerVisitor); //finish up // this is a bit sloppy, maybe disposable? after(); // we have to actually create the types realizedMethodLookup.CreateTypes(); assemblerVisitor.rootType.CreateType(); var yo = String.Join(Environment.NewLine, gens.Select(x => x.GetDeubbingSting())); // now I need to reflexively find my type and call main var complitation = (TacCompilation)(Assembly.Value.CreateInstance(assemblerVisitor.rootType.Name) ?? throw new NullReferenceException()); //var runtimeTypeCache = new ConcurrentIndexed<System.Type,IVerifiableType>(); //foreach (var type in typeTracker.GetTypes()) //{ // runtimeTypeCache.AddOrThrow(type.Value, type.Key); //} //foreach (var pair in conversionTypes) //{ // // the runtimeTypeCache shouldn't cause any trouble // // pair.Key.Item2 should all be root // runtimeTypeCache.AddOrThrow(pair.Value, runtimeTypeCache[pair.Key.Item2]); //} //complitation.addType = (type, tacType) => { typeTracker.typeCache.AddOrThrow(type, tacType); }; //complitation. //var wrapsAndImplementsCache = new ConcurrentIndexed<(System.Type, System.Type), System.Type>(); //foreach (var conversion in conversionTypes) //{ // wrapsAndImplementsCache[conversion.Key] = conversion.Value; //} complitation.runTimeTypeTracker = typeTracker2.RunTimeTypeTracker(); var compType = complitation.GetType(); var dependenciesField = compType.GetField(nameof(TacCompilation <int, int, object> .dependencies)) ?? throw new NullReferenceException(); var dependencies = Activator.CreateInstance(dependenciesField.FieldType); dependenciesField.SetValue(complitation, dependencies); // A502902A-8EC8-4F5F-A55F-32E36F146762 this is a bit weird // it would be great if these didn't have to be wraped // the MSIL type could flow into the front end // and be picked up again on the backend foreach (var reference in project.References) { var field = dependenciesType.GetField(TypeTracker.ConvertName(reference.Key.Name)) ?? throw new NullReferenceException(); var setTo = AssemblyWalkerHelp.TryAssignOperationHelper_Cast(reference.Backing, typeTracker2.ResolvePossiblyPrimitive(reference.Scope), complitation.runTimeTypeTracker); field.SetValue(dependencies, setTo); } //complitation.indexerArray = assemblerVisitor.indexerList.indexers.ToArray(); //complitation.verifyableTypesArray = assemblerVisitor.verifyableTypesList.types.ToArray(); complitation.Init(); return((TacCompilation <Tin, TOut>)complitation); }