Skip to content

Commit

Permalink
#23, #24
Browse files Browse the repository at this point in the history
  • Loading branch information
pgenfer committed Dec 3, 2016
1 parent 615ee3c commit 7b14eef
Show file tree
Hide file tree
Showing 16 changed files with 238 additions and 14 deletions.
28 changes: 28 additions & 0 deletions MixinRefactoring.Test/Common/NameMixinTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using NUnit.Framework;
using MixinRefactoring;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static NUnit.Framework.Assert;

namespace MixinRefactoring.Test
{
public class NameMixinTest : IntegrationTestBase
{
[TestDescription("Check that names with a reserved keyword are prefixed")]
public void NameIsReservedKeyword_Prefix()
{
var mixin = new NameMixin {Name = "new"};
AreEqual("@new", mixin.Name);
}

[TestDescription("Check that names without a reserved keyword are not prefixed")]
public void NameIsNotReservedKeyword_DoNotPrefix()
{
var mixin = new NameMixin { Name = "old" };
AreEqual("old", mixin.Name);
}
}
}
25 changes: 25 additions & 0 deletions MixinRefactoring.Test/MetaData/ParameterTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using NUnit.Framework;
using MixinRefactoring;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using static NUnit.Framework.Assert;
using static NSubstitute.Substitute;

namespace MixinRefactoring.Test
{
public class ParameterTest : IntegrationTestBase
{
// ensure that this issue is fixed:
// https://github.com/pgenfer/mixinSharp/issues/23
[TestDescription("Ensure that parameter name is prefixed")]
public void Parameter_Prefix_Name()
{
var parameter = new Parameter("double",For<ITypeSymbol>());
AreEqual("@double", parameter.Name);
}
}
}
2 changes: 2 additions & 0 deletions MixinRefactoring.Test/MixinRefactoring.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<Compile Include="Commands\CreateMixinFromInterfaceTestCommand.cs" />
<Compile Include="Common\NameMixinTest.cs" />
<Compile Include="Extensions\StringExtensionTest.cs" />
<Compile Include="Commands\AddFieldDeclarationForMixinCommandTests.cs" />
<Compile Include="Commands\AddMixinToBaseListCommandTest.cs" />
Expand Down Expand Up @@ -163,6 +164,7 @@
<Compile Include="Integration\IntegrationTestBase.cs" />
<Compile Include="MetaData\ClassTest.cs" />
<Compile Include="MetaData\MixinReferenceFactoryTest.cs" />
<Compile Include="MetaData\ParameterTest.cs" />
<Compile Include="Strategies\ImplementMethodForwardingTest.cs" />
<Compile Include="Strategies\ImplementPropertyForwardingTest.cs" />
<Compile Include="SyntaxReader\EventSyntaxReaderTest.cs" />
Expand Down
2 changes: 1 addition & 1 deletion MixinRefactoring.Vsix/source.extension.vsixmanifest
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
<Metadata>
<Identity Id="mixinSharp..6af25ee5-c001-4b3b-85f4-e7785ff466f0" Version="1.6" Language="en-US" Publisher="Patric Genfer" />
<Identity Id="mixinSharp..6af25ee5-c001-4b3b-85f4-e7785ff466f0" Version="1.6.1" Language="en-US" Publisher="Patric Genfer" />
<DisplayName>mixinSharp</DisplayName>
<Description xml:space="preserve">A code refactoring extension that adds mixin support to C# by auto generating the required code.</Description>
<MoreInfo>https://github.com/pgenfer/mixinSharp/wiki</MoreInfo>
Expand Down
7 changes: 7 additions & 0 deletions MixinRefactoring/CodeRefactoringProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContex
var settings = new Settings(serviceProvider);

var childClassDeclaration = node.FindContainingClass();
// it can happen that the field declaration is not inside a class declaration
// (e.g. the user just started typing inside an interface declaration
// and has not finished yet, so the node might look like a field declaration)
// in that case we stop processing here
if (childClassDeclaration == null)
return;

var childClass = new ClassFactory(model).Create(childClassDeclaration);
if (!command.CanExecute(childClass, settings))
return;
Expand Down
2 changes: 1 addition & 1 deletion MixinRefactoring/Commands/CompositeCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public ClassDeclarationSyntax Execute(
{
// we need the class name of the child to find it in the syntax tree
// after it was changed
var childClassName = childDeclaration.Identifier.Text.ToString();
var childClassName = childDeclaration.Identifier.Text;
foreach (var command in _commands)
{
var oldSyntaxTree = childDeclaration.SyntaxTree;
Expand Down
6 changes: 4 additions & 2 deletions MixinRefactoring/Commands/MixinCommandBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,10 @@ public abstract class MixinCommandBase : IMixinCommand
/// a reference to the mixin that should be included in the child class
/// </summary>
protected readonly MixinReference _mixin;

/// <summary>
/// initializes the base fields of the command object
/// </summary>
/// <param name="mixinChild">child class where the mixin should be added</param>
/// <param name="mixin">mixin that should be added to the child class</param>
protected MixinCommandBase(MixinReference mixin)
{
Expand All @@ -40,6 +39,7 @@ protected MixinCommandBase(MixinReference mixin)
/// <summary>
/// called to check if the command can be executed.
/// </summary>
/// <param name="childClass"></param>
/// <param name="settings">optional settings</param>
/// <returns>true if the command can be executed, otherwise false</returns>
public abstract bool CanExecute(
Expand All @@ -50,6 +50,7 @@ public abstract bool CanExecute(
/// executes the command on the given child class.
/// Logic of command execution must be implemented in derived classes.
/// </summary>
/// <param name="childClass"></param>
/// <param name="semantic">semantic model of the child's and mixin's source code</param>
/// <param name="settings">optional settings object</param>
/// <returns></returns>
Expand All @@ -62,6 +63,7 @@ protected abstract ClassDeclarationSyntax InternalExecute(
/// Template method that checks if command can be executed and if yes,
/// executes the command. Otherwise the original source code of the child is returned.
/// </summary>
/// <param name="childDeclaration"></param>
/// <param name="semantic">semantic model of the child's and mixin's source code</param>
/// <param name="settings">optional settings object</param>
/// <returns>the modified class declaration of the child class after executing
Expand Down
25 changes: 24 additions & 1 deletion MixinRefactoring/Common/NameMixin.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,32 @@

using Microsoft.CodeAnalysis.CSharp;

namespace MixinRefactoring
{
/// <summary>
/// stores all kind of names/identifiers during the processing.
/// Since identifiers can always be reserved keywords but are not prefixed
/// when retrieved during parsing, this mixin automatically adds a "@" in front
/// of all names that equal a reserved keyword.
/// </summary>
public class NameMixin
{
public string Name { get; set; }
private string _name;

private static string PrefixKeywords(string name)
{
var isAnyKeyword = SyntaxFacts.GetKeywordKind(name) != SyntaxKind.None;
if (isAnyKeyword)
name = $"@{name}";
return name;
}

public string Name
{
get { return _name; }
set { _name = PrefixKeywords(value); }
}

public override string ToString() => Name;
}
}
15 changes: 9 additions & 6 deletions MixinRefactoring/MetaData/Parameter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,9 @@ namespace MixinRefactoring
{
public class Parameter
{
public ITypeSymbol Type
{
get;
}
private readonly NameMixin _name = new NameMixin();

public string Name
public ITypeSymbol Type
{
get;
}
Expand All @@ -21,6 +18,12 @@ public Parameter(string name, ITypeSymbol type)
}

public bool IsEqual(Parameter other) => Name == other.Name && Type == other.Type;
public override string ToString() => string.Format("{0} {1}", Type.Name, Name);
public override string ToString() => $"{Type.Name} {Name}";

public string Name
{
get { return _name.Name; }
set { _name.Name = value; }
}
}
}
5 changes: 2 additions & 3 deletions MixinRefactoring/SemanticReader/ParameterSymbolReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp;

namespace MixinRefactoring
{
Expand All @@ -16,10 +17,8 @@ public ParameterSymbolReader(IParameterList parameters)
_parameters = parameters;
}

protected override void ReadSymbol(IParameterSymbol parameter)
{
protected override void ReadSymbol(IParameterSymbol parameter) =>
_parameters.Add(new Parameter(parameter.Name, parameter.Type));
}


protected override void ReadSymbol(IPropertySymbol propertySymbol)
Expand Down
12 changes: 12 additions & 0 deletions MixinRefactoringTests/MetaData/ParameterTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MixinRefactoringTests.MetaData
{
class ParameterTest
{
}
}
83 changes: 83 additions & 0 deletions MixinRefactoringTests/MixinRefactoringTests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{5394A626-C739-4B9C-A116-052E4B8F3487}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>MixinRefactoringTests</RootNamespace>
<AssemblyName>MixinRefactoringTests</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
<IsCodedUITest>False</IsCodedUITest>
<TestProjectType>UnitTest</TestProjectType>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<Choose>
<When Condition="('$(VisualStudioVersion)' == '10.0' or '$(VisualStudioVersion)' == '') and '$(TargetFrameworkVersion)' == 'v3.5'">
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
</ItemGroup>
</When>
<Otherwise>
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework" />
</ItemGroup>
</Otherwise>
</Choose>
<ItemGroup>
<Compile Include="UnitTest1.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Choose>
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Extension, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestTools.UITesting, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
</ItemGroup>
</When>
</Choose>
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
36 changes: 36 additions & 0 deletions MixinRefactoringTests/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
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("MixinRefactoringTests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("MixinRefactoringTests")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("5394a626-c739-4b9c-a116-052e4b8f3487")]

// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
4 changes: 4 additions & 0 deletions MixinRefactoringTests/packages.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="NUnit" version="3.0.1" targetFramework="net45" />
</packages>
Binary file modified images/icon_large.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/mixin_logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 7b14eef

Please sign in to comment.