protected OOPEmulator CreateEmulator(ICompilation compilation, IErrorReporter errorReporter = null) {
			var n = new Namer();
			errorReporter = errorReporter ?? new MockErrorReporter();
			var md = new MetadataImporter(errorReporter, compilation, new CompilerOptions());
			md.Prepare(compilation.GetAllTypeDefinitions());
			var rtl = new RuntimeLibrary(md, errorReporter, compilation, n);
			return new OOPEmulator(compilation, md, rtl, n, new MockLinker(), errorReporter);
		}
		private void RunAutomaticMetadataAttributeAppliers(IAttributeStore store, ICompilation compilation) {
			var processors = new IAutomaticMetadataAttributeApplier[] { new MakeMembersWithScriptableAttributesReflectable(store) };
			foreach (var p in processors) {
				foreach (var asm in compilation.Assemblies)
					p.Process(asm);
				foreach (var t in compilation.GetAllTypeDefinitions())
					p.Process(t);
			}
		}
        private void RunAutomaticMetadataAttributeAppliers(IAttributeStore store, ICompilation compilation)
        {
            var processors = new IAutomaticMetadataAttributeApplier[] { new MakeMembersWithScriptableAttributesReflectable(store) };

            foreach (var p in processors)
            {
                foreach (var asm in compilation.Assemblies)
                {
                    p.Process(asm);
                }
                foreach (var t in compilation.GetAllTypeDefinitions())
                {
                    p.Process(t);
                }
            }
        }
        private void InitializeAttributeStore(AttributeStore attributeStore, WindsorContainer container, ICompilation compilation)
        {
            var assemblies = compilation.Assemblies;
            var types      = compilation.GetAllTypeDefinitions().ToList();

            foreach (var applier in container.ResolveAll <IAutomaticMetadataAttributeApplier>())
            {
                foreach (var a in assemblies)
                {
                    applier.Process(a);
                }
                foreach (var t in types)
                {
                    applier.Process(t);
                }
            }
            attributeStore.RunAttributeCode();
        }
        private void Prepare(string source, IRuntimeLibrary runtimeLibrary = null, bool expectErrors = false, bool MinimizeNames = false)
        {
            IProjectContent project = new CSharpProjectContent();
            var             parser  = new CSharpParser();

            using (var rdr = new StringReader(source)) {
                var pf = new CSharpUnresolvedFile()
                {
                    FileName = "File.cs"
                };
                var syntaxTree = parser.Parse(rdr, pf.FileName);
                syntaxTree.AcceptVisitor(new TypeSystemConvertVisitor(pf));
                project = project.AddOrUpdateFiles(pf);
            }
            project = project.AddAssemblyReferences(new[] { Files.Mscorlib, Files.Web, Files.Knockout });

            _compilation = project.CreateCompilation();

            var options = new CompilerOptions {
                MinimizeScript = MinimizeNames
            };

            _errorReporter = new MockErrorReporter(!expectErrors);
            var s = new AttributeStore(_compilation, _errorReporter);

            s.RunAttributeCode();
            _metadata = new MetadataImporter(_errorReporter, _compilation, s, options);

            _metadata.Prepare(_compilation.GetAllTypeDefinitions());

            _allErrors = _errorReporter.AllMessages.ToList().AsReadOnly();
            if (expectErrors)
            {
                Assert.That(_allErrors, Is.Not.Empty, "Compile should have generated errors");
            }
            else
            {
                Assert.That(_allErrors, Is.Empty, "Compile should not generate errors");
            }

            var rtl = new RuntimeLibrary(_metadata, _errorReporter, _compilation, new Namer(), s);
        }
Example #6
0
        IList <IType> FindTypesInBounds(IList <IType> lowerBounds, IList <IType> upperBounds)
        {
            // If there's only a single type; return that single type.
            // If both inputs are empty, return the empty list.
            if (lowerBounds.Count == 0 && upperBounds.Count <= 1)
            {
                return(upperBounds);
            }
            if (upperBounds.Count == 0 && lowerBounds.Count <= 1)
            {
                return(lowerBounds);
            }
            if (nestingLevel > maxNestingLevel)
            {
                return(EmptyList <IType> .Instance);
            }

            // Finds a type X so that "LB <: X <: UB"
            Log.WriteCollection("FindTypesInBound, LowerBounds=", lowerBounds);
            Log.WriteCollection("FindTypesInBound, UpperBounds=", upperBounds);

            // First try the Fixing algorithm from the C# spec (ยง7.5.2.11)
            List <IType> candidateTypes = lowerBounds.Union(upperBounds)
                                          .Where(c => lowerBounds.All(b => conversions.ImplicitConversion(b, c).IsValid))
                                          .Where(c => upperBounds.All(b => conversions.ImplicitConversion(c, b).IsValid))
                                          .ToList(); // evaluate the query only once

            Log.WriteCollection("FindTypesInBound, Candidates=", candidateTypes);

            // According to the C# specification, we need to pick the most specific
            // of the candidate types. (the type which has conversions to all others)
            // However, csc actually seems to choose the least specific.
            candidateTypes = candidateTypes.Where(
                c => candidateTypes.All(o => conversions.ImplicitConversion(o, c).IsValid)
                ).ToList();

            // If the specified algorithm produces a single candidate, we return
            // that candidate.
            // We also return the whole candidate list if we're not using the improved
            // algorithm.
            if (candidateTypes.Count == 1 || !(algorithm == TypeInferenceAlgorithm.Improved || algorithm == TypeInferenceAlgorithm.ImprovedReturnAllResults))
            {
                return(candidateTypes);
            }
            candidateTypes.Clear();

            // Now try the improved algorithm
            Log.Indent();
            List <ITypeDefinition> candidateTypeDefinitions;

            if (lowerBounds.Count > 0)
            {
                // Find candidates by using the lower bounds:
                var hashSet = new HashSet <ITypeDefinition>(lowerBounds[0].GetAllBaseTypeDefinitions());
                for (int i = 1; i < lowerBounds.Count; i++)
                {
                    hashSet.IntersectWith(lowerBounds[i].GetAllBaseTypeDefinitions());
                }
                candidateTypeDefinitions = hashSet.ToList();
            }
            else
            {
                // Find candidates by looking at all classes in the project:
                candidateTypeDefinitions = compilation.GetAllTypeDefinitions().ToList();
            }

            // Now filter out candidates that violate the upper bounds:
            foreach (IType ub in upperBounds)
            {
                ITypeDefinition ubDef = ub.GetDefinition();
                if (ubDef != null)
                {
                    candidateTypeDefinitions.RemoveAll(c => !c.IsDerivedFrom(ubDef));
                }
            }

            foreach (ITypeDefinition candidateDef in candidateTypeDefinitions)
            {
                // determine the type parameters for the candidate:
                IType candidate;
                if (candidateDef.TypeParameterCount == 0)
                {
                    candidate = candidateDef;
                }
                else
                {
                    Log.WriteLine("Inferring arguments for candidate type definition: " + candidateDef);
                    bool    success;
                    IType[] result = InferTypeArgumentsFromBounds(
                        candidateDef.TypeParameters,
                        new ParameterizedType(candidateDef, candidateDef.TypeParameters),
                        lowerBounds, upperBounds,
                        out success);
                    if (success)
                    {
                        candidate = new ParameterizedType(candidateDef, result);
                    }
                    else
                    {
                        Log.WriteLine("Inference failed; ignoring candidate");
                        continue;
                    }
                }
                Log.WriteLine("Candidate type: " + candidate);

                if (upperBounds.Count == 0)
                {
                    // if there were only lower bounds, we aim for the most specific candidate:

                    // if this candidate isn't made redundant by an existing, more specific candidate:
                    if (!candidateTypes.Any(c => c.GetDefinition().IsDerivedFrom(candidateDef)))
                    {
                        // remove all existing candidates made redundant by this candidate:
                        candidateTypes.RemoveAll(c => candidateDef.IsDerivedFrom(c.GetDefinition()));
                        // add new candidate
                        candidateTypes.Add(candidate);
                    }
                }
                else
                {
                    // if there were upper bounds, we aim for the least specific candidate:

                    // if this candidate isn't made redundant by an existing, less specific candidate:
                    if (!candidateTypes.Any(c => candidateDef.IsDerivedFrom(c.GetDefinition())))
                    {
                        // remove all existing candidates made redundant by this candidate:
                        candidateTypes.RemoveAll(c => c.GetDefinition().IsDerivedFrom(candidateDef));
                        // add new candidate
                        candidateTypes.Add(candidate);
                    }
                }
            }
            Log.Unindent();
            return(candidateTypes);
        }
Example #7
0
        public IEnumerable<JsType> Compile(PreparedCompilation compilation)
        {
            _compilation = compilation.Compilation;

            _metadataImporter.Prepare(_compilation.GetAllTypeDefinitions(), _compilation.MainAssembly, _errorReporter);

            _types = new Dictionary<ITypeDefinition, JsClass>();
            _constructorDeclarations = new HashSet<Tuple<ConstructorDeclaration, CSharpAstResolver>>();
            _instanceInitStatements = new Dictionary<JsClass, List<JsStatement>>();

            var unsupportedConstructsScanner = new UnsupportedConstructsScanner(_errorReporter, compilation.Compilation.ReferencedAssemblies.Count == 0);
            bool hasUnsupported = false;

            foreach (var f in compilation.SourceFiles) {
                try {
                    if (!AllowUnsupportedConstructs) {
                        if (!unsupportedConstructsScanner.ProcessAndReturnTrueIfEverythingIsSupported(f.SyntaxTree)) {
                            hasUnsupported = true;
                            continue;
                        }
                    }
                    _definedSymbols = f.DefinedSymbols;

                    _resolver = new CSharpAstResolver(_compilation, f.SyntaxTree, f.ParsedFile);
                    _resolver.ApplyNavigator(new ResolveAllNavigator());
                    f.SyntaxTree.AcceptVisitor(this);
                }
                catch (Exception ex) {
                    _errorReporter.Region = _currentNode.GetRegion();
                    _errorReporter.InternalError(ex);
                }
            }

            if (hasUnsupported)
                return new JsType[0];	// Just to be safe

            // Handle constructors. We must do this after we have visited all the compilation units because field initializer (which change the InstanceInitStatements and StaticInitStatements) might appear anywhere.
            foreach (var n in _constructorDeclarations) {
                try {
                    _resolver = n.Item2;
                    HandleConstructorDeclaration(n.Item1);
                }
                catch (Exception ex) {
                    _errorReporter.Region = n.Item1.GetRegion();
                    _errorReporter.InternalError(ex);
                }
            }

            // Add default constructors where needed.
            foreach (var toAdd in _types.Where(t => t.Value != null).SelectMany(kvp => kvp.Key.GetConstructors().Where(c => c.IsSynthetic).Select(c => new { jsClass = kvp.Value, c }))) {
                try {
                    MaybeAddDefaultConstructorToType(toAdd.jsClass, toAdd.c);
                }
                catch (Exception ex) {
                    _errorReporter.Region = toAdd.c.Region;
                    _errorReporter.InternalError(ex, "Error adding default constructor to type");
                }
            }

            _types.Values.Where(t => t != null).ForEach(t => t.Freeze());

            var enums = new List<JsType>();
            foreach (var e in _compilation.MainAssembly.TopLevelTypeDefinitions.SelectMany(SelfAndNested).Where(t => t.Kind == TypeKind.Enum)) {
                try {
                    enums.Add(ConvertEnum(e.GetDefinition()));
                }
                catch (Exception ex) {
                    _errorReporter.Region = e.GetDefinition().Region;
                    _errorReporter.InternalError(ex);
                }
            }

            return _types.Values.Concat(enums).Where(t => t != null);
        }
Example #8
0
		public ReadOnlyCollection<AssemblyNode> Analyze()
		{
			IUnresolvedAssembly[] loadedAssemblies = LoadAssemblies().ToArray();
			compilation = new SimpleCompilation(loadedAssemblies.First(), loadedAssemblies.Skip(1));
			
			assemblyMappings = new Dictionary<IAssembly, AssemblyNode>();
			namespaceMappings = new Dictionary<string, NamespaceNode>();
			typeMappings = new Dictionary<ITypeDefinition, TypeNode>();
			fieldMappings = new Dictionary<IField, FieldNode>();
			methodMappings = new Dictionary<IMethod, MethodNode>();
			propertyMappings = new Dictionary<IProperty, PropertyNode>();
			eventMappings = new Dictionary<IEvent, EventNode>();
			cecilMappings = new Dictionary<MemberReference, IEntity>();
			
			// first we have to read all types so every method, field or property has a container
			foreach (var type in compilation.GetAllTypeDefinitions()) {
				var tn = ReadType(type);
				
				foreach (var field in type.Fields) {
					var node = new FieldNode(field);
					fieldMappings.Add(field, node);
					var cecilObj = loader.GetCecilObject((IUnresolvedField)field.UnresolvedMember);
					if (cecilObj != null)
						cecilMappings[cecilObj] = field;
					tn.AddChild(node);
				}
				
				foreach (var method in type.Methods) {
					var node = new MethodNode(method);
					methodMappings.Add(method, node);
					var cecilObj = loader.GetCecilObject((IUnresolvedMethod)method.UnresolvedMember);
					if (cecilObj != null)
						cecilMappings[cecilObj] = method;
					tn.AddChild(node);
				}
				
				foreach (var property in type.Properties) {
					var node = new PropertyNode(property);
					propertyMappings.Add(property, node);
					var cecilPropObj = loader.GetCecilObject((IUnresolvedProperty)property.UnresolvedMember);
					if (cecilPropObj != null)
						cecilMappings[cecilPropObj] = property;
					if (property.CanGet) {
						var cecilMethodObj = loader.GetCecilObject((IUnresolvedMethod)property.Getter.UnresolvedMember);
						if (cecilMethodObj != null)
							cecilMappings[cecilMethodObj] = property;
					}
					if (property.CanSet) {
						var cecilMethodObj = loader.GetCecilObject((IUnresolvedMethod)property.Setter.UnresolvedMember);
						if (cecilMethodObj != null)
							cecilMappings[cecilMethodObj] = property;
					}
					tn.AddChild(node);
				}
				
				foreach (var @event in type.Events) {
					var node = new EventNode(@event);
					eventMappings.Add(@event, node);
					var cecilObj = loader.GetCecilObject((IUnresolvedEvent)@event.UnresolvedMember);
					if (cecilObj != null)
						cecilMappings[cecilObj] = @event;
					if (@event.CanAdd) {
						var cecilMethodObj = loader.GetCecilObject((IUnresolvedMethod)@event.AddAccessor.UnresolvedMember);
						if (cecilMethodObj != null)
							cecilMappings[cecilMethodObj] = @event;
					}
					if (@event.CanInvoke) {
						var cecilMethodObj = loader.GetCecilObject((IUnresolvedMethod)@event.InvokeAccessor.UnresolvedMember);
						if (cecilMethodObj != null)
							cecilMappings[cecilMethodObj] = @event;
					}
					if (@event.CanRemove) {
						var cecilMethodObj = loader.GetCecilObject((IUnresolvedMethod)@event.RemoveAccessor.UnresolvedMember);
						if (cecilMethodObj != null)
							cecilMappings[cecilMethodObj] = @event;
					}
					tn.AddChild(node);
				}
			}
			
			ILAnalyzer analyzer = new ILAnalyzer(loadedAssemblies.Select(asm => loader.GetCecilObject(asm)).ToArray(), this);
			int count = typeMappings.Count + methodMappings.Count + fieldMappings.Count + propertyMappings.Count;
			int i  = 0;
			
			foreach (var element in typeMappings) {
				ReportProgress(++i / (double)count);
				AddRelationshipsForTypes(element.Key.DirectBaseTypes, element.Value);
				AddRelationshipsForAttributes(element.Key.Attributes, element.Value);
				CreateEdges(element.Value);
			}
			
			foreach (var element in methodMappings) {
				ReportProgress(++i / (double)count);
				var cecilObj = loader.GetCecilObject((IUnresolvedMethod)element.Key.UnresolvedMember);
				if (cecilObj != null)
					analyzer.Analyze(cecilObj.Body, element.Value);
				var node = element.Value;
				var method = element.Key;
				AddRelationshipsForType(node, method.ReturnType);
				AddRelationshipsForAttributes(method.Attributes, node);
				AddRelationshipsForAttributes(method.ReturnTypeAttributes, node);
				AddRelationshipsForTypeParameters(method.TypeParameters, node);
				foreach (var param in method.Parameters) {
					AddRelationshipsForType(node, param.Type);
					AddRelationshipsForAttributes(param.Attributes, node);
				}
				CreateEdges(element.Value);
			}
			
			foreach (var element in fieldMappings) {
				ReportProgress(++i / (double)count);
				var node = element.Value;
				var field = element.Key;
				AddRelationshipsForType(node, field.Type);
				AddRelationshipsForAttributes(field.Attributes, node);
				CreateEdges(element.Value);
			}
			
			foreach (var element in propertyMappings) {
				ReportProgress(++i / (double)count);
				var node = element.Value;
				var property = element.Key;
				if (property.CanGet) {
					var cecilObj = loader.GetCecilObject((IUnresolvedMethod)element.Key.Getter.UnresolvedMember);
					if (cecilObj != null)
						analyzer.Analyze(cecilObj.Body, node);
				}
				if (property.CanSet) {
					var cecilObj = loader.GetCecilObject((IUnresolvedMethod)element.Key.Setter.UnresolvedMember);
					if (cecilObj != null)
						analyzer.Analyze(cecilObj.Body, node);
				}
				AddRelationshipsForType(node, property.ReturnType);
				AddRelationshipsForAttributes(property.Attributes, node);
				CreateEdges(element.Value);
			}
			
			foreach (var element in eventMappings) {
				ReportProgress(++i / (double)count);
				var node = element.Value;
				var @event = element.Key;
				if (@event.CanAdd) {
					var cecilObj = loader.GetCecilObject((IUnresolvedMethod)@event.AddAccessor.UnresolvedMember);
					if (cecilObj != null)
						analyzer.Analyze(cecilObj.Body, node);
				}
				if (@event.CanInvoke) {
					var cecilObj = loader.GetCecilObject((IUnresolvedMethod)@event.InvokeAccessor.UnresolvedMember);
					if (cecilObj != null)
						analyzer.Analyze(cecilObj.Body, node);
				}
				if (@event.CanRemove) {
					var cecilObj = loader.GetCecilObject((IUnresolvedMethod)@event.RemoveAccessor.UnresolvedMember);
					if (cecilObj != null)
						analyzer.Analyze(cecilObj.Body, node);
				}
				AddRelationshipsForType(node, @event.ReturnType);
				AddRelationshipsForAttributes(@event.Attributes, node);
				CreateEdges(element.Value);
			}
			
			return new ReadOnlyCollection<AssemblyNode>(assemblyMappings.Values.ToList());
		}
        public IEnumerable <JsType> Compile(PreparedCompilation compilation)
        {
            _compilation = compilation.Compilation;

            _metadataImporter.Prepare(_compilation.GetAllTypeDefinitions(), _compilation.MainAssembly, _errorReporter);

            _types = new Dictionary <ITypeDefinition, JsClass>();
            _constructorDeclarations = new HashSet <Tuple <ConstructorDeclaration, CSharpAstResolver> >();
            _instanceInitStatements  = new Dictionary <JsClass, List <JsStatement> >();

            foreach (var f in compilation.SourceFiles)
            {
                try {
                    _definedSymbols = f.DefinedSymbols;

                    _resolver = new CSharpAstResolver(_compilation, f.SyntaxTree, f.ParsedFile);
                    _resolver.ApplyNavigator(new ResolveAllNavigator());
                    f.SyntaxTree.AcceptVisitor(this);
                }
                catch (Exception ex) {
                    _errorReporter.Region = _currentNode.GetRegion();
                    _errorReporter.InternalError(ex);
                }
            }

            // Handle constructors. We must do this after we have visited all the compilation units because field initializer (which change the InstanceInitStatements and StaticInitStatements) might appear anywhere.
            foreach (var n in _constructorDeclarations)
            {
                try {
                    _resolver = n.Item2;
                    HandleConstructorDeclaration(n.Item1);
                }
                catch (Exception ex) {
                    _errorReporter.Region = n.Item1.GetRegion();
                    _errorReporter.InternalError(ex);
                }
            }

            // Add default constructors where needed.
            foreach (var toAdd in _types.Where(t => t.Value != null).SelectMany(kvp => kvp.Key.GetConstructors().Where(c => c.IsSynthetic).Select(c => new { jsClass = kvp.Value, c })))
            {
                try {
                    MaybeAddDefaultConstructorToType(toAdd.jsClass, toAdd.c);
                }
                catch (Exception ex) {
                    _errorReporter.Region = toAdd.c.Region;
                    _errorReporter.InternalError(ex, "Error adding default constructor to type");
                }
            }

            _types.Values.Where(t => t != null).ForEach(t => t.Freeze());

            var enums = new List <JsType>();

            foreach (var e in _compilation.MainAssembly.TopLevelTypeDefinitions.SelectMany(SelfAndNested).Where(t => t.Kind == TypeKind.Enum))
            {
                try {
                    enums.Add(ConvertEnum(e.GetDefinition()));
                }
                catch (Exception ex) {
                    _errorReporter.Region = e.GetDefinition().Region;
                    _errorReporter.InternalError(ex);
                }
            }

            return(_types.Values.Concat(enums).Where(t => t != null));
        }
		private void InitializeAttributeStore(AttributeStore attributeStore, WindsorContainer container, ICompilation compilation) {
			var assemblies = compilation.Assemblies;
			var types = compilation.GetAllTypeDefinitions().ToList();
			foreach (var applier in container.ResolveAll<IAutomaticMetadataAttributeApplier>()) {
				foreach (var a in assemblies)
					applier.Process(a);
				foreach (var t in types)
					applier.Process(t);
			}
			attributeStore.RunAttributeCode();
		}
        private void Prepare(string source, IRuntimeLibrary runtimeLibrary = null, bool expectErrors = false, bool MinimizeNames = false)
        {
            IProjectContent project = new CSharpProjectContent();
            var parser = new CSharpParser();

            using (var rdr = new StringReader(source)) {
                var pf = new CSharpUnresolvedFile() { FileName = "File.cs" };
                var syntaxTree = parser.Parse(rdr, pf.FileName);
                syntaxTree.AcceptVisitor(new TypeSystemConvertVisitor(pf));
                project = project.AddOrUpdateFiles(pf);
            }
            project = project.AddAssemblyReferences(new[] { Files.Mscorlib, Files.Web, Files.Knockout });

            _compilation = project.CreateCompilation();

            var options = new CompilerOptions { MinimizeScript = MinimizeNames };
            _errorReporter = new MockErrorReporter(!expectErrors);
            var s = new AttributeStore(_compilation, _errorReporter);
            s.RunAttributeCode();
            _metadata = new MetadataImporter(_errorReporter, _compilation, s, options);

            _metadata.Prepare(_compilation.GetAllTypeDefinitions());

            _allErrors = _errorReporter.AllMessages.ToList().AsReadOnly();
            if (expectErrors) {
                Assert.That(_allErrors, Is.Not.Empty, "Compile should have generated errors");
            }
            else {
                Assert.That(_allErrors, Is.Empty, "Compile should not generate errors");
            }

            var rtl = new RuntimeLibrary(_metadata, _errorReporter, _compilation, new Namer(), s);
        }
        public ReadOnlyCollection <AssemblyNode> Analyze()
        {
            IUnresolvedAssembly[] loadedAssemblies = LoadAssemblies().ToArray();
            compilation = new SimpleCompilation(loadedAssemblies.First(), loadedAssemblies.Skip(1));

            assemblyMappings  = new Dictionary <IAssembly, AssemblyNode>();
            namespaceMappings = new Dictionary <string, NamespaceNode>();
            typeMappings      = new Dictionary <ITypeDefinition, TypeNode>();
            fieldMappings     = new Dictionary <IField, FieldNode>();
            methodMappings    = new Dictionary <IMethod, MethodNode>();
            propertyMappings  = new Dictionary <IProperty, PropertyNode>();
            eventMappings     = new Dictionary <IEvent, EventNode>();
            cecilMappings     = new Dictionary <MemberReference, IEntity>();

            // first we have to read all types so every method, field or property has a container
            foreach (var type in compilation.GetAllTypeDefinitions())
            {
                var tn = ReadType(type);

                foreach (var field in type.Fields)
                {
                    var node = new FieldNode(field);
                    fieldMappings.Add(field, node);
                    var cecilObj = loader.GetCecilObject((IUnresolvedField)field.UnresolvedMember);
                    if (cecilObj != null)
                    {
                        cecilMappings[cecilObj] = field;
                    }
                    tn.AddChild(node);
                }

                foreach (var method in type.Methods)
                {
                    var node = new MethodNode(method);
                    methodMappings.Add(method, node);
                    var cecilObj = loader.GetCecilObject((IUnresolvedMethod)method.UnresolvedMember);
                    if (cecilObj != null)
                    {
                        cecilMappings[cecilObj] = method;
                    }
                    tn.AddChild(node);
                }

                foreach (var property in type.Properties)
                {
                    var node = new PropertyNode(property);
                    propertyMappings.Add(property, node);
                    var cecilPropObj = loader.GetCecilObject((IUnresolvedProperty)property.UnresolvedMember);
                    if (cecilPropObj != null)
                    {
                        cecilMappings[cecilPropObj] = property;
                    }
                    if (property.CanGet)
                    {
                        var cecilMethodObj = loader.GetCecilObject((IUnresolvedMethod)property.Getter.UnresolvedMember);
                        if (cecilMethodObj != null)
                        {
                            cecilMappings[cecilMethodObj] = property;
                        }
                    }
                    if (property.CanSet)
                    {
                        var cecilMethodObj = loader.GetCecilObject((IUnresolvedMethod)property.Setter.UnresolvedMember);
                        if (cecilMethodObj != null)
                        {
                            cecilMappings[cecilMethodObj] = property;
                        }
                    }
                    tn.AddChild(node);
                }

                foreach (var @event in type.Events)
                {
                    var node = new EventNode(@event);
                    eventMappings.Add(@event, node);
                    var cecilObj = loader.GetCecilObject((IUnresolvedEvent)@event.UnresolvedMember);
                    if (cecilObj != null)
                    {
                        cecilMappings[cecilObj] = @event;
                    }
                    if (@event.CanAdd)
                    {
                        var cecilMethodObj = loader.GetCecilObject((IUnresolvedMethod)@event.AddAccessor.UnresolvedMember);
                        if (cecilMethodObj != null)
                        {
                            cecilMappings[cecilMethodObj] = @event;
                        }
                    }
                    if (@event.CanInvoke)
                    {
                        var cecilMethodObj = loader.GetCecilObject((IUnresolvedMethod)@event.InvokeAccessor.UnresolvedMember);
                        if (cecilMethodObj != null)
                        {
                            cecilMappings[cecilMethodObj] = @event;
                        }
                    }
                    if (@event.CanRemove)
                    {
                        var cecilMethodObj = loader.GetCecilObject((IUnresolvedMethod)@event.RemoveAccessor.UnresolvedMember);
                        if (cecilMethodObj != null)
                        {
                            cecilMappings[cecilMethodObj] = @event;
                        }
                    }
                    tn.AddChild(node);
                }
            }

            ILAnalyzer analyzer = new ILAnalyzer(loadedAssemblies.Select(asm => loader.GetCecilObject(asm)).ToArray(), this);
            int        count    = typeMappings.Count + methodMappings.Count + fieldMappings.Count + propertyMappings.Count;
            int        i        = 0;

            foreach (var element in typeMappings)
            {
                ReportProgress(++i / (double)count);
                AddRelationshipsForTypes(element.Key.DirectBaseTypes, element.Value);
                AddRelationshipsForAttributes(element.Key.Attributes, element.Value);
                CreateEdges(element.Value);
            }

            foreach (var element in methodMappings)
            {
                ReportProgress(++i / (double)count);
                var cecilObj = loader.GetCecilObject((IUnresolvedMethod)element.Key.UnresolvedMember);
                if (cecilObj != null)
                {
                    analyzer.Analyze(cecilObj.Body, element.Value);
                }
                var node   = element.Value;
                var method = element.Key;
                AddRelationshipsForType(node, method.ReturnType);
                AddRelationshipsForAttributes(method.Attributes, node);
                AddRelationshipsForAttributes(method.ReturnTypeAttributes, node);
                AddRelationshipsForTypeParameters(method.TypeParameters, node);
                foreach (var param in method.Parameters)
                {
                    AddRelationshipsForType(node, param.Type);
                    AddRelationshipsForAttributes(param.Attributes, node);
                }
                CreateEdges(element.Value);
            }

            foreach (var element in fieldMappings)
            {
                ReportProgress(++i / (double)count);
                var node  = element.Value;
                var field = element.Key;
                AddRelationshipsForType(node, field.Type);
                AddRelationshipsForAttributes(field.Attributes, node);
                CreateEdges(element.Value);
            }

            foreach (var element in propertyMappings)
            {
                ReportProgress(++i / (double)count);
                var node     = element.Value;
                var property = element.Key;
                if (property.CanGet)
                {
                    var cecilObj = loader.GetCecilObject((IUnresolvedMethod)element.Key.Getter.UnresolvedMember);
                    if (cecilObj != null)
                    {
                        analyzer.Analyze(cecilObj.Body, node);
                    }
                }
                if (property.CanSet)
                {
                    var cecilObj = loader.GetCecilObject((IUnresolvedMethod)element.Key.Setter.UnresolvedMember);
                    if (cecilObj != null)
                    {
                        analyzer.Analyze(cecilObj.Body, node);
                    }
                }
                AddRelationshipsForType(node, property.ReturnType);
                AddRelationshipsForAttributes(property.Attributes, node);
                CreateEdges(element.Value);
            }

            foreach (var element in eventMappings)
            {
                ReportProgress(++i / (double)count);
                var node   = element.Value;
                var @event = element.Key;
                if (@event.CanAdd)
                {
                    var cecilObj = loader.GetCecilObject((IUnresolvedMethod)@event.AddAccessor.UnresolvedMember);
                    if (cecilObj != null)
                    {
                        analyzer.Analyze(cecilObj.Body, node);
                    }
                }
                if (@event.CanInvoke)
                {
                    var cecilObj = loader.GetCecilObject((IUnresolvedMethod)@event.InvokeAccessor.UnresolvedMember);
                    if (cecilObj != null)
                    {
                        analyzer.Analyze(cecilObj.Body, node);
                    }
                }
                if (@event.CanRemove)
                {
                    var cecilObj = loader.GetCecilObject((IUnresolvedMethod)@event.RemoveAccessor.UnresolvedMember);
                    if (cecilObj != null)
                    {
                        analyzer.Analyze(cecilObj.Body, node);
                    }
                }
                AddRelationshipsForType(node, @event.ReturnType);
                AddRelationshipsForAttributes(@event.Attributes, node);
                CreateEdges(element.Value);
            }

            return(new ReadOnlyCollection <AssemblyNode>(assemblyMappings.Values.ToList()));
        }