internal override void ValidateOptions(ArrayBuilder <Diagnostic> builder) { ValidateOptions(builder, MessageProvider.Instance); // Validate LanguageVersion not SpecifiedLanguageVersion, after Latest/Default has been converted: if (!LanguageVersion.IsValid()) { builder.Add( Diagnostic.Create( MessageProvider.Instance, (int)ErrorCode.ERR_BadLanguageVersion, LanguageVersion.ToString() ) ); } if (!PreprocessorSymbols.IsDefaultOrEmpty) { foreach (var symbol in PreprocessorSymbols) { if (symbol == null) { builder.Add( Diagnostic.Create( MessageProvider.Instance, (int)ErrorCode.ERR_InvalidPreprocessingSymbol, "null" ) ); } else if (!SyntaxFacts.IsValidIdentifier(symbol)) { builder.Add( Diagnostic.Create( MessageProvider.Instance, (int)ErrorCode.ERR_InvalidPreprocessingSymbol, symbol ) ); } } } }
public static string Translate(LanguageVersion Value) { string Name = "Undefined"; switch (Value.ToString()) { case "VB6": Name = "Visual Basic 6.0"; break; case "VB7": Name = "Visual Basic 2003"; break; case "VB8": Name = "Visual Basic 2005"; break; } return(Name); }
void WriteProjectFile(TextWriter writer, IEnumerable <Tuple <string, string> > files, Metadata.PEFile module) { const string ns = "http://schemas.microsoft.com/developer/msbuild/2003"; string platformName = GetPlatformName(module); Guid guid = this.ProjectGuid ?? Guid.NewGuid(); using (XmlTextWriter w = new XmlTextWriter(writer)) { w.Formatting = Formatting.Indented; w.WriteStartDocument(); w.WriteStartElement("Project", ns); w.WriteAttributeString("ToolsVersion", "4.0"); w.WriteAttributeString("DefaultTargets", "Build"); w.WriteStartElement("PropertyGroup"); w.WriteElementString("ProjectGuid", guid.ToString("B").ToUpperInvariant()); w.WriteStartElement("Configuration"); w.WriteAttributeString("Condition", " '$(Configuration)' == '' "); w.WriteValue("Debug"); w.WriteEndElement(); // </Configuration> w.WriteStartElement("Platform"); w.WriteAttributeString("Condition", " '$(Platform)' == '' "); w.WriteValue(platformName); w.WriteEndElement(); // </Platform> if (module.Reader.PEHeaders.IsDll) { w.WriteElementString("OutputType", "Library"); } else { switch (module.Reader.PEHeaders.PEHeader.Subsystem) { case Subsystem.WindowsGui: w.WriteElementString("OutputType", "WinExe"); break; case Subsystem.WindowsCui: w.WriteElementString("OutputType", "Exe"); break; default: w.WriteElementString("OutputType", "Library"); break; } } w.WriteElementString("LangVersion", LanguageVersion.ToString().Replace("CSharp", "").Replace('_', '.')); w.WriteElementString("AssemblyName", module.Name); bool useTargetFrameworkAttribute = false; LanguageTargets languageTargets = LanguageTargets.None; string targetFramework = module.Reader.DetectTargetFrameworkId(); if (!string.IsNullOrEmpty(targetFramework)) { string[] frameworkParts = targetFramework.Split(','); string frameworkIdentifier = frameworkParts.FirstOrDefault(a => !a.StartsWith("Version=", StringComparison.OrdinalIgnoreCase) && !a.StartsWith("Profile=", StringComparison.OrdinalIgnoreCase)); if (frameworkIdentifier != null) { w.WriteElementString("TargetFrameworkIdentifier", frameworkIdentifier); switch (frameworkIdentifier) { case ".NETPortable": languageTargets = LanguageTargets.Portable; break; } } string frameworkVersion = frameworkParts.FirstOrDefault(a => a.StartsWith("Version=", StringComparison.OrdinalIgnoreCase)); if (frameworkVersion != null) { w.WriteElementString("TargetFrameworkVersion", frameworkVersion.Substring("Version=".Length)); useTargetFrameworkAttribute = true; } string frameworkProfile = frameworkParts.FirstOrDefault(a => a.StartsWith("Profile=", StringComparison.OrdinalIgnoreCase)); if (frameworkProfile != null) { w.WriteElementString("TargetFrameworkProfile", frameworkProfile.Substring("Profile=".Length)); } } if (!useTargetFrameworkAttribute) { switch (module.GetRuntime()) { case Metadata.TargetRuntime.Net_1_0: w.WriteElementString("TargetFrameworkVersion", "v1.0"); break; case Metadata.TargetRuntime.Net_1_1: w.WriteElementString("TargetFrameworkVersion", "v1.1"); break; case Metadata.TargetRuntime.Net_2_0: w.WriteElementString("TargetFrameworkVersion", "v2.0"); // TODO: Detect when .NET 3.0/3.5 is required break; default: w.WriteElementString("TargetFrameworkVersion", "v4.0"); break; } } w.WriteElementString("WarningLevel", "4"); w.WriteElementString("AllowUnsafeBlocks", "True"); w.WriteEndElement(); // </PropertyGroup> w.WriteStartElement("PropertyGroup"); // platform-specific w.WriteAttributeString("Condition", " '$(Platform)' == '" + platformName + "' "); w.WriteElementString("PlatformTarget", platformName); if ((module.Reader.PEHeaders.CorHeader.Flags & CorFlags.Prefers32Bit) != 0) { w.WriteElementString("Prefer32Bit", "True"); } w.WriteEndElement(); // </PropertyGroup> (platform-specific) w.WriteStartElement("PropertyGroup"); // Debug w.WriteAttributeString("Condition", " '$(Configuration)' == 'Debug' "); w.WriteElementString("OutputPath", "bin\\Debug\\"); w.WriteElementString("DebugSymbols", "true"); w.WriteElementString("DebugType", "full"); w.WriteElementString("Optimize", "false"); w.WriteEndElement(); // </PropertyGroup> (Debug) w.WriteStartElement("PropertyGroup"); // Release w.WriteAttributeString("Condition", " '$(Configuration)' == 'Release' "); w.WriteElementString("OutputPath", "bin\\Release\\"); w.WriteElementString("DebugSymbols", "true"); w.WriteElementString("DebugType", "pdbonly"); w.WriteElementString("Optimize", "true"); w.WriteEndElement(); // </PropertyGroup> (Release) w.WriteStartElement("ItemGroup"); // References foreach (var r in module.AssemblyReferences) { if (r.Name != "mscorlib") { w.WriteStartElement("Reference"); w.WriteAttributeString("Include", r.Name); var asm = AssemblyResolver.Resolve(r); if (!IsGacAssembly(r, asm)) { if (asm != null) { w.WriteElementString("HintPath", asm.FileName); } } w.WriteEndElement(); } } w.WriteEndElement(); // </ItemGroup> (References) foreach (IGrouping <string, string> gr in (from f in files group f.Item2 by f.Item1 into g orderby g.Key select g)) { w.WriteStartElement("ItemGroup"); foreach (string file in gr.OrderBy(f => f, StringComparer.OrdinalIgnoreCase)) { w.WriteStartElement(gr.Key); w.WriteAttributeString("Include", file); w.WriteEndElement(); } w.WriteEndElement(); } switch (languageTargets) { case LanguageTargets.Portable: w.WriteStartElement("Import"); w.WriteAttributeString("Project", "$(MSBuildExtensionsPath32)\\Microsoft\\Portable\\$(TargetFrameworkVersion)\\Microsoft.Portable.CSharp.targets"); w.WriteEndElement(); break; default: w.WriteStartElement("Import"); w.WriteAttributeString("Project", "$(MSBuildToolsPath)\\Microsoft.CSharp.targets"); w.WriteEndElement(); break; } w.WriteEndDocument(); } }
void RunInternal(string dir, string fileToRoundtrip, Action <string> testAction, LanguageVersion languageVersion, string snkFilePath = null, bool useOldProjectFormat = false) { if (!Directory.Exists(TestDir)) { Assert.Ignore($"Assembly-roundtrip test ignored: test directory '{TestDir}' needs to be checked out separately." + Environment.NewLine + $"git clone https://github.com/icsharpcode/ILSpy-tests \"{TestDir}\""); } string inputDir = Path.Combine(TestDir, dir); string decompiledDir = inputDir + "-decompiled"; string outputDir = inputDir + "-output"; if (inputDir.EndsWith("TestCases")) { // make sure output dir names are unique so that we don't get trouble due to parallel test execution decompiledDir += Path.GetFileNameWithoutExtension(fileToRoundtrip) + "_" + languageVersion.ToString(); outputDir += Path.GetFileNameWithoutExtension(fileToRoundtrip) + "_" + languageVersion.ToString(); } ClearDirectory(decompiledDir); ClearDirectory(outputDir); string projectFile = null; foreach (string file in Directory.EnumerateFiles(inputDir, "*", SearchOption.AllDirectories)) { if (!file.StartsWith(inputDir + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase)) { Assert.Fail($"Unexpected file name: {file}"); } string relFile = file.Substring(inputDir.Length + 1); Directory.CreateDirectory(Path.Combine(outputDir, Path.GetDirectoryName(relFile))); if (relFile.Equals(fileToRoundtrip, StringComparison.OrdinalIgnoreCase)) { Console.WriteLine($"Decompiling {fileToRoundtrip}..."); Stopwatch w = Stopwatch.StartNew(); using (var fileStream = new FileStream(file, FileMode.Open, FileAccess.Read)) { PEFile module = new PEFile(file, fileStream, PEStreamOptions.PrefetchEntireImage); var resolver = new TestAssemblyResolver(file, inputDir, module.Reader.DetectTargetFrameworkId()); resolver.AddSearchDirectory(inputDir); resolver.RemoveSearchDirectory("."); // use a fixed GUID so that we can diff the output between different ILSpy runs without spurious changes var projectGuid = Guid.Parse("{127C83E4-4587-4CF9-ADCA-799875F3DFE6}"); var settings = new DecompilerSettings(languageVersion); if (useOldProjectFormat) { settings.UseSdkStyleProjectFormat = false; } var decompiler = new TestProjectDecompiler(projectGuid, resolver, resolver, settings); if (snkFilePath != null) { decompiler.StrongNameKeyFile = Path.Combine(inputDir, snkFilePath); } decompiler.DecompileProject(module, decompiledDir); Console.WriteLine($"Decompiled {fileToRoundtrip} in {w.Elapsed.TotalSeconds:f2}"); projectFile = Path.Combine(decompiledDir, module.Name + ".csproj"); } } else { File.Copy(file, Path.Combine(outputDir, relFile)); } } Assert.IsNotNull(projectFile, $"Could not find {fileToRoundtrip}"); Compile(projectFile, outputDir); testAction(outputDir); }
public override void ValidateOptions(ArrayBuilder <Diagnostic> builder) { base.ValidateOptions(builder); // Validate LanguageVersion not SpecifiedLanguageVersion, after Latest/Default has been converted: if (!LanguageVersion.IsValid()) { builder.Add(MetaErrorCode.ERR_BadLanguageVersion.ToDiagnosticWithNoLocation(LanguageVersion.ToString())); } }
ProjectId WriteProjectFile(TextWriter writer, IEnumerable <Tuple <string, string> > files, Metadata.PEFile module) { const string ns = "http://schemas.microsoft.com/developer/msbuild/2003"; string platformName = GetPlatformName(module); Guid guid = this.ProjectGuid ?? Guid.NewGuid(); var targetFramework = DetectTargetFramework(module); List <Guid> typeGuids = new List <Guid>(); if (targetFramework.IsPortableClassLibrary) { typeGuids.Add(ProjectTypeGuids.PortableLibrary); } typeGuids.Add(ProjectTypeGuids.CSharpWindows); // TODO: .NET core support using (XmlTextWriter w = new XmlTextWriter(writer)) { w.Formatting = Formatting.Indented; w.WriteStartDocument(); w.WriteStartElement("Project", ns); w.WriteAttributeString("ToolsVersion", "4.0"); w.WriteAttributeString("DefaultTargets", "Build"); w.WriteStartElement("PropertyGroup"); w.WriteElementString("ProjectGuid", guid.ToString("B").ToUpperInvariant()); w.WriteElementString("ProjectTypeGuids", string.Join(";", typeGuids.Select(g => g.ToString("B").ToUpperInvariant()))); w.WriteStartElement("Configuration"); w.WriteAttributeString("Condition", " '$(Configuration)' == '' "); w.WriteValue("Debug"); w.WriteEndElement(); // </Configuration> w.WriteStartElement("Platform"); w.WriteAttributeString("Condition", " '$(Platform)' == '' "); w.WriteValue(platformName); w.WriteEndElement(); // </Platform> if (module.Reader.PEHeaders.IsDll) { w.WriteElementString("OutputType", "Library"); } else { switch (module.Reader.PEHeaders.PEHeader.Subsystem) { case Subsystem.WindowsGui: w.WriteElementString("OutputType", "WinExe"); break; case Subsystem.WindowsCui: w.WriteElementString("OutputType", "Exe"); break; default: w.WriteElementString("OutputType", "Library"); break; } } w.WriteElementString("LangVersion", LanguageVersion.ToString().Replace("CSharp", "").Replace('_', '.')); w.WriteElementString("AssemblyName", module.Name); if (targetFramework.TargetFrameworkIdentifier != null) { w.WriteElementString("TargetFrameworkIdentifier", targetFramework.TargetFrameworkIdentifier); } if (targetFramework.TargetFrameworkVersion != null) { w.WriteElementString("TargetFrameworkVersion", targetFramework.TargetFrameworkVersion); } if (targetFramework.TargetFrameworkProfile != null) { w.WriteElementString("TargetFrameworkProfile", targetFramework.TargetFrameworkProfile); } w.WriteElementString("WarningLevel", "4"); w.WriteElementString("AllowUnsafeBlocks", "True"); if (StrongNameKeyFile != null) { w.WriteElementString("SignAssembly", "True"); w.WriteElementString("AssemblyOriginatorKeyFile", Path.GetFileName(StrongNameKeyFile)); } w.WriteEndElement(); // </PropertyGroup> w.WriteStartElement("PropertyGroup"); // platform-specific w.WriteAttributeString("Condition", " '$(Platform)' == '" + platformName + "' "); w.WriteElementString("PlatformTarget", platformName); if (targetFramework.VersionNumber > 400 && platformName == "AnyCPU" && (module.Reader.PEHeaders.CorHeader.Flags & CorFlags.Prefers32Bit) == 0) { w.WriteElementString("Prefer32Bit", "false"); } w.WriteEndElement(); // </PropertyGroup> (platform-specific) w.WriteStartElement("PropertyGroup"); // Debug w.WriteAttributeString("Condition", " '$(Configuration)' == 'Debug' "); w.WriteElementString("OutputPath", "bin\\Debug\\"); w.WriteElementString("DebugSymbols", "true"); w.WriteElementString("DebugType", "full"); w.WriteElementString("Optimize", "false"); w.WriteEndElement(); // </PropertyGroup> (Debug) w.WriteStartElement("PropertyGroup"); // Release w.WriteAttributeString("Condition", " '$(Configuration)' == 'Release' "); w.WriteElementString("OutputPath", "bin\\Release\\"); w.WriteElementString("DebugSymbols", "true"); w.WriteElementString("DebugType", "pdbonly"); w.WriteElementString("Optimize", "true"); w.WriteEndElement(); // </PropertyGroup> (Release) w.WriteStartElement("ItemGroup"); // References foreach (var r in module.AssemblyReferences) { if (r.Name != "mscorlib") { w.WriteStartElement("Reference"); w.WriteAttributeString("Include", r.Name); var asm = AssemblyResolver.Resolve(r); if (!IsGacAssembly(r, asm)) { if (asm != null) { w.WriteElementString("HintPath", asm.FileName); } } w.WriteEndElement(); } } w.WriteEndElement(); // </ItemGroup> (References) foreach (IGrouping <string, string> gr in (from f in files group f.Item2 by f.Item1 into g orderby g.Key select g)) { w.WriteStartElement("ItemGroup"); foreach (string file in gr.OrderBy(f => f, StringComparer.OrdinalIgnoreCase)) { w.WriteStartElement(gr.Key); w.WriteAttributeString("Include", file); w.WriteEndElement(); } w.WriteEndElement(); } if (targetFramework.IsPortableClassLibrary) { w.WriteStartElement("Import"); w.WriteAttributeString("Project", "$(MSBuildExtensionsPath32)\\Microsoft\\Portable\\$(TargetFrameworkVersion)\\Microsoft.Portable.CSharp.targets"); w.WriteEndElement(); } else { w.WriteStartElement("Import"); w.WriteAttributeString("Project", "$(MSBuildToolsPath)\\Microsoft.CSharp.targets"); w.WriteEndElement(); } w.WriteEndDocument(); } return(new ProjectId(platformName, guid, ProjectTypeGuids.CSharpWindows)); }