Пример #1
0
        public static void PlasmaRegisterAll(this IMetaWriter writer)
        {
            // todo - fetch external references!!
            var assemblies = AppDomain.CurrentDomain.GetAssemblies()
                             .Where(x =>
                                    !x.Location.ToLowerInvariant().StartsWith(Path.GetTempPath().ToLowerInvariant()) &&
                                    !x.FullName.StartsWith("System") &&
                                    !x.FullName.StartsWith("Microsoft.") &&
                                    !x.FullName.StartsWith("mscorlib") &&
                                    !x.FullName.StartsWith("MetaCreator") &&
                                    !x.FullName.StartsWith("Plasma,") &&
                                    !x.FullName.StartsWith("Plasma ") &&
                                    !x.FullName.StartsWith("Accessibility,")
#if !NET3
                                    && !x.IsDynamic    // not sure
#endif
                                    );

#if DEBUG
            foreach (var assembly in assemblies)
            {
                writer.WriteLine("// " + assembly.FullName);                 // + " IsDynamic:" + assembly.IsDynamic + " HostContext:" + assembly.HostContext + " Location:" + assembly.Location);
            }
#endif
            PlasmaRegisterAssembly(writer, assemblies.ToArray());
        }
Пример #2
0
 /// <summary>
 /// Generate code necessary to prepare registers for working with types collected
 /// </summary>
 public override void Write(IMetaWriter writer)
 {
     foreach (var kvp in _result)
     {
         if (kvp.Value.Res != null)
         {
             writer.WriteLine("{2}.Register<{0}, {1}>();", kvp.Key, kvp.Value.Res, typeof(FaceImplRegister));
         }
         else if (kvp.Value.Ex != null)
         {
             writer.WriteLine("#warning " + kvp.Value.Ex.Message);
             writer.WriteLine("/*");
             writer.WriteLine(ExceptionAnalyzer.ExceptionDetails(kvp.Value.Ex));
             writer.WriteLine("*/");
         }
     }
 }
Пример #3
0
 public override void Write(IMetaWriter writer)
 {
     foreach (var result in _result)
     {
         if (result.Value.FactoryCode != null || result.Value.FactoryFactoryCode != null)
         {
             writer.WriteLine("{2}.Add<{0}>({1});", result.Key, result.Value.FactoryFactoryCode ?? result.Value.FactoryCode, typeof(TypeFactoryRegister));
         }
         else if (result.Value.Ex != null)
         {
             writer.WriteLine("#warning " + result.Value.Ex.Message);
             writer.WriteLine("/*");
             writer.WriteLine(ExceptionAnalyzer.ExceptionDetails(result.Value.Ex));
             writer.WriteLine("*/");
         }
     }
 }
Пример #4
0
 public static void PlasmaRegisterType(this IMetaWriter writer, Type type)
 {
     if (PlasmaContainer.IsValidImplementationType(type))
     {
         writer.WriteLine("// " + type.CSharpTypeIdentifier());
         _context.Types.Add(type);
     }
 }
Пример #5
0
        /// <summary>
        /// Generate code necessary to prepare registers for working with types collected
        /// </summary>
        public override void Write(IMetaWriter writer)
        {
            foreach (var type in _result)
            {
                if (type.Value)
                {
                    var plumbingPros = PlasmaContainer.GetPlumbingProperties(type.Key).ToArray();
                    var plumbingc    = "";
                    foreach (var pi in plumbingPros)
                    {
                        plumbingc += string.Format("\tx.{0} = {1};\r\n", pi.Name, _mining.GetArgument(pi));
                    }
                    // todo remove extra cast in plumber
                    // todo remove dependancy on 'c'
                    writer.WriteLine(@"{2}.Register<{0}>((c, x)=>{{
{1}}});", type.Key, plumbingc, typeof(TypeAutoPlumberRegister));
                }
                else
                {
                    writer.WriteLine("{1}.RegisterNone(typeof({0}));", type.Key, typeof(TypeAutoPlumberRegister));
                }
            }
        }
Пример #6
0
        public void Generate(IMetaWriter writer, Type type)
        {
            _writer = writer;
            _type   = type;

            writer.WriteLine("// iface - " + type.Name);
            //			writer.WriteLine("// all ifaces - " + string.Join(", ", Mining.GetAllIfaces(type).Distinct().Select(x => x.Name)));

            var members = type.GetMembers(BindingFlags.Public | BindingFlags.Instance).Concat(Mining.GetAllIfaces(type).Distinct().SelectMany(x => x.GetMembers())).ToArray();

//			if (!members.Any())
//			{
//				return;
//			}

            var names = GetTypeName(type);

            _typeShortName        = names.Name;
            _typeShortNameGeneric = names.NameGeneric;
            _typeFullNameGeneric  = names.FullNameGeneric;

            writer.WriteLine("public class {0} : {2} {1}", _typeShortNameGeneric, type.CSharpTypeIdentifier(), string.Format(BaseClass, type.CSharpTypeIdentifier()));
            writer.WriteLine("{");

            BeforeMembers();

            var methods = members.Where(x => x.MemberType == MemberTypes.Method).Cast <MethodInfo>().Where(x => !x.IsSpecialName).ToArray();

            foreach (var method in methods)
            {
                if (methods.Count(x => x.Name == method.Name) > 1 /* && method.ReturnType == typeof(object) */)                 // todo improve by comparing signature, not just name
                {
                    writer.Write("\t{0} {4}.{1}{2}({3})", method.ReturnType.CSharpTypeIdentifier(), method.Name, null, string.Join(", ", method.GetParameters().Select(x => x.CSharpTypeIdentifier() + " " + x.Name).ToArray()), method.DeclaringType.CSharpTypeIdentifier());
                }
                else
                {
                    writer.Write("\tpublic virtual {0} {1}{2}({3})", method.ReturnType.CSharpTypeIdentifier(), method.Name, null, string.Join(", ", method.GetParameters().Select(x => x.CSharpTypeIdentifier() + " " + x.Name).ToArray()));
                }


                writer.Write(" { ");
                WriteMethodBody(method);
                writer.WriteLine(" }");
            }

            foreach (var eventInfo in members.Where(x => x.MemberType == MemberTypes.Event).Cast <EventInfo>())
            {
                writer.Write("\tpublic virtual event {0} {1}", eventInfo.EventHandlerType.CSharpTypeIdentifier(), eventInfo.Name);
                writer.Write(" { ");
                writer.Write(" add { ");
                WriteEventSubscriber(eventInfo);
                writer.Write(" }");
                writer.Write(" remove { ");
                WriteEventUnsubscriber(eventInfo);
                writer.Write(" }");
                writer.WriteLine(" }");
            }

            var pros = members.Where(x => x.MemberType == MemberTypes.Property).Cast <PropertyInfo>().ToArray();

            foreach (var pro in pros)
            {
                var isIndexer = pro.GetIndexParameters().Any();

                var indexerParameters = string.Join(", ", pro.GetIndexParameters().Select(x => x.ParameterType.CSharpTypeIdentifier() + " " + x.Name).ToArray());
                indexerParameters = indexerParameters.Any() ? " [" + indexerParameters + "]" : null;

                var indexerArguments = string.Join(", ", pro.GetIndexParameters().Select(x => x.Name).ToArray());
                indexerArguments = indexerArguments.Any() ? "[" + indexerArguments + "]" : null;

                var myProName = isIndexer ? "this" : pro.Name;
                var orProName = isIndexer ? "" : "." + pro.Name;

                if (pros.Count(x => x.Name == pro.Name) > 1 /* && pro.PropertyType == typeof(object)*/)                // todo improve by comparing signature, not just name. +not just object but all except several obvious cases
                {
                    writer.Write("\t{0} {3}.{1}{2}", pro.PropertyType.CSharpTypeIdentifier(), myProName, indexerParameters, pro.DeclaringType.CSharpTypeIdentifier());
                }
                else
                {
                    writer.Write("\tpublic virtual {0} {1}{2}", pro.PropertyType.CSharpTypeIdentifier(), myProName, indexerParameters);
                }

                writer.Write(" { ");
                if (pro.CanRead)
                {
                    writer.Write(" get { ");
                    if (isIndexer)
                    {
                        WriteIndexerGetter(pro, indexerArguments);
                    }
                    else
                    {
                        WritePropertyGetter(pro);
                    }
                    writer.Write(" }");
                }
                if (pro.CanWrite)
                {
                    writer.Write(" set { ");
                    if (isIndexer)
                    {
                        WriteIndexerSetter(pro, indexerArguments);
                    }
                    else
                    {
                        WritePropertySetter(pro);
                    }
                    writer.Write(" }");
                }
                writer.WriteLine(" }");
            }

            writer.WriteLine("}");
        }
Пример #7
0
        /// <summary>
        /// Finally write all code
        /// End your file with that line
        /// </summary>
        public static void PlasmaGenerate(this IMetaWriter writer)
        {
            #region PREPARE


            _writerTmp = writer;

            var ctx = new PlasmaContainer();

            // AssemblyAnalyzeCache.LoadAll(writer);

            AssemblyAnalyzeCache.AnalyzeImpls();

            // a set of types that is going to be asked from container
            var requests          = new HashSet <Type>(_context.Types);
            var requestsProcessed = new HashSet <Type>();

            var faceImpls = ctx.Get <FaceImplStrategy>();
            var factory   = ctx.Get <FactoryStrategy>();
            var plumbing  = ctx.Get <PlumbingStrategy>();

            var miner = ctx.Get <StaticMining>();
            miner.RequestByType += Miner_RequestByType;

            writer.WriteLine("// Analyze...");

            while (requests.Count > 0)
            {
                _requestsFromMiner.Clear();                 // not necessary - just to simplify debugging
                var fromFace  = faceImpls.GetRequests(requests).ToArray();
                var fromFact  = factory.GetRequests(requests).ToArray();
                var fromPlumb = plumbing.GetRequests(requests).ToArray();

                foreach (var request in requests)
                {
                    requestsProcessed.Add(request);
                }

                // new requests
                requests = new HashSet <Type>(fromFace.Concat(fromFact).Concat(fromPlumb).Concat(_requestsFromMiner).Except(requestsProcessed));
                writer.WriteLine("// New requests: {0}", string.Join(", ", requests.Select(x => x.CSharpTypeIdentifier())));
            }

            miner.RequestByType -= Miner_RequestByType;

            writer.WriteLine("// Analyze completed");

            #endregion

            #region Proxy

            if (_enableProxy)
            {
                foreach (var type in _context.Types.Where(x => x.IsInterface))
                {
                    _proxyGenerator.Generate(writer, type);
                    // GenerateStub(writer, type);
                }
            }

            #endregion

            #region Null

            if (_enableNullObject)
            {
                var req = _context.Types.Where(x => x.IsInterface);
                do
                {
                    foreach (var type in req.ToArray())
                    {
                        try
                        {
                            writer.Transactional(w => _nullGenerator.Generate(writer, type));
                        }
                        catch (Exception ex)
                        {
                            writer.WriteLine("#warning " + ex.Message);
                            writer.WriteLine("/*");
                            writer.WriteLine(ExceptionAnalyzer.ExceptionDetails(ex));
                            writer.WriteLine("*/");
                        }
                    }
                    req = _nullGenerator.RequestedObjects.Except(_nullGenerator.NullObjects).ToArray();
                    _nullGenerator.RequestedObjects.Clear();
                } while (req.Any());
            }

            #endregion

            writer.WriteLine(@"
public static partial class PlasmaRegistration
{{
	static volatile bool _executed;

	public static void Run({1}? reflectionPermission = null)
	{{
		if (_executed)
		{{
			return;
		}}
		_executed = true;
		{0}.DefaultReflectionPermission = reflectionPermission ?? {1}.Throw;
", typeof(PlasmaContainer), typeof(ReflectionPermission));
            writer.WriteLine();             // ignore tabs

            #region Factory

            writer.WriteLine();
            writer.WriteLine("// Factory ");

            factory.Write(writer);

            #endregion

            #region face impl

            writer.WriteLine();
            writer.WriteLine("// Iface impl");

            faceImpls.Write(writer);

            #endregion

            #region plumbers

            writer.WriteLine();
            writer.WriteLine("// Plumbers (Property injectors)");

            plumbing.Write(writer);

            #endregion

            #region null object register

            if (_enableNullObject)
            {
                foreach (var type in _nullGenerator.NullObjects.Concat(_nullGenerator.ExplicitRequests).Distinct())
                {
                    if (type.IsGenericType && type.IsGenericTypeDefinition)
                    {
                        writer.WriteLine(@"Null.RegisterGeneric(typeof({0}), t =>
	typeof ({1}).MakeGenericType(t).GetField(""Instance"").GetValue(null));"    , type.CSharpTypeIdentifier(_omitTypeDef), _nullGenerator.GetTypeName(type).FullNameGenericNoT);

                        //typeof (NullEnumerable<>).MakeGenericType(t).GetField("Instance").GetValue(null));
                    }
                    else
                    {
                        writer.WriteLine("Null.Register<{0}>({1}.Instance);", type, _nullGenerator.GetTypeName(type).FullNameGeneric);
                    }
                }
            }

            #endregion

            writer.WriteLine(@"
	}
}

");
        }