Browse Source

Merge pull request #626 from olegbevz/master

Assembly Info Editor (issue #96, second attempt)
pull/628/head
Siegfried Pammer 11 years ago
parent
commit
bcae54ad89
  1. 63
      data/resources/StringResources.resx
  2. 3
      src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin
  3. 15
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  4. 60
      src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/ProjectOptions/AssemblyInfo/AssemblyInfo.cs
  5. 117
      src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/ProjectOptions/AssemblyInfo/AssemblyInfoPanel.xaml
  6. 120
      src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/ProjectOptions/AssemblyInfo/AssemblyInfoPanel.xaml.cs
  7. 420
      src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/ProjectOptions/AssemblyInfo/AssemblyInfoProvider.cs
  8. 161
      src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/ProjectOptions/AssemblyInfo/AssemblyInfoViewModel.cs
  9. 66
      src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/ProjectOptions/AssemblyInfo/VersionToStringConverter.cs
  10. 3
      src/Main/Base/Test/ICSharpCode.SharpDevelop.Tests.csproj
  11. 518
      src/Main/Base/Test/ProjectOptions/AssemblyInfoProviderTests.cs

63
data/resources/StringResources.resx

@ -8377,4 +8377,67 @@ Press Esc to cancel this operation.</value> @@ -8377,4 +8377,67 @@ Press Esc to cancel this operation.</value>
<data name="ICSharpCode.WpfDesign.AddIn.PressAltText" xml:space="preserve">
<value>Press "Alt" to enter Container</value>
</data>
<data name="Dialog.ProjectOptions.AssemblyInfo" xml:space="preserve">
<value>Assembly Info</value>
</data>
<data name="Dialog.ProjectOptions.AssemblyInfo.AssemblyVersion" xml:space="preserve">
<value>Assembly version:</value>
</data>
<data name="Dialog.ProjectOptions.AssemblyInfo.Company" xml:space="preserve">
<value>Company:</value>
</data>
<data name="Dialog.ProjectOptions.AssemblyInfo.Copyright" xml:space="preserve">
<value>Copyright:</value>
</data>
<data name="Dialog.ProjectOptions.AssemblyInfo.Description" xml:space="preserve">
<value>Description:</value>
</data>
<data name="Dialog.ProjectOptions.AssemblyInfo.FileVersion" xml:space="preserve">
<value>File version:</value>
</data>
<data name="Dialog.ProjectOptions.AssemblyInfo.GUID" xml:space="preserve">
<value>GUID:</value>
</data>
<data name="Dialog.ProjectOptions.AssemblyInfo.MakeAssemblyCOMVisible" xml:space="preserve">
<value>Make assembly COM-visible</value>
</data>
<data name="Dialog.ProjectOptions.AssemblyInfo.NeutralLanguage" xml:space="preserve">
<value>Neutral language:</value>
</data>
<data name="Dialog.ProjectOptions.AssemblyInfo.Product" xml:space="preserve">
<value>Product:</value>
</data>
<data name="Dialog.ProjectOptions.AssemblyInfo.Title" xml:space="preserve">
<value>Title:</value>
</data>
<data name="Dialog.ProjectOptions.AssemblyInfo.Trademark" xml:space="preserve">
<value>Trademark:</value>
</data>
<data name="Dialog.ProjectOptions.AssemblyInfo.AssemblyInfoNotFound" xml:space="preserve">
<value>Assembly info file was not found. Please ensure that the project contains assembly info file.</value>
</data>
<data name="Dialog.ProjectOptions.AssemblyInfo.ClsCompliant" xml:space="preserve">
<value>CLS compliant</value>
</data>
<data name="Dialog.ProjectOptions.AssemblyInfo.DefaultAlias" xml:space="preserve">
<value>Default alias:</value>
</data>
<data name="Dialog.ProjectOptions.AssemblyInfo.InformationalVersion" xml:space="preserve">
<value>Informational version:</value>
</data>
<data name="Dialog.ProjectOptions.AssemblyInfo.JitOptimization" xml:space="preserve">
<value>JIT optimization</value>
</data>
<data name="Dialog.ProjectOptions.AssemblyInfo.JitTracking" xml:space="preserve">
<value>JIT tracking</value>
</data>
<data name="Dialog.ProjectOptions.AssemblyInfo.NewGUID" xml:space="preserve">
<value>New GUID</value>
</data>
<data name="Dialog.ProjectOptions.AssemblyInfo.IncorrectValue" xml:space="preserve">
<value>One of the assembly info values is incorrect.</value>
</data>
<data name="Dialog.ProjectOptions.AssemblyInfo.None" xml:space="preserve">
<value>None</value>
</data>
</root>

3
src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin

@ -115,6 +115,9 @@ @@ -115,6 +115,9 @@
<OptionPanel id = "DebugOptions"
label = "${res:Dialog.ProjectOptions.DebugOptions}"
class = "ICSharpCode.SharpDevelop.Gui.OptionPanels.DebugOptions"/>
<OptionPanel id = "AssemblyInfo"
label = "${res:Dialog.ProjectOptions.AssemblyInfo}"
class = "ICSharpCode.SharpDevelop.Gui.OptionPanels.AssemblyInfoPanel"/>
<!--<OptionPanel id = "Publish"
label = "${res:Dialog.ProjectOptions.Publish}"
class = "ICSharpCode.SharpDevelop.Gui.OptionPanels.Publish"/>-->

15
src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj

@ -297,6 +297,13 @@ @@ -297,6 +297,13 @@
<DependentUpon>OutputWindowOptionsPanel.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Src\Gui\Dialogs\OptionPanels\ProjectOptions\AssemblyInfo\AssemblyInfo.cs" />
<Compile Include="Src\Gui\Dialogs\OptionPanels\ProjectOptions\AssemblyInfo\AssemblyInfoPanel.xaml.cs">
<DependentUpon>AssemblyInfoPanel.xaml</DependentUpon>
</Compile>
<Compile Include="Src\Gui\Dialogs\OptionPanels\ProjectOptions\AssemblyInfo\AssemblyInfoProvider.cs" />
<Compile Include="Src\Gui\Dialogs\OptionPanels\ProjectOptions\AssemblyInfo\AssemblyInfoViewModel.cs" />
<Compile Include="Src\Gui\Dialogs\OptionPanels\ProjectOptions\AssemblyInfo\VersionToStringConverter.cs" />
<Compile Include="Src\Gui\Pads\CompilerMessageView\MessageViewCategoryTextWriter.cs" />
<Compile Include="Src\Gui\Pads\TaskList\TaskViewResources.xaml.cs">
<DependentUpon>TaskViewResources.xaml</DependentUpon>
@ -904,6 +911,10 @@ @@ -904,6 +911,10 @@
<Page Include="Src\Gui\Dialogs\OptionPanels\IDEOptions\TaskListOptionsPanel.xaml" />
<Page Include="Src\Gui\Dialogs\OptionPanels\OutputWindowOptionsPanel.xaml" />
<Page Include="Src\Gui\Dialogs\OptionPanels\ProjectOptions\ApplicationSettings.xaml" />
<Page Include="Src\Gui\Dialogs\OptionPanels\ProjectOptions\AssemblyInfo\AssemblyInfoPanel.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Src\Gui\Dialogs\OptionPanels\ProjectOptions\BuildAdvanced.xaml" />
<Page Include="Src\Gui\Dialogs\OptionPanels\ProjectOptions\BuildEvents.xaml" />
<Page Include="Src\Gui\Dialogs\OptionPanels\ProjectOptions\BuildOutput.xaml" />
@ -933,6 +944,10 @@ @@ -933,6 +944,10 @@
<Name>ICSharpCode.NRefactory.Cecil</Name>
<Private>False</Private>
</ProjectReference>
<ProjectReference Include="..\..\..\Libraries\NRefactory\ICSharpCode.NRefactory.CSharp\ICSharpCode.NRefactory.CSharp.csproj">
<Project>{53dca265-3c3c-42f9-b647-f72ba678122b}</Project>
<Name>ICSharpCode.NRefactory.CSharp</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\Libraries\NRefactory\ICSharpCode.NRefactory.Xml\ICSharpCode.NRefactory.Xml.csproj">
<Project>{DC393B66-92ED-4CAD-AB25-CFEF23F3D7C6}</Project>
<Name>ICSharpCode.NRefactory.Xml</Name>

60
src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/ProjectOptions/AssemblyInfo/AssemblyInfo.cs

@ -0,0 +1,60 @@ @@ -0,0 +1,60 @@
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
namespace ICSharpCode.SharpDevelop.Gui.OptionPanels
{
/// <summary>
/// Assembly info parameters model
/// </summary>
public class AssemblyInfo
{
public string Title { get; set; }
public string Description { get; set; }
public string Company { get; set; }
public string Product { get; set; }
public string Copyright { get; set; }
public string Trademark { get; set; }
public string DefaultAlias { get; set; }
public Version AssemblyVersion { get; set; }
public Version AssemblyFileVersion { get; set; }
public Version InformationalVersion { get; set; }
public Guid? Guid { get; set; }
public string NeutralLanguage { get; set; }
public bool ComVisible { get; set; }
public bool ClsCompliant { get; set; }
public bool JitOptimization { get; set; }
public bool JitTracking { get; set; }
}
}

117
src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/ProjectOptions/AssemblyInfo/AssemblyInfoPanel.xaml

@ -0,0 +1,117 @@ @@ -0,0 +1,117 @@
<optionPanels:ProjectOptionPanel
x:Class="ICSharpCode.SharpDevelop.Gui.OptionPanels.AssemblyInfoPanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:core="http://icsharpcode.net/sharpdevelop/core"
xmlns:optionPanels="clr-namespace:ICSharpCode.SharpDevelop.Gui.OptionPanels"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type={x:Type optionPanels:AssemblyInfoViewModel}}">
<ScrollViewer VerticalScrollBarVisibility="Auto">
<Grid x:Name="RootGrid">
<Grid.Resources>
<Style TargetType="{x:Type Label}">
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Height" Value="20"/>
<Setter Property="Margin" Value="4"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Validation.ErrorTemplate" Value="{x:Null}"/>
</Style>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="Height" Value="20"/>
<Setter Property="Margin" Value="4"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Validation.ErrorTemplate" Value="{x:Null}"/>
</Style>
<Style TargetType="{x:Type CheckBox}">
<Setter Property="Margin" Value="4"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Height" Value="24"/>
<Setter Property="Margin" Value="4"/>
<Setter Property="Padding" Value="4,0,4,0"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
<optionPanels:VersionToStringConverter x:Key="VersionToStringConverter"/>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Content="{core:Localize Dialog.ProjectOptions.AssemblyInfo.Title}" Grid.Column="0" Grid.Row="0"/>
<TextBox Text="{Binding Title, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="0"/>
<Label Content="{core:Localize Dialog.ProjectOptions.AssemblyInfo.Description}" Grid.Column="0" Grid.Row="1"/>
<TextBox Text="{Binding Description, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="1"/>
<Label Content="{core:Localize Dialog.ProjectOptions.AssemblyInfo.Company}" Grid.Column="0" Grid.Row="2"/>
<TextBox Text="{Binding Company, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="2"/>
<Label Content="{core:Localize Dialog.ProjectOptions.AssemblyInfo.Product}" Grid.Column="0" Grid.Row="3"/>
<TextBox Text="{Binding Product, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="3"/>
<Label Content="{core:Localize Dialog.ProjectOptions.AssemblyInfo.Copyright}" Grid.Column="0" Grid.Row="4"/>
<TextBox Text="{Binding Copyright, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="4"/>
<Label Content="{core:Localize Dialog.ProjectOptions.AssemblyInfo.Trademark}" Grid.Column="0" Grid.Row="5"/>
<TextBox Text="{Binding Trademark, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="5"/>
<Label Content="{core:Localize Dialog.ProjectOptions.AssemblyInfo.DefaultAlias}" Grid.Column="0" Grid.Row="6"/>
<TextBox Text="{Binding DefaultAlias, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="6"/>
<Label Content="{core:Localize Dialog.ProjectOptions.AssemblyInfo.AssemblyVersion}" Grid.Column="0" Grid.Row="7"/>
<TextBox Text="{Binding AssemblyVersion, Converter={StaticResource VersionToStringConverter}, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="7"/>
<Label Content="{core:Localize Dialog.ProjectOptions.AssemblyInfo.FileVersion}" Grid.Column="0" Grid.Row="8"/>
<TextBox Text="{Binding AssemblyFileVersion, Converter={StaticResource VersionToStringConverter}, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="8"/>
<Label Content="{core:Localize Dialog.ProjectOptions.AssemblyInfo.InformationalVersion}" Grid.Column="0" Grid.Row="9"/>
<TextBox Text="{Binding InformationalVersion, Converter={StaticResource VersionToStringConverter}, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="9"/>
<Label Content="{core:Localize Dialog.ProjectOptions.AssemblyInfo.GUID}" Grid.Column="0" Grid.Row="10"/>
<TextBox Text="{Binding Guid, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Grid.Row="10"/>
<Button Content="{core:Localize Dialog.ProjectOptions.AssemblyInfo.NewGUID}" Command="{Binding NewGuidCommand}" Grid.Column="2" Grid.Row="10"/>
<Label Content="{core:Localize Dialog.ProjectOptions.AssemblyInfo.NeutralLanguage}" Grid.Column="0" Grid.Row="11"/>
<ComboBox SelectedValue="{Binding NeutralLanguage, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding Languages}"
IsEditable="True" DisplayMemberPath="Value" SelectedValuePath="Key"
Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="11"/>
<CheckBox Content="{core:Localize Dialog.ProjectOptions.AssemblyInfo.MakeAssemblyCOMVisible}"
IsChecked="{Binding ComVisible}" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="12"/>
<CheckBox Content="{core:Localize Dialog.ProjectOptions.AssemblyInfo.ClsCompliant}"
IsChecked="{Binding ClsCompliant}" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="13"/>
<CheckBox Content="{core:Localize Dialog.ProjectOptions.AssemblyInfo.JitOptimization}"
IsChecked="{Binding JitOptimization}" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="14"/>
<CheckBox Content="{core:Localize Dialog.ProjectOptions.AssemblyInfo.JitTracking}"
IsChecked="{Binding JitTracking}" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="15"/>
</Grid>
</ScrollViewer>
</optionPanels:ProjectOptionPanel>

120
src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/ProjectOptions/AssemblyInfo/AssemblyInfoPanel.xaml.cs

@ -0,0 +1,120 @@ @@ -0,0 +1,120 @@
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Project;
namespace ICSharpCode.SharpDevelop.Gui.OptionPanels
{
/// <summary>
/// Interaction logic for AssemblyInfo.xaml
/// </summary>
public partial class AssemblyInfoPanel
{
private AssemblyInfo assemblyInfo;
public AssemblyInfoPanel()
{
InitializeComponent();
}
protected override void Load(MSBuildBasedProject project, string configuration, string platform)
{
var assemblyInfoFileName = GetAssemblyInfoFileName(project);
if (string.IsNullOrEmpty(assemblyInfoFileName))
{
assemblyInfo = new AssemblyInfo();
MessageService.ShowError("${res:Dialog.ProjectOptions.AssemblyInfo.AssemblyInfoNotFound}");
}
else
{
var assemblyInfoProvider = new AssemblyInfoProvider();
assemblyInfo = assemblyInfoProvider.ReadAssemblyInfo(assemblyInfoFileName);
}
var assemblyInfoViewModel = new AssemblyInfoViewModel(assemblyInfo);
assemblyInfoViewModel.PropertyChanged += OnAssemblyInfoChanged;
DataContext = assemblyInfoViewModel;
base.Load(project, configuration, platform);
}
protected override bool Save(MSBuildBasedProject project, string configuration, string platform)
{
if (!CheckForValidationErrors())
{
return false;
}
var assemblyInfoFileName = GetAssemblyInfoFileName(project);
if (!string.IsNullOrEmpty(assemblyInfoFileName))
{
if (assemblyInfo != null)
{
var assemblyInfoProvider = new AssemblyInfoProvider();
assemblyInfoProvider.MergeAssemblyInfo(assemblyInfo, assemblyInfoFileName);
}
}
else
{
MessageService.ShowError("${res:Dialog.ProjectOptions.AssemblyInfo.AssemblyInfoNotFound}");
}
return base.Save(project, configuration, platform);
}
private string GetAssemblyInfoFileName(MSBuildBasedProject project)
{
var assemblyInfoProjectItem = project.Items
.FirstOrDefault(projectItem => projectItem.FileName.GetFileNameWithoutExtension() == "AssemblyInfo");
if (assemblyInfoProjectItem == null || assemblyInfoProjectItem.FileName == null)
return null;
return assemblyInfoProjectItem.FileName.ToString();
}
private void OnAssemblyInfoChanged(object sender, EventArgs e)
{
this.IsDirty = true;
}
private bool CheckForValidationErrors()
{
var wrongControl = RootGrid.Children.OfType<UIElement>().FirstOrDefault(Validation.GetHasError);
if (wrongControl != null)
{
MessageService.ShowError("${res:Dialog.ProjectOptions.AssemblyInfo.IncorrectValue}");
wrongControl.Focus();
var textBox = wrongControl as TextBox;
if (textBox != null)
textBox.SelectAll();
return false;
}
return true;
}
}
}

420
src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/ProjectOptions/AssemblyInfo/AssemblyInfoProvider.cs

@ -0,0 +1,420 @@ @@ -0,0 +1,420 @@
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.CSharp;
using Attribute = ICSharpCode.NRefactory.CSharp.Attribute;
using CSharpParser = ICSharpCode.NRefactory.CSharp.CSharpParser;
namespace ICSharpCode.SharpDevelop.Gui.OptionPanels
{
/// <summary>
/// Class for reading and writing assembly info file
/// </summary>
public class AssemblyInfoProvider
{
#region Constants
private const string Attribute = "Attribute";
private const string AssemblyTitle = "AssemblyTitle";
private const string AssemblyDescription = "AssemblyDescription";
private const string AssemblyCompany = "AssemblyCompany";
private const string AssemblyProduct = "AssemblyProduct";
private const string AssemblyCopyright = "AssemblyCopyright";
private const string AssemblyTrademark = "AssemblyTrademark";
private const string AssemblyDefaultAlias = "AssemblyDefaultAlias";
private const string AssemblyVersion = "AssemblyVersion";
private const string AssemblyFileVersion = "AssemblyFileVersion";
private const string AssemblyInformationalVersion = "AssemblyInformationalVersion";
private const string Guid = "Guid";
private const string NeutralResourcesLanguage = "NeutralResourcesLanguage";
private const string ComVisible = "ComVisible";
private const string ClsCompliant = "CLSCompliant";
private const string AssemblyFlags = "AssemblyFlags";
#endregion
/// <summary>
/// Read assembly info from file
/// </summary>
/// <param name="assemblyInfoFileName">Source file name</param>
/// <returns>Assembly info model</returns>
public AssemblyInfo ReadAssemblyInfo(string assemblyInfoFileName)
{
using (var fileStream = new FileStream(assemblyInfoFileName, FileMode.Open, FileAccess.Read))
{
return ReadAssemblyInfo(fileStream);
}
}
/// <summary>
/// Read assembly info from stream
/// </summary>
/// <param name="stream">Sourcce stream</param>
/// <returns>Assembly info model</returns>
public AssemblyInfo ReadAssemblyInfo(Stream stream)
{
var syntaxTree = ReadSyntaxTree(stream);
if (syntaxTree == null)
throw new Exception("Can't read assembly info syntax tree.");
var assemblyInfo = new AssemblyInfo {JitOptimization = true};
foreach (var attributeSection in syntaxTree.Children.OfType<AttributeSection>())
{
foreach (var attribute in attributeSection.Attributes)
{
var attributeType = attribute.Type as SimpleType;
if (attributeType == null)
continue;
switch (attributeType.Identifier)
{
case AssemblyTitle:
case AssemblyTitle + Attribute:
assemblyInfo.Title = GetAttributeValue<string>(attribute);
break;
case AssemblyDescription:
case AssemblyDescription + Attribute:
assemblyInfo.Description = GetAttributeValue<string>(attribute);
break;
case AssemblyCompany:
case AssemblyCompany + Attribute:
assemblyInfo.Company = GetAttributeValue<string>(attribute);
break;
case AssemblyProduct:
case AssemblyProduct + Attribute:
assemblyInfo.Product = GetAttributeValue<string>(attribute);
break;
case AssemblyCopyright:
case AssemblyCopyright + Attribute:
assemblyInfo.Copyright = GetAttributeValue<string>(attribute);
break;
case AssemblyTrademark:
case AssemblyTrademark + Attribute:
assemblyInfo.Trademark = GetAttributeValue<string>(attribute);
break;
case AssemblyDefaultAlias:
case AssemblyDefaultAlias + Attribute:
assemblyInfo.DefaultAlias = GetAttributeValue<string>(attribute);
break;
case AssemblyVersion:
case AssemblyVersion + Attribute:
assemblyInfo.AssemblyVersion = GetAttributeValueAsVersion(attribute);
break;
case AssemblyFileVersion:
case AssemblyFileVersion + Attribute:
assemblyInfo.AssemblyFileVersion = GetAttributeValueAsVersion(attribute);
break;
case AssemblyInformationalVersion:
case AssemblyInformationalVersion + Attribute:
assemblyInfo.InformationalVersion = GetAttributeValueAsVersion(attribute);
break;
case Guid:
case Guid + Attribute:
assemblyInfo.Guid = GetAttributeValueAsGuid(attribute);
break;
case NeutralResourcesLanguage:
case NeutralResourcesLanguage + Attribute:
assemblyInfo.NeutralLanguage = GetAttributeValue<string>(attribute);
break;
case ComVisible:
case ComVisible + Attribute:
assemblyInfo.ComVisible = GetAttributeValue<bool>(attribute);
break;
case ClsCompliant:
case ClsCompliant + Attribute:
assemblyInfo.ClsCompliant = GetAttributeValue<bool>(attribute);
break;
case AssemblyFlags:
case AssemblyFlags + Attribute:
var assemblyFlags = GetAssemblyFlagsFromAttribute(attribute);
assemblyInfo.JitOptimization = !assemblyFlags.HasFlag(AssemblyNameFlags.EnableJITcompileOptimizer);
assemblyInfo.JitTracking = assemblyFlags.HasFlag(AssemblyNameFlags.EnableJITcompileTracking);
break;
}
}
}
return assemblyInfo;
}
/// <summary>
/// Merge assembly info in file with the assembly info model
/// </summary>
/// <param name="assemblyInfo">Assembly info model</param>
/// <param name="fileName">Source file name</param>
public void MergeAssemblyInfo(AssemblyInfo assemblyInfo, string fileName)
{
string content;
using (var fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
content = MergeAssemblyInfo(assemblyInfo, fileStream);
}
if (!string.IsNullOrEmpty(content))
File.WriteAllText(fileName, content);
}
/// <summary>
/// Merge assembly info from the stream with the assembly info model
/// </summary>
/// <param name="assemblyInfo">Assembly info model</param>
/// <param name="inputStream">Source file name</param>
/// <returns>Result assembly info file content</returns>
public string MergeAssemblyInfo(AssemblyInfo assemblyInfo, Stream inputStream)
{
var syntaxTree = ReadSyntaxTree(inputStream);
if (syntaxTree == null)
throw new Exception("Can't read assembly info syntax tree.");
// Add missing namespaces
AddNamespaceUsingIfNotExist(syntaxTree, "System");
AddNamespaceUsingIfNotExist(syntaxTree, "System.Reflection");
if (assemblyInfo.NeutralLanguage != null)
AddNamespaceUsingIfNotExist(syntaxTree, "System.Resources");
if (assemblyInfo.Guid.HasValue || assemblyInfo.ComVisible)
AddNamespaceUsingIfNotExist(syntaxTree, "System.Runtime.InteropServices");
// Update assembly info attributes
SetAttributeValueOrAddAttributeIfNotDefault(syntaxTree, AssemblyTitle, assemblyInfo.Title);
SetAttributeValueOrAddAttributeIfNotDefault(syntaxTree, AssemblyDescription, assemblyInfo.Description);
SetAttributeValueOrAddAttributeIfNotDefault(syntaxTree, AssemblyCompany, assemblyInfo.Company);
SetAttributeValueOrAddAttributeIfNotDefault(syntaxTree, AssemblyProduct, assemblyInfo.Product);
SetAttributeValueOrAddAttributeIfNotDefault(syntaxTree, AssemblyCopyright, assemblyInfo.Copyright);
SetAttributeValueOrAddAttributeIfNotDefault(syntaxTree, AssemblyTrademark, assemblyInfo.Trademark);
SetAttributeValueOrAddAttributeIfNotDefault(syntaxTree, AssemblyDefaultAlias, assemblyInfo.DefaultAlias);
SetAttributeValueOrAddAttributeIfNotDefault(syntaxTree, AssemblyVersion, assemblyInfo.AssemblyVersion, null, true);
SetAttributeValueOrAddAttributeIfNotDefault(syntaxTree, AssemblyFileVersion, assemblyInfo.AssemblyFileVersion, null, true);
SetAttributeValueOrAddAttributeIfNotDefault(syntaxTree, AssemblyInformationalVersion, assemblyInfo.InformationalVersion, null, true);
SetAttributeValueOrAddAttributeIfNotDefault(syntaxTree, Guid, assemblyInfo.Guid, null, true);
SetAttributeValueOrAddAttributeIfNotDefault(syntaxTree, NeutralResourcesLanguage, assemblyInfo.NeutralLanguage);
SetAttributeValueOrAddAttributeIfNotDefault(syntaxTree, ComVisible, assemblyInfo.ComVisible, false);
SetAttributeValueOrAddAttributeIfNotDefault(syntaxTree, ClsCompliant, assemblyInfo.ClsCompliant, false);
AssemblyNameFlags assemblyFlags = AssemblyNameFlags.PublicKey;
if (!assemblyInfo.JitOptimization)
assemblyFlags = assemblyFlags | AssemblyNameFlags.EnableJITcompileOptimizer;
if (assemblyInfo.JitTracking)
assemblyFlags = assemblyFlags | AssemblyNameFlags.EnableJITcompileTracking;
var flagsExpression = GetAssemblyFlagsExpression(assemblyFlags);
SetAttributeValueOrAddAttributeIfNotDefault(syntaxTree, AssemblyFlags, (int)assemblyFlags, (int)AssemblyNameFlags.PublicKey, flagsExpression);
return syntaxTree.ToString();
}
private SyntaxTree ReadSyntaxTree(Stream stream)
{
using (var streamReader = new StreamReader(stream))
{
var codeParser = new CSharpParser();
return codeParser.Parse(streamReader);
}
}
private T GetAttributeValue<T>(Attribute attribute, T defaultValue = default(T))
{
var attributeArguments = attribute.Arguments.OfType<PrimitiveExpression>().ToArray();
if (attributeArguments.Length == 1 && attributeArguments[0].Value is T)
return (T)attributeArguments[0].Value;
return defaultValue;
}
private Guid? GetAttributeValueAsGuid(Attribute attribute)
{
var attributeArguments = attribute.Arguments.OfType<PrimitiveExpression>().ToArray();
if (attributeArguments.Length == 1)
{
var guidString = attributeArguments[0].Value as string;
if (!string.IsNullOrEmpty(guidString))
{
Guid guid;
if (System.Guid.TryParse(guidString, out guid))
{
return guid;
}
}
}
return null;
}
private Version GetAttributeValueAsVersion(Attribute attribute)
{
var attributeArguments = attribute.Arguments.OfType<PrimitiveExpression>().ToArray();
if (attributeArguments.Length == 1)
{
var versionString = attributeArguments[0].Value as string;
if (!string.IsNullOrEmpty(versionString))
{
Version version;
if (Version.TryParse(versionString, out version))
return version;
}
}
return null;
}
private AssemblyNameFlags GetAssemblyFlagsFromAttribute(Attribute attribute)
{
if (attribute.Arguments.Count == 1)
return GetAssemblyFlagsFromExpression(attribute.Arguments.ElementAt(0));
return AssemblyNameFlags.PublicKey;
}
private AssemblyNameFlags GetAssemblyFlagsFromExpression(Expression expression)
{
if (expression == null)
return AssemblyNameFlags.PublicKey;
var primitiveExpression = expression as PrimitiveExpression;
if (primitiveExpression != null && primitiveExpression.Value is int)
return (AssemblyNameFlags)(int)primitiveExpression.Value;
var memberReferenceExpression = expression as MemberReferenceExpression;
if (memberReferenceExpression != null)
{
AssemblyNameFlags assemblyFlags;
if (Enum.TryParse(memberReferenceExpression.MemberName, out assemblyFlags))
{
return assemblyFlags;
}
}
var binaryExpression = expression as BinaryOperatorExpression;
if (binaryExpression != null && binaryExpression.Operator == BinaryOperatorType.BitwiseOr)
return GetAssemblyFlagsFromExpression(binaryExpression.Left) |
GetAssemblyFlagsFromExpression(binaryExpression.Right);
return AssemblyNameFlags.PublicKey;
}
private Expression GetAssemblyFlagsExpression(AssemblyNameFlags assemblyFlags)
{
var flagNames = new List<string>();
var flagValues = Enum.GetValues(typeof(AssemblyNameFlags));
foreach (var flagValue in flagValues)
{
if (assemblyFlags.HasFlag((Enum)flagValue) && (int)flagValue > 0)
flagNames.Add(flagValue.ToString());
}
Expression expression = null;
while (flagNames.Count > 0)
{
var currentFlagName = flagNames[0];
var flagExpression = new MemberReferenceExpression(new IdentifierExpression("AssemblyNameFlags"), currentFlagName);
expression = expression == null
? (Expression) flagExpression
: new BinaryOperatorExpression(expression, BinaryOperatorType.BitwiseOr, flagExpression);
flagNames.Remove(currentFlagName);
}
return expression;
}
private void SetAttributeValueOrAddAttributeIfNotDefault(
SyntaxTree syntaxTree,
string attributeName,
object value,
object defaultValue = null,
bool transformValueToString = false)
{
if (value == null)
return;
var attributeValue = transformValueToString ? value.ToString() : value;
SetAttributeValueOrAddAttributeIfNotDefault(
syntaxTree,
attributeName,
value,
defaultValue,
new PrimitiveExpression(attributeValue));
}
private void SetAttributeValueOrAddAttributeIfNotDefault(
SyntaxTree syntaxTree,
string attributeName,
object value,
object defaultValue,
Expression valueExpression)
{
if (value == null)
return;
var attribute = syntaxTree.Children.OfType<AttributeSection>().SelectMany(x => x.Attributes)
.FirstOrDefault(x => x.Type is SimpleType && ((SimpleType)x.Type).Identifier == attributeName);
if (attribute != null)
{
attribute.Arguments.Clear();
attribute.Arguments.Add(valueExpression);
}
else if (!value.Equals(defaultValue))
{
attribute = new Attribute { Type = new SimpleType(attributeName) };
attribute.Arguments.Add(valueExpression);
var attributeSection = new AttributeSection(attribute) { AttributeTarget = "assembly" };
syntaxTree.AddChild(attributeSection, new NRefactory.Role<AttributeSection>("Member"));
}
}
private void AddNamespaceUsingIfNotExist(SyntaxTree syntaxTree, string @namespace)
{
AstNode nodeToInsertAfter = null;
foreach (var usingDeclaration in syntaxTree.Children.OfType<UsingDeclaration>())
{
if (usingDeclaration.Namespace == @namespace)
return;
if (string.Compare(usingDeclaration.Namespace, @namespace, StringComparison.InvariantCulture) < 0)
nodeToInsertAfter = usingDeclaration;
}
if (nodeToInsertAfter != null)
syntaxTree.InsertChildAfter(nodeToInsertAfter, new UsingDeclaration(@namespace), new Role<UsingDeclaration>("Using"));
else if (syntaxTree.HasChildren)
syntaxTree.InsertChildBefore(syntaxTree.FirstChild, new UsingDeclaration(@namespace), new Role<UsingDeclaration>("Using"));
else
syntaxTree.AddChild(new UsingDeclaration(@namespace), new Role<UsingDeclaration>("Using"));
}
}
}

161
src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/ProjectOptions/AssemblyInfo/AssemblyInfoViewModel.cs

@ -0,0 +1,161 @@ @@ -0,0 +1,161 @@
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Windows.Input;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Widgets;
namespace ICSharpCode.SharpDevelop.Gui.OptionPanels
{
/// <summary>
/// View model for assembly info
/// </summary>
public class AssemblyInfoViewModel : ViewModelBase
{
private const string NONE_LANGUAGE_CODE = "NONE";
private readonly AssemblyInfo assemblyInfo;
public AssemblyInfoViewModel(AssemblyInfo assemblyInfo)
{
this.assemblyInfo = assemblyInfo;
NewGuidCommand = new RelayCommand(() => Guid = System.Guid.NewGuid());
var cultures = CultureInfo.GetCultures(CultureTypes.AllCultures);
Languages = new Dictionary<string, string>();
Languages.Add(
NONE_LANGUAGE_CODE,
string.Format("({0})", StringParser.Parse("${res:Dialog.ProjectOptions.AssemblyInfo.None}")));
Languages.AddRange(cultures.ToDictionary(x => x.Name, x => x.DisplayName).Distinct().OrderBy(x => x.Value));
}
public string Title
{
get { return assemblyInfo.Title; }
set { assemblyInfo.Title = value; OnPropertyChanged(); }
}
public string Description
{
get { return assemblyInfo.Description; }
set { assemblyInfo.Description = value; OnPropertyChanged(); }
}
public string Company
{
get { return assemblyInfo.Company; }
set { assemblyInfo.Company = value; OnPropertyChanged(); }
}
public string Product
{
get { return assemblyInfo.Product; }
set { assemblyInfo.Product = value; OnPropertyChanged(); }
}
public string Copyright
{
get { return assemblyInfo.Copyright; }
set { assemblyInfo.Copyright = value; OnPropertyChanged(); }
}
public string Trademark
{
get { return assemblyInfo.Trademark; }
set { assemblyInfo.Trademark = value; OnPropertyChanged(); }
}
public string DefaultAlias
{
get { return assemblyInfo.DefaultAlias; }
set { assemblyInfo.DefaultAlias = value; OnPropertyChanged(); }
}
public Version AssemblyVersion
{
get { return assemblyInfo.AssemblyVersion; }
set { assemblyInfo.AssemblyVersion = value; OnPropertyChanged(); }
}
public Version AssemblyFileVersion
{
get { return assemblyInfo.AssemblyFileVersion; }
set { assemblyInfo.AssemblyFileVersion = value; OnPropertyChanged(); }
}
public Version InformationalVersion
{
get { return assemblyInfo.InformationalVersion; }
set { assemblyInfo.InformationalVersion = value; OnPropertyChanged(); }
}
public Guid? Guid
{
get { return assemblyInfo.Guid; }
set { assemblyInfo.Guid = value; OnPropertyChanged(); }
}
public string NeutralLanguage
{
get
{
return assemblyInfo.NeutralLanguage ?? NONE_LANGUAGE_CODE;
}
set
{
assemblyInfo.NeutralLanguage = value == NONE_LANGUAGE_CODE ? null : value;
OnPropertyChanged();
}
}
public bool ComVisible
{
get { return assemblyInfo.ComVisible; }
set { assemblyInfo.ComVisible = value; OnPropertyChanged(); }
}
public bool ClsCompliant
{
get { return assemblyInfo.ClsCompliant; }
set { assemblyInfo.ClsCompliant = value; OnPropertyChanged(); }
}
public bool JitOptimization
{
get { return assemblyInfo.JitOptimization; }
set { assemblyInfo.JitOptimization = value; OnPropertyChanged(); }
}
public bool JitTracking
{
get { return assemblyInfo.JitTracking; }
set { assemblyInfo.JitTracking = value; OnPropertyChanged(); }
}
public ICommand NewGuidCommand { get; private set; }
public Dictionary<string, string> Languages { get; private set; }
}
}

66
src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/ProjectOptions/AssemblyInfo/VersionToStringConverter.cs

@ -0,0 +1,66 @@ @@ -0,0 +1,66 @@
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Windows;
using System.Windows.Data;
namespace ICSharpCode.SharpDevelop.Gui.OptionPanels
{
[ValueConversion(typeof(Version), typeof(string))]
public class VersionToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
try
{
var version = value as Version;
if (version != null)
return version.ToString();
return DependencyProperty.UnsetValue;
}
catch
{
return DependencyProperty.UnsetValue;
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
try
{
var versionString = value as string;
if (versionString != null)
{
Version version;
if (Version.TryParse(versionString, out version))
{
return version;
}
}
return DependencyProperty.UnsetValue;
}
catch
{
return DependencyProperty.UnsetValue;
}
}
}
}

3
src/Main/Base/Test/ICSharpCode.SharpDevelop.Tests.csproj

@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.40607</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{4980B743-B32F-4aba-AABD-45E2CAD3568D}</ProjectGuid>
<ProjectGuid>{4980B743-B32F-4ABA-AABD-45E2CAD3568D}</ProjectGuid>
<RootNamespace>ICSharpCode.SharpDevelop</RootNamespace>
<AssemblyName>ICSharpCode.SharpDevelop.Tests</AssemblyName>
<OutputTarget>Library</OutputTarget>
@ -97,6 +97,7 @@ @@ -97,6 +97,7 @@
<Compile Include="ProcessRunner\ProcessExitedTestFixture.cs" />
<Compile Include="ProcessRunner\ProcessRunnerNotStartedTestFixture.cs" />
<Compile Include="ProcessRunner\StandardOutputFromProcessTestFixture.cs" />
<Compile Include="ProjectOptions\AssemblyInfoProviderTests.cs" />
<Compile Include="Project\AddExistingProjectTests.cs" />
<Compile Include="Project\BeforeBuildCustomToolProjectItemsTests.cs" />
<Compile Include="Project\MockSolution.cs" />

518
src/Main/Base/Test/ProjectOptions/AssemblyInfoProviderTests.cs

@ -0,0 +1,518 @@ @@ -0,0 +1,518 @@
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System.IO;
using System.Text;
using ICSharpCode.SharpDevelop.Gui.OptionPanels;
using NUnit.Framework;
using System;
namespace ICSharpCode.SharpDevelop.ProjectOptions
{
/// <summary>
/// Tests for assembly info reading and writing
/// </summary>
[TestFixture]
public class AssemblyInfoProviderTests
{
private const string AssemblyInfoSample1 =
@"using System;
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle (""SharpDevelop"")]
[assembly: AssemblyDescription (""OpenSource IDE"")]
[assembly: AssemblyCompany (""Company"")]
[assembly: AssemblyProduct (""Product"")]
[assembly: AssemblyCopyright (""Copyright 2014"")]
[assembly: AssemblyTrademark (""Trademark"")]
[assembly: AssemblyDefaultAlias (""Alias"")]
// This sets the default COM visibility of types in the assembly to invisible.
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
[assembly: ComVisible (true)]
// The assembly version has following format :
//
// Major.Minor.Build.Revision
//
// You can specify all the values or you can use the default the Revision and
// Build Numbers by using the '*' as shown below:
[assembly: AssemblyVersion (""1.2.3.1"")]
[assembly: AssemblyFileVersion (""1.2.3.2"")]
[assembly: AssemblyInformationalVersion (""1.2.3.3"")]
[assembly: Guid (""0c8c889f-ced2-4167-b155-2d48a99d8c72"")]
[assembly: NeutralResourcesLanguage (""ru-RU"")]
[assembly: AssemblyFlags (32769)]
[assembly: CLSCompliant (true)]";
[TestCase]
public void ReadEmptyAssemblyInfoTest()
{
var assemblyInfoFile = string.Empty;
var assemblyInfo = ReadAssemblyInfo(assemblyInfoFile);
Assert.IsNull(assemblyInfo.Title);
Assert.IsNull(assemblyInfo.Description);
Assert.IsNull(assemblyInfo.Company);
Assert.IsNull(assemblyInfo.Product);
Assert.IsNull(assemblyInfo.Copyright);
Assert.IsNull(assemblyInfo.Trademark);
Assert.IsNull(assemblyInfo.DefaultAlias);
Assert.IsNull(assemblyInfo.AssemblyVersion);
Assert.IsNull(assemblyInfo.AssemblyFileVersion);
Assert.IsNull(assemblyInfo.InformationalVersion);
Assert.IsNull(assemblyInfo.Guid);
Assert.IsNull(assemblyInfo.NeutralLanguage);
Assert.IsFalse(assemblyInfo.ComVisible);
Assert.IsFalse(assemblyInfo.ClsCompliant);
Assert.IsTrue(assemblyInfo.JitOptimization);
Assert.IsFalse(assemblyInfo.JitTracking);
}
[TestCase]
public void ReadNotEmptyAssemblyInfoTest()
{
var assemblyInfoFile = AssemblyInfoSample1;
var assemblyInfo = ReadAssemblyInfo(assemblyInfoFile);
Assert.AreEqual("SharpDevelop", assemblyInfo.Title);
Assert.AreEqual("OpenSource IDE" , assemblyInfo.Description);
Assert.AreEqual("Company", assemblyInfo.Company);
Assert.AreEqual("Product", assemblyInfo.Product);
Assert.AreEqual("Copyright 2014", assemblyInfo.Copyright);
Assert.AreEqual("Trademark", assemblyInfo.Trademark);
Assert.AreEqual("Alias", assemblyInfo.DefaultAlias);
Assert.AreEqual(new Version(1, 2, 3, 1), assemblyInfo.AssemblyVersion);
Assert.AreEqual(new Version(1, 2, 3, 2), assemblyInfo.AssemblyFileVersion);
Assert.AreEqual(new Version(1, 2, 3, 3), assemblyInfo.InformationalVersion);
Assert.AreEqual(new Guid("0c8c889f-ced2-4167-b155-2d48a99d8c72"), assemblyInfo.Guid);
Assert.AreEqual("ru-RU", assemblyInfo.NeutralLanguage);
Assert.IsTrue(assemblyInfo.ComVisible);
Assert.IsTrue(assemblyInfo.ClsCompliant);
Assert.IsTrue(assemblyInfo.JitOptimization);
Assert.IsTrue(assemblyInfo.JitTracking);
}
[TestCase]
public void ReadAssemblyInfoWithIncorrectVersionsTest()
{
var assemblyInfoFile =
@"using System;
using System.Reflection;
using System.Runtime.InteropServices;
// This sets the default COM visibility of types in the assembly to invisible.
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
[assembly: ComVisible (true)]
// The assembly version has following format :
//
// Major.Minor.Build.Revision
//
// You can specify all the values or you can use the default the Revision and
// Build Numbers by using the '*' as shown below:
[assembly: AssemblyVersion (""Incorrect version"")]
[assembly: AssemblyFileVersion (""Incorrect version"")]
[assembly: AssemblyInformationalVersion (""Incorrect version"")]";
var assemblyInfo = ReadAssemblyInfo(assemblyInfoFile);
Assert.IsNull(assemblyInfo.AssemblyVersion);
Assert.IsNull(assemblyInfo.AssemblyFileVersion);
Assert.IsNull(assemblyInfo.InformationalVersion);
}
[TestCase]
public void ReadAssemblyInfoWithIncorrectGuidTest()
{
var assemblyInfoFile =
@"using System;
using System.Reflection;
using System.Runtime.InteropServices;
// This sets the default COM visibility of types in the assembly to invisible.
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
[assembly: ComVisible (true)]
[assembly: Guid (""Incorrect GUID"")]";
var assemblyInfo = ReadAssemblyInfo(assemblyInfoFile);
Assert.IsNull(assemblyInfo.Guid);
}
[TestCase]
public void ReadAssemblyInfoWithEmptyStringsTest()
{
var assemblyInfoFile =
@"using System;
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle ("""")]
[assembly: AssemblyDescription ("""")]
[assembly: AssemblyCompany ("""")]
[assembly: AssemblyProduct ("""")]
[assembly: AssemblyCopyright ("""")]
[assembly: AssemblyTrademark ("""")]
[assembly: AssemblyDefaultAlias ("""")]
// This sets the default COM visibility of types in the assembly to invisible.
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
[assembly: ComVisible (true)]
// The assembly version has following format :
//
// Major.Minor.Build.Revision
//
// You can specify all the values or you can use the default the Revision and
// Build Numbers by using the '*' as shown below:
[assembly: AssemblyVersion ("""")]
[assembly: AssemblyFileVersion ("""")]
[assembly: AssemblyInformationalVersion ("""")]
[assembly: Guid ("""")]
[assembly: NeutralResourcesLanguage ("""")]";
var assemblyInfo = ReadAssemblyInfo(assemblyInfoFile);
Assert.AreEqual("", assemblyInfo.Title);
Assert.AreEqual("", assemblyInfo.Description);
Assert.AreEqual("", assemblyInfo.Company);
Assert.AreEqual("", assemblyInfo.Product);
Assert.AreEqual("", assemblyInfo.Copyright);
Assert.AreEqual("", assemblyInfo.Trademark);
Assert.AreEqual("", assemblyInfo.DefaultAlias);
Assert.IsNull(assemblyInfo.AssemblyVersion);
Assert.IsNull(assemblyInfo.AssemblyFileVersion);
Assert.IsNull(assemblyInfo.InformationalVersion);
Assert.IsNull(assemblyInfo.Guid);
Assert.AreEqual("", assemblyInfo.NeutralLanguage);
}
[TestCase]
public void ReadAssemblyInfoWithFalseBooleanValuesTest()
{
var assemblyInfoFile =
@"using System;
using System.Reflection;
using System.Runtime.InteropServices;
// This sets the default COM visibility of types in the assembly to invisible.
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
[assembly: ComVisible (false)]
[assembly: CLSCompliant (false)]";
var assemblyInfo = ReadAssemblyInfo(assemblyInfoFile);
Assert.IsFalse(assemblyInfo.ComVisible);
Assert.IsFalse(assemblyInfo.ClsCompliant);
}
[TestCase]
public void ReadAssemblyInfoWithTrueBooleanValuesTest()
{
var assemblyInfoFile =
@"using System;
using System.Reflection;
using System.Runtime.InteropServices;
// This sets the default COM visibility of types in the assembly to invisible.
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
[assembly: ComVisible (true)]
[assembly: CLSCompliant (true)]";
var assemblyInfo = ReadAssemblyInfo(assemblyInfoFile);
Assert.IsTrue(assemblyInfo.ComVisible);
Assert.IsTrue(assemblyInfo.ClsCompliant);
}
[TestCase]
public void ReadAssemblyInfoWithAttributePostfixTest()
{
var assemblyInfoFile =
@"using System;
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitleAttribute (""SharpDevelop"")]
[assembly: AssemblyDescriptionAttribute (""OpenSource IDE"")]
[assembly: AssemblyCompanyAttribute (""Company"")]
[assembly: AssemblyProductAttribute (""Product"")]
[assembly: AssemblyCopyrightAttribute (""Copyright 2014"")]
[assembly: AssemblyTrademarkAttribute (""Trademark"")]
[assembly: AssemblyDefaultAliasAttribute (""Alias"")]
// This sets the default COM visibility of types in the assembly to invisible.
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
[assembly: ComVisibleAttribute (true)]
// The assembly version has following format :
//
// Major.Minor.Build.Revision
//
// You can specify all the values or you can use the default the Revision and
// Build Numbers by using the '*' as shown below:
[assembly: AssemblyVersionAttribute (""1.2.3.1"")]
[assembly: AssemblyFileVersionAttribute (""1.2.3.2"")]
[assembly: AssemblyInformationalVersionAttribute (""1.2.3.3"")]
[assembly: GuidAttribute (""0c8c889f-ced2-4167-b155-2d48a99d8c72"")]
[assembly: NeutralResourcesLanguageAttribute (""ru-RU"")]
[assembly: AssemblyFlagsAttribute (32769)]
[assembly: CLSCompliantAttribute (true)]";
var assemblyInfo = ReadAssemblyInfo(assemblyInfoFile);
Assert.AreEqual("SharpDevelop", assemblyInfo.Title);
Assert.AreEqual("OpenSource IDE", assemblyInfo.Description);
Assert.AreEqual("Company", assemblyInfo.Company);
Assert.AreEqual("Product", assemblyInfo.Product);
Assert.AreEqual("Copyright 2014", assemblyInfo.Copyright);
Assert.AreEqual("Trademark", assemblyInfo.Trademark);
Assert.AreEqual("Alias", assemblyInfo.DefaultAlias);
Assert.AreEqual(new Version(1, 2, 3, 1), assemblyInfo.AssemblyVersion);
Assert.AreEqual(new Version(1, 2, 3, 2), assemblyInfo.AssemblyFileVersion);
Assert.AreEqual(new Version(1, 2, 3, 3), assemblyInfo.InformationalVersion);
Assert.AreEqual(new Guid("0c8c889f-ced2-4167-b155-2d48a99d8c72"), assemblyInfo.Guid);
Assert.AreEqual("ru-RU", assemblyInfo.NeutralLanguage);
Assert.IsTrue(assemblyInfo.ComVisible);
Assert.IsTrue(assemblyInfo.ClsCompliant);
Assert.IsTrue(assemblyInfo.JitOptimization);
Assert.IsTrue(assemblyInfo.JitTracking);
}
[TestCase]
public void ReadAssemblyFlagsTests()
{
var assemblyInfo = ReadAssemblyInfo("[assembly: AssemblyFlags (32769)]");
Assert.IsTrue(assemblyInfo.JitOptimization);
Assert.IsTrue(assemblyInfo.JitTracking);
assemblyInfo = ReadAssemblyInfo("[assembly: AssemblyFlags (16385)]");
Assert.IsFalse(assemblyInfo.JitOptimization);
Assert.IsFalse(assemblyInfo.JitTracking);
assemblyInfo = ReadAssemblyInfo("[assembly: AssemblyFlags (49153)]");
Assert.IsFalse(assemblyInfo.JitOptimization);
Assert.IsTrue(assemblyInfo.JitTracking);
assemblyInfo = ReadAssemblyInfo("[assembly: AssemblyFlags (0)]");
Assert.IsTrue(assemblyInfo.JitOptimization);
Assert.IsFalse(assemblyInfo.JitTracking);
assemblyInfo = ReadAssemblyInfo(
"[assembly: AssemblyFlags(AssemblyNameFlags.EnableJITcompileTracking)]");
Assert.IsTrue(assemblyInfo.JitOptimization);
Assert.IsTrue(assemblyInfo.JitTracking);
assemblyInfo = ReadAssemblyInfo(
"[assembly: AssemblyFlags(AssemblyNameFlags.EnableJITcompileOptimizer)]");
Assert.IsFalse(assemblyInfo.JitOptimization);
Assert.IsFalse(assemblyInfo.JitTracking);
assemblyInfo = ReadAssemblyInfo(
"[assembly: AssemblyFlags()]");
Assert.IsTrue(assemblyInfo.JitOptimization);
Assert.IsFalse(assemblyInfo.JitTracking);
assemblyInfo = ReadAssemblyInfo(
"[assembly: AssemblyFlags(AssemblyNameFlags.EnableJITcompileOptimizer | AssemblyNameFlags.EnableJITcompileTracking)]");
Assert.IsFalse(assemblyInfo.JitOptimization);
Assert.IsTrue(assemblyInfo.JitTracking);
}
[TestCase]
public void WriteAssemblyFlagsTests()
{
var assemblyInfo = new AssemblyInfo { JitOptimization = false, JitTracking = true };
Assert.AreEqual(
@"using System;
using System.Reflection;
[assembly: AssemblyFlags (AssemblyNameFlags.PublicKey | AssemblyNameFlags.EnableJITcompileOptimizer | AssemblyNameFlags.EnableJITcompileTracking)]
",
WriteAssemblyInfoFile(assemblyInfo, string.Empty));
assemblyInfo = new AssemblyInfo { JitOptimization = true, JitTracking = true };
Assert.AreEqual(
@"using System;
using System.Reflection;
[assembly: AssemblyFlags (AssemblyNameFlags.PublicKey | AssemblyNameFlags.EnableJITcompileTracking)]
",
WriteAssemblyInfoFile(assemblyInfo, string.Empty));
assemblyInfo = new AssemblyInfo { JitOptimization = true, JitTracking = false };
Assert.AreEqual("using System;\r\nusing System.Reflection;\r\n\r\n", WriteAssemblyInfoFile(assemblyInfo, string.Empty));
assemblyInfo = new AssemblyInfo { JitOptimization = false, JitTracking = false };
Assert.AreEqual(
@"using System;
using System.Reflection;
[assembly: AssemblyFlags (AssemblyNameFlags.PublicKey | AssemblyNameFlags.EnableJITcompileOptimizer)]
",
WriteAssemblyInfoFile(assemblyInfo, string.Empty));
}
[TestCase]
public void WriteDefaultAssemblyInfoToEmptyAssemblyInfoFileTest()
{
var assemblyInfoFile = "using System;";
var assemblyInfo = new AssemblyInfo { JitOptimization = true };
var result = WriteAssemblyInfoFile(assemblyInfo, assemblyInfoFile);
Assert.AreEqual("using System;\r\nusing System.Reflection;\r\n\r\n", result);
}
[TestCase]
public void WriteNotDefaultAssemblyInfoToEmptyAssemblyInfoFileTest()
{
var assemblyInfoFile = "using System.Reflection;";
var assemblyInfo = new AssemblyInfo
{
Title = "SharpDevelop",
Description = "OpenSource IDE",
Company = "Company",
Product = "Product",
Copyright = "Copyright 2014",
Trademark = "Trademark",
DefaultAlias = "Alias",
AssemblyVersion = new Version(1, 2, 3, 4),
AssemblyFileVersion = new Version(1, 2, 3, 4),
InformationalVersion = new Version(1, 2, 3, 4),
Guid = new Guid("0c8c889f-ced2-4167-b155-2d48a99d8c72"),
NeutralLanguage = "ru-RU",
ComVisible = true,
ClsCompliant = true,
JitOptimization = true,
JitTracking = true
};
var result = WriteAssemblyInfoFile(assemblyInfo, assemblyInfoFile);
Assert.AreEqual(
@"using System;
using System.Reflection;
using System.Resources;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle (""SharpDevelop"")]
[assembly: AssemblyDescription (""OpenSource IDE"")]
[assembly: AssemblyCompany (""Company"")]
[assembly: AssemblyProduct (""Product"")]
[assembly: AssemblyCopyright (""Copyright 2014"")]
[assembly: AssemblyTrademark (""Trademark"")]
[assembly: AssemblyDefaultAlias (""Alias"")]
[assembly: AssemblyVersion (""1.2.3.4"")]
[assembly: AssemblyFileVersion (""1.2.3.4"")]
[assembly: AssemblyInformationalVersion (""1.2.3.4"")]
[assembly: Guid (""0c8c889f-ced2-4167-b155-2d48a99d8c72"")]
[assembly: NeutralResourcesLanguage (""ru-RU"")]
[assembly: ComVisible (true)]
[assembly: CLSCompliant (true)]
[assembly: AssemblyFlags (AssemblyNameFlags.PublicKey | AssemblyNameFlags.EnableJITcompileTracking)]
", result);
}
[TestCase]
public void WriteNotDefaultAssemblyInfoToNotEmptyAssemblyInfoFileTest()
{
var assemblyInfoFile = AssemblyInfoSample1;
var assemblyInfo = new AssemblyInfo
{
Title = "SharpDevelop-changed",
Description = "OpenSource IDE-changed",
Company = "Company-changed",
Product = "Product-changed",
Copyright = "Copyright 2014-changed",
Trademark = "Trademark-changed",
DefaultAlias = "Alias-changed",
AssemblyVersion = new Version(4, 3, 2, 1),
AssemblyFileVersion = new Version(4, 3, 2, 1),
InformationalVersion = new Version(4, 3, 2, 1),
Guid = new Guid("dc8c889f-ced2-4167-b155-2d48a99d8c72"),
NeutralLanguage = "en-US",
ComVisible = false,
ClsCompliant = false,
JitOptimization = false,
JitTracking = false
};
var result = WriteAssemblyInfoFile(assemblyInfo, assemblyInfoFile);
Assert.AreEqual(
@"using System;
using System.Reflection;
using System.Resources;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle (""SharpDevelop-changed"")]
[assembly: AssemblyDescription (""OpenSource IDE-changed"")]
[assembly: AssemblyCompany (""Company-changed"")]
[assembly: AssemblyProduct (""Product-changed"")]
[assembly: AssemblyCopyright (""Copyright 2014-changed"")]
[assembly: AssemblyTrademark (""Trademark-changed"")]
[assembly: AssemblyDefaultAlias (""Alias-changed"")]
// This sets the default COM visibility of types in the assembly to invisible.
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
[assembly: ComVisible (false)]
// The assembly version has following format :
//
// Major.Minor.Build.Revision
//
// You can specify all the values or you can use the default the Revision and
// Build Numbers by using the '*' as shown below:
[assembly: AssemblyVersion (""4.3.2.1"")]
[assembly: AssemblyFileVersion (""4.3.2.1"")]
[assembly: AssemblyInformationalVersion (""4.3.2.1"")]
[assembly: Guid (""dc8c889f-ced2-4167-b155-2d48a99d8c72"")]
[assembly: NeutralResourcesLanguage (""en-US"")]
[assembly: AssemblyFlags (AssemblyNameFlags.PublicKey | AssemblyNameFlags.EnableJITcompileOptimizer)]
[assembly: CLSCompliant (false)]
", result);
}
private AssemblyInfo ReadAssemblyInfo(string assemblyInfoFile)
{
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(assemblyInfoFile)))
{
var assemblyInfoProvider = new AssemblyInfoProvider();
return assemblyInfoProvider.ReadAssemblyInfo(stream);
}
}
private string WriteAssemblyInfoFile(AssemblyInfo assemblyInfo, string sourceFile)
{
using (var inputStream = new MemoryStream(Encoding.UTF8.GetBytes(sourceFile)))
{
var assemblyInfoProvider = new AssemblyInfoProvider();
return assemblyInfoProvider.MergeAssemblyInfo(assemblyInfo, inputStream);
}
}
}
}
Loading…
Cancel
Save