protected virtual void WriteUserDefinedTypes(ModuleDefinition module, Func <bool> shouldCancel) { Mono.Collections.Generic.Collection <TypeDefinition> moduleTypes; if (!UserDefinedTypes.TryGetValue(module, out moduleTypes)) { throw new Exception("Module types not found."); } ProjectItemWriterFactory writerFactory = new ProjectItemWriterFactory(this.assembly, moduleTypes, this.projectFileManager, this.filePathsService, this.language.VSCodeFileExtension, this.targetDir); #if !NET35 CancellationTokenSource cts = new CancellationTokenSource(); ParallelOptions parallelOptions = new ParallelOptions() { CancellationToken = cts.Token, MaxDegreeOfParallelism = Environment.ProcessorCount }; try { Parallel.ForEach( moduleTypes, parallelOptions, (TypeDefinition type) => { try { if (shouldCancel()) { cts.Cancel(); return; } IProjectItemFileWriter itemWriter = writerFactory.GetProjectItemWriter(type); bool shouldBeXamlPartial = Utilities.ShouldBePartial(type) || this.projectFileManager.XamlFullNameToRelativePathMap.ContainsKey(type.FullName); if (shouldBeXamlPartial) { string typeName = type.FullName; if (this.xamlGeneratedFields.ContainsKey(typeName)) { this.xamlGeneratedFields[typeName].Add("_contentLoaded"); // Always present, not bound to any XAML element } else { this.xamlGeneratedFields.Add(typeName, new HashSet <string>(new string[1] { "_contentLoaded" })); // Always present, not bound to any XAML element } } List <WritingInfo> writingInfos; string theCodeString; bool exceptionsWhileDecompiling = WriteTypeToFile(type, itemWriter, this.xamlGeneratedFields, shouldBeXamlPartial, language, out writingInfos, out theCodeString); bool exceptionsWhileWriting = HasExceptionsWhileWriting(writingInfos); lock (writeTypesLock) { itemWriter.GenerateProjectItems(); Dictionary <MemberIdentifier, CodeSpan> mapping = null; if (this.fileGeneratedNotifier != null) { /// Create the mapping only when it's needed for the internal API. mapping = GenerateMemberMapping(this.assemblyPath, theCodeString, writingInfos); } IUniqueMemberIdentifier uniqueMemberIdentifier = new UniqueMemberIdentifier(module.FilePath, type.MetadataToken.ToInt32()); IFileGeneratedInfo args = new TypeGeneratedInfo(itemWriter.FullSourceFilePath, exceptionsWhileDecompiling, exceptionsWhileWriting, uniqueMemberIdentifier, mapping); this.OnProjectFileCreated(args); } } catch (Exception ex) { this.OnTypeWritingFailure(type.FullName, ex); if (this.projectNotifier != null) { this.projectNotifier.OnTypeWritingFailure(type.FullName, ex); } } }); } catch (OperationCanceledException e) { } #else for (int typeIndex = 0; typeIndex < moduleTypes.Count; typeIndex++) { if (shouldCancel()) { return; } TypeDefinition type = moduleTypes[typeIndex]; try { IProjectItemFileWriter itemWriter = writerFactory.GetProjectItemWriter(type); bool shouldBeXamlPartial = Utilities.ShouldBePartial(type) || this.projectFileManager.XamlFullNameToRelativePathMap.ContainsKey(type.FullName); if (shouldBeXamlPartial) { string typeName = type.FullName; if (xamlGeneratedFields.ContainsKey(typeName)) { xamlGeneratedFields[typeName].Add("_contentLoaded"); //Always present, not bound to any XAML element } else { xamlGeneratedFields.Add(typeName, new HashSet <string>(new string[1] { "_contentLoaded" })); //Always present, not bound to any XAML element } } List <WritingInfo> writingInfos; string typeCode; bool exceptionsWhileDecompiling = WriteTypeToFile(type, itemWriter, xamlGeneratedFields, shouldBeXamlPartial, language, out writingInfos, out typeCode); bool exceptionsWhileWriting = HasExceptionsWhileWriting(writingInfos); itemWriter.GenerateProjectItems(); Dictionary <MemberIdentifier, CodeSpan> mapping = GenerateMemberMapping(this.assemblyPath, typeCode, writingInfos); IUniqueMemberIdentifier uniqueMemberIdentifier = new UniqueMemberIdentifier(module.FilePath, type.MetadataToken.ToInt32()); IFileGeneratedInfo args = new TypeGeneratedInfo(itemWriter.FullSourceFilePath, exceptionsWhileDecompiling, exceptionsWhileWriting, uniqueMemberIdentifier, mapping); this.OnProjectFileCreated(args); } catch (Exception ex) { if (TypeWritingFailure != null) { TypeWritingFailure(this, type.FullName, ex); } } } #endif }
public bool WriteTypeToFile(TypeDefinition type, IProjectItemFileWriter itemWriter, Dictionary <string, ICollection <string> > membersToSkip, bool shouldBePartial, ILanguage language, out List <WritingInfo> writingInfos, out string theCodeString) { theCodeString = string.Empty; writingInfos = null; StringWriter theWriter = new StringWriter(); bool showCompilerGeneratedMembers = Utilities.IsVbInternalTypeWithoutRootNamespace(type) || Utilities.IsVbInternalTypeWithRootNamespace(type); IFormatter formatter = GetFormatter(theWriter); IWriterSettings settings = new WriterSettings(writeExceptionsAsComments: true, writeFullyQualifiedNames: decompilationPreferences.WriteFullNames, writeDocumentation: decompilationPreferences.WriteDocumentation, showCompilerGeneratedMembers: showCompilerGeneratedMembers, writeLargeNumbersInHex: decompilationPreferences.WriteLargeNumbersInHex); ILanguageWriter writer = language.GetWriter(formatter, this.exceptionFormater, settings); IWriterContextService writerContextService = this.GetWriterContextService(); writer.ExceptionThrown += OnExceptionThrown; writerContextService.ExceptionThrown += OnExceptionThrown; bool exceptionOccurred = false; try { if (!(writer is INamespaceLanguageWriter)) { writingInfos = writer.Write(type, writerContextService); } else { if (shouldBePartial) { writingInfos = (writer as INamespaceLanguageWriter).WritePartialTypeAndNamespaces(type, writerContextService, membersToSkip); } else { writingInfos = (writer as INamespaceLanguageWriter).WriteTypeAndNamespaces(type, writerContextService); } } this.RecordGeneratedFileData(type, itemWriter.FullSourceFilePath, theWriter, formatter, writerContextService, writingInfos); MemoryStream sourceFileStream = new MemoryStream(Encoding.UTF8.GetBytes(theWriter.ToString())); itemWriter.CreateProjectSourceFile(sourceFileStream); sourceFileStream.Close(); theWriter.Close(); } catch (Exception e) { exceptionOccurred = true; string[] exceptionMessageLines = exceptionFormater.Format(e, type.FullName, itemWriter.FullSourceFilePath); string exceptionMessage = string.Join(Environment.NewLine, exceptionMessageLines); string commentedExceptionMessage = language.CommentLines(exceptionMessage); itemWriter.CreateProjectSourceFile(new MemoryStream(Encoding.UTF8.GetBytes(commentedExceptionMessage))); OnExceptionThrown(this, e); } theCodeString = theWriter.ToString(); writer.ExceptionThrown -= OnExceptionThrown; writerContextService.ExceptionThrown -= OnExceptionThrown; return(exceptionOccurred || writerContextService.ExceptionsWhileDecompiling.Any()); }
public bool WriteTypeToFile(TypeDefinition type, IProjectItemFileWriter itemWriter, Dictionary<string, ICollection<string>> membersToSkip, bool shouldBePartial, ILanguage language, out List<WritingInfo> writingInfos, out string theCodeString) { theCodeString = string.Empty; writingInfos = null; StringWriter theWriter = new StringWriter(); IFormatter formatter = GetFormatter(theWriter); ILanguageWriter writer = language.GetWriter(formatter, this.exceptionFormater, true); IWriterContextService writerContextService = this.GetWriterContextService(); bool exceptionOccurred = false; try { bool showCompilerGeneratedMembers = Utilities.IsVbInternalTypeWithoutRootNamespace(type) || Utilities.IsVbInternalTypeWithRootNamespace(type); if (!(writer is INamespaceLanguageWriter)) { writingInfos = writer.Write(type, writerContextService, decompilationPreferences.WriteDocumentation, showCompilerGeneratedMembers); } else { if (shouldBePartial) { writingInfos = (writer as INamespaceLanguageWriter).WritePartialTypeAndNamespaces(type, writerContextService, showCompilerGeneratedMembers, decompilationPreferences.WriteFullNames, decompilationPreferences.WriteDocumentation, membersToSkip); } else { writingInfos = (writer as INamespaceLanguageWriter).WriteTypeAndNamespaces(type, writerContextService, decompilationPreferences.WriteDocumentation, showCompilerGeneratedMembers, decompilationPreferences.WriteFullNames); } } RecordGeneratedFileData(type, itemWriter.FullSourceFilePath, theWriter, formatter, writerContextService, writingInfos); MemoryStream sourceFileStream = new MemoryStream(Encoding.UTF8.GetBytes(theWriter.ToString())); itemWriter.CreateProjectSourceFile(sourceFileStream); sourceFileStream.Close(); theWriter.Close(); } catch (Exception e) { exceptionOccurred = true; string[] exceptionMessageLines = exceptionFormater.Format(e, type.FullName, itemWriter.FullSourceFilePath); string exceptionMessage = string.Join(Environment.NewLine, exceptionMessageLines); string commentedExceptionMessage = language.CommentLines(exceptionMessage); itemWriter.CreateProjectSourceFile(new MemoryStream(Encoding.UTF8.GetBytes(commentedExceptionMessage))); } theCodeString = theWriter.ToString(); return exceptionOccurred || writerContextService.ExceptionsWhileDecompiling.Any(); }