Beispiel #1
0
        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
                                )
                            );
                    }
                }
            }
        }
Beispiel #2
0
        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();
            }
        }
Beispiel #4
0
        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()));
     }
 }
Beispiel #6
0
        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));
        }