Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

ReSharper support for derived Subject attributes

  • Loading branch information...
commit 374d012c9dedf54b8000b1cbb95c4fb4242e92c7 1 parent 12c6f6b
@citizenmatt authored
View
7 Machine.Specifications.sln
@@ -90,6 +90,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Machine.Specifications.ReSh
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Machine.Specifications.dotCoverRunner.2.2", "Source\Machine.Specifications.dotCoverRunner.2.2\Machine.Specifications.dotCoverRunner.2.2.csproj", "{B88940C4-9552-4C47-85F2-33E820CD9FD1}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Machine.Specifications.Example.DerivedSubject", "Source\Machine.Specifications.Example.DerivedSubject\Machine.Specifications.Example.DerivedSubject.csproj", "{13650EC6-35A0-429A-A779-DCA0214E7F79}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -228,6 +230,10 @@ Global
{B88940C4-9552-4C47-85F2-33E820CD9FD1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B88940C4-9552-4C47-85F2-33E820CD9FD1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B88940C4-9552-4C47-85F2-33E820CD9FD1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {13650EC6-35A0-429A-A779-DCA0214E7F79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {13650EC6-35A0-429A-A779-DCA0214E7F79}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {13650EC6-35A0-429A-A779-DCA0214E7F79}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {13650EC6-35A0-429A-A779-DCA0214E7F79}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -242,6 +248,7 @@ Global
{1295C389-FCE4-4425-93E4-E4AE239B3E35} = {85BC2C4A-493A-476C-971E-BE9CE51ECF5D}
{0CE411DF-CFC3-45E3-96AD-2F872D99E1B1} = {85BC2C4A-493A-476C-971E-BE9CE51ECF5D}
{A6B234F5-5D96-4809-BD25-86F6544BF838} = {85BC2C4A-493A-476C-971E-BE9CE51ECF5D}
+ {13650EC6-35A0-429A-A779-DCA0214E7F79} = {85BC2C4A-493A-476C-971E-BE9CE51ECF5D}
{E57865B9-C7EF-4340-8AF2-5D85F2545EC6} = {3D475ECE-C800-4087-8FC5-B9A13E76ABC4}
{CFF4B323-24C1-4B19-98CA-7DF92755458E} = {3D475ECE-C800-4087-8FC5-B9A13E76ABC4}
{F25C7917-4ED6-4261-B262-43C56D0CD37F} = {3D475ECE-C800-4087-8FC5-B9A13E76ABC4}
View
66 Source/Machine.Specifications.Example.DerivedSubject/DerivedSubjectSpecs.cs
@@ -0,0 +1,66 @@
+using System;
+
+namespace Machine.Specifications.Example.DerivedSubject
+{
+ public class Account
+ {
+ private decimal _balance;
+
+ public decimal Balance
+ {
+ get { return _balance; }
+ set { _balance = value; }
+ }
+
+ public void Transfer(decimal amount, Account toAccount)
+ {
+ if (amount > _balance)
+ {
+ throw new Exception(String.Format("Cannot transfer ${0}. The available balance is ${1}.", amount, _balance));
+ }
+
+ _balance -= amount;
+ toAccount.Balance += amount;
+ }
+ }
+
+ [MySubject(typeof(Account), "Funds transfer")]
+ public class when_transferring_between_two_accounts_with_derived_subject
+ : AccountSpecs
+ {
+ Because of = () =>
+ fromAccount.Transfer(1m, toAccount);
+
+ It should_debit_the_from_account_by_the_amount_transferred = () =>
+ fromAccount.Balance.ShouldEqual(0m);
+
+ It should_credit_the_to_account_by_the_amount_transferred = () =>
+ toAccount.Balance.ShouldEqual(2m);
+ }
+
+ [Subject(typeof(Account), "Funds transfer")]
+ public class when_transferring_between_two_accounts_with_normal_subject
+ : AccountSpecs
+ {
+ Because of = () =>
+ fromAccount.Transfer(1m, toAccount);
+
+ It should_debit_the_from_account_by_the_amount_transferred = () =>
+ fromAccount.Balance.ShouldEqual(0m);
+
+ It should_credit_the_to_account_by_the_amount_transferred = () =>
+ toAccount.Balance.ShouldEqual(2m);
+ }
+
+ public abstract class AccountSpecs
+ {
+ protected static Account fromAccount;
+ protected static Account toAccount;
+
+ Establish context = () =>
+ {
+ fromAccount = new Account { Balance = 1m };
+ toAccount = new Account { Balance = 1m };
+ };
+ }
+}
View
106 ...pecifications.Example.DerivedSubject/Machine.Specifications.Example.DerivedSubject.csproj
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{13650EC6-35A0-429A-A779-DCA0214E7F79}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Machine.Specifications.Example.DerivedSubject</RootNamespace>
+ <AssemblyName>Machine.Specifications.Example.DerivedSubject</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>3.5</OldToolsVersion>
+ <UpgradeBackupLocation />
+ <PublishUrl>publish\</PublishUrl>
+ <Install>true</Install>
+ <InstallFrom>Disk</InstallFrom>
+ <UpdateEnabled>false</UpdateEnabled>
+ <UpdateMode>Foreground</UpdateMode>
+ <UpdateInterval>7</UpdateInterval>
+ <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+ <UpdatePeriodically>false</UpdatePeriodically>
+ <UpdateRequired>false</UpdateRequired>
+ <MapFileExtensions>true</MapFileExtensions>
+ <ApplicationRevision>0</ApplicationRevision>
+ <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+ <IsWebBootstrapper>false</IsWebBootstrapper>
+ <UseApplicationTrust>false</UseApplicationTrust>
+ <BootstrapperEnabled>true</BootstrapperEnabled>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <RestorePackages>true</RestorePackages>
+ </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>
+ <NoWarn>169</NoWarn>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </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>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="..\SharedAssemblyInfo.cs">
+ <Link>Properties\SharedAssemblyInfo.cs</Link>
+ </Compile>
+ <Compile Include="..\VersionInfo.cs">
+ <Link>Properties\VersionInfo.cs</Link>
+ </Compile>
+ <Compile Include="DerivedSubjectSpecs.cs" />
+ <Compile Include="MySubjectAttribute.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Machine.Specifications\Machine.Specifications.csproj">
+ <Project>{CCD02629-1262-4F78-9E9F-AC97B942D0E7}</Project>
+ <Name>Machine.Specifications</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+ <Visible>False</Visible>
+ <ProductName>Windows Installer 3.1</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(SolutionDir)\.nuget\nuget.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>
View
19 Source/Machine.Specifications.Example.DerivedSubject/MySubjectAttribute.cs
@@ -0,0 +1,19 @@
+using System;
+
+namespace Machine.Specifications.Example.DerivedSubject
+{
+ public class MySubjectAttribute : SubjectAttribute
+ {
+ public MySubjectAttribute(Type subjectType) : base(subjectType)
+ {
+ }
+
+ public MySubjectAttribute(Type subjectType, string subject) : base(subjectType, subject)
+ {
+ }
+
+ public MySubjectAttribute(string subject) : base(subject)
+ {
+ }
+ }
+}
View
21 Source/Machine.Specifications.Example.DerivedSubject/Properties/AssemblyInfo.cs
@@ -0,0 +1,21 @@
+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("Machine.Specifications.Example.Random")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[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("e01bfd4e-4f67-4681-b84e-1aaa4217f239")]
View
397 Source/Machine.Specifications.ReSharperRunner.6.0/MetadataExtensions.cs
@@ -1,195 +1,202 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Linq;
-using System.Text;
-
-using JetBrains.Metadata.Reader.API;
-using JetBrains.ReSharper.Psi;
-using JetBrains.Util;
-
-namespace Machine.Specifications.ReSharperRunner
-{
- internal static partial class MetadataExtensions
- {
- public static bool IsContext(this IMetadataTypeInfo type)
- {
- return !type.IsAbstract &&
- !type.IsStruct() &&
- type.GenericParameters.Length == 0 &&
- !type.HasCustomAttribute(typeof(BehaviorsAttribute).FullName) &&
- (type.GetSpecifications().Any() ||
- type.GetBehaviors().Any());
- }
-
- static bool IsStruct(this IMetadataTypeInfo type)
- {
- if (type.Base != null)
- {
- return type.Base.Type.FullyQualifiedName == typeof(ValueType).FullName;
- }
- return false;
- }
-
- public static IEnumerable<IMetadataField> GetSpecifications(this IMetadataTypeInfo type)
- {
- var privateFieldsOfType = type.GetInstanceFieldsOfType<It>();
- return privateFieldsOfType;
- }
-
- public static IEnumerable<IMetadataField> GetBehaviors(this IMetadataTypeInfo type)
- {
- IEnumerable<IMetadataField> behaviorFields = type.GetInstanceFieldsOfType(typeof(Behaves_like<>));
- foreach (IMetadataField field in behaviorFields)
- {
- if (field.GetFirstGenericArgument().HasCustomAttribute(typeof(BehaviorsAttribute).FullName))
- {
- yield return field;
- }
- }
- }
-
- public static string GetSubjectString(this IMetadataEntity type)
- {
- var attributes = type.GetCustomAttributes(typeof(SubjectAttribute).FullName);
- if (attributes.Count != 1)
- {
- var asMember = type as IMetadataTypeMember;
- if (asMember != null && asMember.DeclaringType != null)
- {
- return asMember.DeclaringType.GetSubjectString();
- }
- return null;
- }
-
- var attribute = attributes.First();
-
- var parameters = attribute.ConstructorArguments.Select(x =>
- {
- var typeArgument = x.Value as IMetadataClassType;
- if (typeArgument != null)
- {
- return new ClrTypeName(typeArgument.Type.FullyQualifiedName).ShortName;
- }
-
- return (string)x.Value;
- }).ToArray();
-
- return String.Join(" ", parameters);
- }
-
- public static ICollection<string> GetTags(this IMetadataEntity type)
- {
- return type.AndAllBaseTypes()
- .SelectMany(x => x.GetCustomAttributes(typeof(TagsAttribute).FullName))
- .Select(x => x.ConstructorArguments)
- .Flatten(tag => tag.FirstOrDefault().Value as string,
- tag => tag.Skip(1).FirstOrDefault().ValuesArray.Select(v => v.Value as string))
- .Distinct()
- .ToList();
- }
-
- static IEnumerable<IMetadataTypeInfo> AndAllBaseTypes(this IMetadataEntity type)
- {
- var typeInfo = type as IMetadataTypeInfo;
- if (typeInfo == null)
- {
- yield break;
- }
-
- yield return typeInfo;
-
- while (typeInfo.Base != null && typeInfo.Base.Type != null)
- {
- yield return typeInfo.Base.Type;
-
- typeInfo = typeInfo.Base.Type;
- }
- }
-
- public static IMetadataTypeInfo GetFirstGenericArgument(this IMetadataField genericField)
- {
- var genericArgument = ((IMetadataClassType)genericField.Type).Arguments.First();
- return ((IMetadataClassType)genericArgument).Type;
- }
-
- public static IMetadataClassType FirstGenericArgumentClass(this IMetadataField genericField)
- {
- var genericArgument = ((IMetadataClassType)genericField.Type).Arguments.First();
- return genericArgument as IMetadataClassType;
- }
-
- public static bool IsIgnored(this IMetadataEntity type)
- {
- return type.HasCustomAttribute(typeof(IgnoreAttribute).FullName);
- }
-
- static IEnumerable<TResult> Flatten<TSource, TResult>(this IEnumerable<TSource> source,
- Func<TSource, TResult> singleResultSelector,
- Func<TSource, IEnumerable<TResult>> collectionResultSelector)
- {
- foreach (var s in source)
- {
- yield return singleResultSelector(s);
- var resultSelector = collectionResultSelector(s);
- if (resultSelector == null)
- {
- yield break;
- }
- foreach (var coll in collectionResultSelector(s))
- {
- yield return coll;
- }
- }
- }
-
- static IEnumerable<IMetadataField> GetInstanceFields(this IMetadataTypeInfo type)
- {
- return type.GetFields().Where(field => !field.IsStatic);
- }
-
- static IEnumerable<IMetadataField> GetInstanceFieldsOfType<T>(this IMetadataTypeInfo type)
- {
- return type.GetInstanceFieldsOfType(typeof(T));
- }
-
- static IEnumerable<IMetadataField> GetInstanceFieldsOfType(this IMetadataTypeInfo type, Type fieldType)
- {
- var metadataFields = type.GetInstanceFields();
- var fields = metadataFields.Where(x => x.Type is IMetadataClassType);
- return fields.Where(x => (((IMetadataClassType)x.Type).Type.FullyQualifiedName == fieldType.FullName));
- }
-
- public static string FullyQualifiedName(this IMetadataClassType classType)
- {
- return FullyQualifiedName(classType, false);
- }
-
- static string FullyQualifiedName(this IMetadataClassType classType, bool appendAssembly)
- {
- var fullyQualifiedName = new StringBuilder();
-
- fullyQualifiedName.Append(classType.Type.FullyQualifiedName);
-
- if (classType.Arguments.Length > 0)
- {
- fullyQualifiedName.Append("[");
- fullyQualifiedName.Append(
- String.Join(",",
- classType.Arguments
- .Select(x => x as IMetadataClassType)
- .Where(x => x != null)
- .Select(x => "[" + x.FullyQualifiedName(true) + "]")
- .ToArray()));
- fullyQualifiedName.Append("]");
- }
-
- if (appendAssembly)
- {
- fullyQualifiedName.Append(classType.AssemblyQualification);
- }
-
- return fullyQualifiedName.ToString();
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+
+using JetBrains.Metadata.Reader.API;
+using JetBrains.ReSharper.Psi;
+using JetBrains.Util;
+
+namespace Machine.Specifications.ReSharperRunner
+{
+ internal static partial class MetadataExtensions
+ {
+ public static bool IsContext(this IMetadataTypeInfo type)
+ {
+ return !type.IsAbstract &&
+ !type.IsStruct() &&
+ type.GenericParameters.Length == 0 &&
+ !type.HasCustomAttribute(typeof(BehaviorsAttribute).FullName) &&
+ (type.GetSpecifications().Any() ||
+ type.GetBehaviors().Any());
+ }
+
+ static bool IsStruct(this IMetadataTypeInfo type)
+ {
+ if (type.Base != null)
+ {
+ return type.Base.Type.FullyQualifiedName == typeof(ValueType).FullName;
+ }
+ return false;
+ }
+
+ public static IEnumerable<IMetadataField> GetSpecifications(this IMetadataTypeInfo type)
+ {
+ var privateFieldsOfType = type.GetInstanceFieldsOfType<It>();
+ return privateFieldsOfType;
+ }
+
+ public static IEnumerable<IMetadataField> GetBehaviors(this IMetadataTypeInfo type)
+ {
+ IEnumerable<IMetadataField> behaviorFields = type.GetInstanceFieldsOfType(typeof(Behaves_like<>));
+ foreach (IMetadataField field in behaviorFields)
+ {
+ if (field.GetFirstGenericArgument().HasCustomAttribute(typeof(BehaviorsAttribute).FullName))
+ {
+ yield return field;
+ }
+ }
+ }
+
+ public static string GetSubjectString(this IMetadataEntity type)
+ {
+ var attributes = GetSubjectAttributes(type);
+ if (attributes.Count != 1)
+ {
+ var asMember = type as IMetadataTypeMember;
+ if (asMember != null && asMember.DeclaringType != null)
+ {
+ return asMember.DeclaringType.GetSubjectString();
+ }
+ return null;
+ }
+
+ var attribute = attributes.First();
+
+ var parameters = attribute.ConstructorArguments.Select(x =>
+ {
+ var typeArgument = x.Value as IMetadataClassType;
+ if (typeArgument != null)
+ {
+ return new ClrTypeName(typeArgument.Type.FullyQualifiedName).ShortName;
+ }
+
+ return (string)x.Value;
+ }).ToArray();
+
+ return String.Join(" ", parameters);
+ }
+
+ private static IList<IMetadataCustomAttribute> GetSubjectAttributes(IMetadataEntity type)
+ {
+ return (from customAttribute in type.CustomAttributes
+ where customAttribute.AndAllBaseTypes().Any(i => i.FullyQualifiedName == typeof(SubjectAttribute).FullName)
+ select customAttribute).ToList();
+ }
+
+ public static ICollection<string> GetTags(this IMetadataEntity type)
+ {
+ return type.AndAllBaseTypes()
+ .SelectMany(x => x.GetCustomAttributes(typeof(TagsAttribute).FullName))
+ .Select(x => x.ConstructorArguments)
+ .Flatten(tag => tag.FirstOrDefault().Value as string,
+ tag => tag.Skip(1).FirstOrDefault().ValuesArray.Select(v => v.Value as string))
+ .Distinct()
+ .ToList();
+ }
+
+ static IEnumerable<IMetadataTypeInfo> AndAllBaseTypes(this IMetadataEntity type)
+ {
+ var typeInfo = type as IMetadataTypeInfo;
+ if (typeInfo == null)
+ {
+ yield break;
+ }
+
+ yield return typeInfo;
+
+ while (typeInfo.Base != null && typeInfo.Base.Type != null)
+ {
+ yield return typeInfo.Base.Type;
+
+ typeInfo = typeInfo.Base.Type;
+ }
+ }
+
+ public static IMetadataTypeInfo GetFirstGenericArgument(this IMetadataField genericField)
+ {
+ var genericArgument = ((IMetadataClassType)genericField.Type).Arguments.First();
+ return ((IMetadataClassType)genericArgument).Type;
+ }
+
+ public static IMetadataClassType FirstGenericArgumentClass(this IMetadataField genericField)
+ {
+ var genericArgument = ((IMetadataClassType)genericField.Type).Arguments.First();
+ return genericArgument as IMetadataClassType;
+ }
+
+ public static bool IsIgnored(this IMetadataEntity type)
+ {
+ return type.HasCustomAttribute(typeof(IgnoreAttribute).FullName);
+ }
+
+ static IEnumerable<TResult> Flatten<TSource, TResult>(this IEnumerable<TSource> source,
+ Func<TSource, TResult> singleResultSelector,
+ Func<TSource, IEnumerable<TResult>> collectionResultSelector)
+ {
+ foreach (var s in source)
+ {
+ yield return singleResultSelector(s);
+ var resultSelector = collectionResultSelector(s);
+ if (resultSelector == null)
+ {
+ yield break;
+ }
+ foreach (var coll in collectionResultSelector(s))
+ {
+ yield return coll;
+ }
+ }
+ }
+
+ static IEnumerable<IMetadataField> GetInstanceFields(this IMetadataTypeInfo type)
+ {
+ return type.GetFields().Where(field => !field.IsStatic);
+ }
+
+ static IEnumerable<IMetadataField> GetInstanceFieldsOfType<T>(this IMetadataTypeInfo type)
+ {
+ return type.GetInstanceFieldsOfType(typeof(T));
+ }
+
+ static IEnumerable<IMetadataField> GetInstanceFieldsOfType(this IMetadataTypeInfo type, Type fieldType)
+ {
+ var metadataFields = type.GetInstanceFields();
+ var fields = metadataFields.Where(x => x.Type is IMetadataClassType);
+ return fields.Where(x => (((IMetadataClassType)x.Type).Type.FullyQualifiedName == fieldType.FullName));
+ }
+
+ public static string FullyQualifiedName(this IMetadataClassType classType)
+ {
+ return FullyQualifiedName(classType, false);
+ }
+
+ static string FullyQualifiedName(this IMetadataClassType classType, bool appendAssembly)
+ {
+ var fullyQualifiedName = new StringBuilder();
+
+ fullyQualifiedName.Append(classType.Type.FullyQualifiedName);
+
+ if (classType.Arguments.Length > 0)
+ {
+ fullyQualifiedName.Append("[");
+ fullyQualifiedName.Append(
+ String.Join(",",
+ classType.Arguments
+ .Select(x => x as IMetadataClassType)
+ .Where(x => x != null)
+ .Select(x => "[" + x.FullyQualifiedName(true) + "]")
+ .ToArray()));
+ fullyQualifiedName.Append("]");
+ }
+
+ if (appendAssembly)
+ {
+ fullyQualifiedName.Append(classType.AssemblyQualification);
+ }
+
+ return fullyQualifiedName.ToString();
+ }
+ }
+}
View
622 Source/Machine.Specifications.ReSharperRunner.6.0/PsiExtensions.cs
@@ -1,307 +1,315 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-using JetBrains.Application.Progress;
-using JetBrains.ReSharper.Psi;
-using JetBrains.ReSharper.Psi.Search;
-using JetBrains.ReSharper.Psi.Tree;
-
-using CLRTypeName = JetBrains.ReSharper.Psi.ClrTypeName;
-
-namespace Machine.Specifications.ReSharperRunner
-{
- internal static partial class PsiExtensions
- {
- public static bool IsContext(this IDeclaredElement element)
- {
- var clazz = element as IClass;
- if (clazz == null)
- {
- return false;
- }
-
- var fields = clazz.Fields;
- if (fields == null || !fields.Any())
- {
- return false;
- }
-
- return clazz.IsValid() &&
- !clazz.IsAbstract &&
- !clazz.HasAttributeInstance(new CLRTypeName(typeof(BehaviorsAttribute).FullName), false) &&
- fields.Any(x => IsSpecification(x) || IsBehavior(x));
- }
-
- public static bool IsBehaviorContainer(this IDeclaredElement element)
- {
- var clazz = element as IClass;
- if (clazz == null)
- {
- return false;
- }
-
- return clazz.IsValid() &&
- !clazz.IsAbstract &&
- clazz.HasAttributeInstance(new CLRTypeName(typeof(BehaviorsAttribute).FullName), false) &&
- clazz.GetFirstGenericArgument() == null &&
- clazz.Fields.Any(IsSpecification);
- }
-
- public static bool IsSpecification(this IDeclaredElement element)
- {
- return element.IsValidFieldOfType(typeof(It));
- }
-
- public static bool IsSupportingField(this IDeclaredElement element)
- {
- return element.IsValidFieldOfType(typeof(Establish)) ||
- element.IsValidFieldOfType(typeof(Because)) ||
- element.IsValidFieldOfType(typeof(Cleanup));
- }
-
- public static bool IsField(this IDeclaredElement element)
- {
- return element is IField;
- }
-
- public static bool IsConstant(this IDeclaredElement element)
- {
- return (element.IsField() && ((IField)element).IsConstant) ||
- (element.IsLocal() && ((ILocalVariable)element).IsConstant);
- }
-
- public static bool IsLocal(this IDeclaredElement element)
- {
- return element is ILocalVariable;
- }
-
- public static bool IsBehavior(this IDeclaredElement element)
- {
- return element.IsValidFieldOfType(typeof(Behaves_like<>)) &&
- element.GetFirstGenericArgument() != null &&
- element.GetFirstGenericArgument().GetFirstGenericArgument() == null &&
- element.GetFirstGenericArgument().HasAttributeInstance(
- new CLRTypeName(typeof(BehaviorsAttribute).FullName), false);
- }
-
- public static IClass GetFirstGenericArgument(this IDeclaredElement element)
- {
- IDeclaredType fieldType = element.GetValidatedFieldType();
- if (fieldType == null)
- {
- return null;
- }
-
- var firstArgument = fieldType.GetSubstitution().Domain.First();
- var referencedType = fieldType.GetSubstitution().Apply(firstArgument).GetScalarType();
-
- if (referencedType != null)
- {
- return referencedType.GetTypeElement() as IClass;
- }
-
- return null;
- }
-
- public static IEnumerable<IField> GetBehaviorSpecifications(this IClass clazz)
- {
- return clazz.Fields.Where(IsSpecification);
- }
-
- public static bool IsIgnored(this IDeclaredElement element)
- {
- IAttributesOwner attributeOwner = element as IAttributesOwner;
- if (attributeOwner == null)
- {
- return false;
- }
-
- IInitializerOwnerDeclaration initializer = element as IInitializerOwnerDeclaration;
- bool hasInitializer = true;
- if (initializer != null)
- {
- hasInitializer = initializer.Initializer != null;
- }
-
- return !hasInitializer || attributeOwner.HasAttributeInstance(new CLRTypeName(typeof(IgnoreAttribute).FullName), false);
- }
-
- public static string GetSubjectString(this IAttributesOwner type)
- {
- var attribute = type.GetAttributeInstances(new CLRTypeName(typeof(SubjectAttribute).FullName), true)
- .FirstOrDefault();
-
- if (attribute == null)
- {
- var containingType = type.GetContainingType();
- if (containingType == null)
- {
- return null;
- }
-
- return containingType.GetSubjectString();
- }
-
- if (attribute.PositionParameters().Any(x => x.IsBadValue))
- {
- return null;
- }
-
- if (attribute.PositionParameters()
- .Where(x => x.IsType)
- .Select(x => x.TypeValue as IDeclaredType)
- .Any(x => x.IsInvalid()))
- {
- return null;
- }
-
- try
- {
- var parameters = attribute.PositionParameters()
- .Select(x =>
- {
- if (x.IsType)
- {
- var declaredType = (IDeclaredType) x.TypeValue;
- return declaredType.GetClrName().ShortName;
- }
-
- return (string) x.ConstantValue.Value;
- })
- .ToArray();
-
- return String.Join(" ", parameters);
- }
- catch (Exception)
- {
- return null;
- }
- }
-
- public static ICollection<string> GetTags(this IAttributesOwner type)
- {
- return type.GetAttributeInstances(new CLRTypeName(typeof(TagsAttribute).FullName), true)
- .SelectMany(x => x.PositionParameters())
- .SelectMany(x =>
- {
- if (x.IsArray)
- {
- return x.ArrayValue.Select(av => av.ConstantValue);
- }
-
- return new[] {x.ConstantValue};
- })
- .Select(v => v.Value.ToString())
- .Distinct()
- .ToList();
- }
-
- static bool IsValidFieldOfType(this IDeclaredElement element, Type type)
- {
- IDeclaredType fieldType = element.GetValidatedFieldType();
- if (fieldType == null)
- {
- return false;
- }
-
- return fieldType.GetClrName().FullName == type.FullName;
- }
-
- static IDeclaredType GetValidatedFieldType(this IDeclaredElement element)
- {
- IField field = element as IField;
- if (field == null)
- {
- return null;
- }
-
- IDeclaredType fieldType = field.Type as IDeclaredType;
- if (fieldType == null)
- {
- return null;
- }
-
- if (!field.IsValid() ||
- !fieldType.IsResolved)
- {
- return null;
- }
-
- return fieldType;
- }
-
- static IEnumerable<AttributeValue> PositionParameters(this IAttributeInstance source)
- {
- for (int i = 0; i < source.PositionParameterCount; i++)
- {
- yield return source.PositionParameter(i);
- }
- }
-
- static bool IsInvalid(this IExpressionType type)
- {
- return type == null || !type.IsValid();
- }
-
- public static bool IsContextBaseClass(this IDeclaredElement element)
- {
- var clazz = element as IClass;
- if (clazz == null)
- {
- return false;
- }
-
- var contextBaseCandidate = !element.IsContext() &&
- clazz.IsValid() &&
- clazz.GetContainingType() == null;
- if (!contextBaseCandidate)
- {
- return false;
- }
-
- IFinder finder = clazz.GetSolution().GetPsiServices().Finder;
- var searchDomain = clazz.GetSearchDomain();
-
- var findResult = new InheritedContextFinder();
-
- finder.FindInheritors(clazz,
- searchDomain,
- findResult.Consumer,
- NullProgressIndicator.Instance);
-
- return findResult.Found;
- }
-
- class InheritedContextFinder
- {
- public InheritedContextFinder()
- {
- Found = false;
-
- Consumer = new FindResultConsumer(result =>
- {
- FindResultDeclaredElement foundElement = result as FindResultDeclaredElement;
- if (foundElement != null)
- {
- Found = foundElement.DeclaredElement.IsContext();
- }
-
- return Found ? FindExecution.Stop : FindExecution.Continue;
- });
- }
-
- public bool Found
- {
- get;
- private set;
- }
-
- public FindResultConsumer Consumer
- {
- get;
- private set;
- }
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+using JetBrains.Application.Progress;
+using JetBrains.ReSharper.Psi;
+using JetBrains.ReSharper.Psi.Search;
+using JetBrains.ReSharper.Psi.Tree;
+
+using CLRTypeName = JetBrains.ReSharper.Psi.ClrTypeName;
+
+using JetBrains.ReSharper.Psi.Util;
+
+namespace Machine.Specifications.ReSharperRunner
+{
+ internal static partial class PsiExtensions
+ {
+ public static bool IsContext(this IDeclaredElement element)
+ {
+ var clazz = element as IClass;
+ if (clazz == null)
+ {
+ return false;
+ }
+
+ var fields = clazz.Fields;
+ if (fields == null || !fields.Any())
+ {
+ return false;
+ }
+
+ return clazz.IsValid() &&
+ !clazz.IsAbstract &&
+ !clazz.HasAttributeInstance(new CLRTypeName(typeof(BehaviorsAttribute).FullName), false) &&
+ fields.Any(x => IsSpecification(x) || IsBehavior(x));
+ }
+
+ public static bool IsBehaviorContainer(this IDeclaredElement element)
+ {
+ var clazz = element as IClass;
+ if (clazz == null)
+ {
+ return false;
+ }
+
+ return clazz.IsValid() &&
+ !clazz.IsAbstract &&
+ clazz.HasAttributeInstance(new CLRTypeName(typeof(BehaviorsAttribute).FullName), false) &&
+ clazz.GetFirstGenericArgument() == null &&
+ clazz.Fields.Any(IsSpecification);
+ }
+
+ public static bool IsSpecification(this IDeclaredElement element)
+ {
+ return element.IsValidFieldOfType(typeof(It));
+ }
+
+ public static bool IsSupportingField(this IDeclaredElement element)
+ {
+ return element.IsValidFieldOfType(typeof(Establish)) ||
+ element.IsValidFieldOfType(typeof(Because)) ||
+ element.IsValidFieldOfType(typeof(Cleanup));
+ }
+
+ public static bool IsField(this IDeclaredElement element)
+ {
+ return element is IField;
+ }
+
+ public static bool IsConstant(this IDeclaredElement element)
+ {
+ return (element.IsField() && ((IField)element).IsConstant) ||
+ (element.IsLocal() && ((ILocalVariable)element).IsConstant);
+ }
+
+ public static bool IsLocal(this IDeclaredElement element)
+ {
+ return element is ILocalVariable;
+ }
+
+ public static bool IsBehavior(this IDeclaredElement element)
+ {
+ return element.IsValidFieldOfType(typeof(Behaves_like<>)) &&
+ element.GetFirstGenericArgument() != null &&
+ element.GetFirstGenericArgument().GetFirstGenericArgument() == null &&
+ element.GetFirstGenericArgument().HasAttributeInstance(
+ new CLRTypeName(typeof(BehaviorsAttribute).FullName), false);
+ }
+
+ public static IClass GetFirstGenericArgument(this IDeclaredElement element)
+ {
+ IDeclaredType fieldType = element.GetValidatedFieldType();
+ if (fieldType == null)
+ {
+ return null;
+ }
+
+ var firstArgument = fieldType.GetSubstitution().Domain.First();
+ var referencedType = fieldType.GetSubstitution().Apply(firstArgument).GetScalarType();
+
+ if (referencedType != null)
+ {
+ return referencedType.GetTypeElement() as IClass;
+ }
+
+ return null;
+ }
+
+ public static IEnumerable<IField> GetBehaviorSpecifications(this IClass clazz)
+ {
+ return clazz.Fields.Where(IsSpecification);
+ }
+
+ public static bool IsIgnored(this IDeclaredElement element)
+ {
+ IAttributesOwner attributeOwner = element as IAttributesOwner;
+ if (attributeOwner == null)
+ {
+ return false;
+ }
+
+ IInitializerOwnerDeclaration initializer = element as IInitializerOwnerDeclaration;
+ bool hasInitializer = true;
+ if (initializer != null)
+ {
+ hasInitializer = initializer.Initializer != null;
+ }
+
+ return !hasInitializer || attributeOwner.HasAttributeInstance(new CLRTypeName(typeof(IgnoreAttribute).FullName), false);
+ }
+
+ public static string GetSubjectString(this IAttributesOwner type)
+ {
+ var attribute = GetSubjectAttribute(type);
+ if (attribute == null)
+ {
+ var containingType = type.GetContainingType();
+ if (containingType == null)
+ {
+ return null;
+ }
+
+ return containingType.GetSubjectString();
+ }
+
+ if (attribute.PositionParameters().Any(x => x.IsBadValue))
+ {
+ return null;
+ }
+
+ if (attribute.PositionParameters()
+ .Where(x => x.IsType)
+ .Select(x => x.TypeValue as IDeclaredType)
+ .Any(x => x.IsInvalid()))
+ {
+ return null;
+ }
+
+ try
+ {
+ var parameters = attribute.PositionParameters()
+ .Select(x =>
+ {
+ if (x.IsType)
+ {
+ var declaredType = (IDeclaredType) x.TypeValue;
+ return declaredType.GetClrName().ShortName;
+ }
+
+ return (string) x.ConstantValue.Value;
+ })
+ .ToArray();
+
+ return String.Join(" ", parameters);
+ }
+ catch (Exception)
+ {
+ return null;
+ }
+ }
+
+ private static IAttributeInstance GetSubjectAttribute(IAttributesSet type)
+ {
+ return (from a in type.GetAttributeInstances(true)
+ let h = (new[] { a.AttributeType}).Concat(a.AttributeType.GetSuperTypes())
+ where h.Any(t => t.GetClrName().FullName == typeof(SubjectAttribute).FullName)
+ select a).FirstOrDefault();
+ }
+
+ public static ICollection<string> GetTags(this IAttributesOwner type)
+ {
+ return type.GetAttributeInstances(new CLRTypeName(typeof(TagsAttribute).FullName), true)
+ .SelectMany(x => x.PositionParameters())
+ .SelectMany(x =>
+ {
+ if (x.IsArray)
+ {
+ return x.ArrayValue.Select(av => av.ConstantValue);
+ }
+
+ return new[] {x.ConstantValue};
+ })
+ .Select(v => v.Value.ToString())
+ .Distinct()
+ .ToList();
+ }
+
+ static bool IsValidFieldOfType(this IDeclaredElement element, Type type)
+ {
+ IDeclaredType fieldType = element.GetValidatedFieldType();
+ if (fieldType == null)
+ {
+ return false;
+ }
+
+ return fieldType.GetClrName().FullName == type.FullName;
+ }
+
+ static IDeclaredType GetValidatedFieldType(this IDeclaredElement element)
+ {
+ IField field = element as IField;
+ if (field == null)
+ {
+ return null;
+ }
+
+ IDeclaredType fieldType = field.Type as IDeclaredType;
+ if (fieldType == null)
+ {
+ return null;
+ }
+
+ if (!field.IsValid() ||
+ !fieldType.IsResolved)
+ {
+ return null;
+ }
+
+ return fieldType;
+ }
+
+ static IEnumerable<AttributeValue> PositionParameters(this IAttributeInstance source)
+ {
+ for (int i = 0; i < source.PositionParameterCount; i++)
+ {
+ yield return source.PositionParameter(i);
+ }
+ }
+
+ static bool IsInvalid(this IExpressionType type)
+ {
+ return type == null || !type.IsValid();
+ }
+
+ public static bool IsContextBaseClass(this IDeclaredElement element)
+ {
+ var clazz = element as IClass;
+ if (clazz == null)
+ {
+ return false;
+ }
+
+ var contextBaseCandidate = !element.IsContext() &&
+ clazz.IsValid() &&
+ clazz.GetContainingType() == null;
+ if (!contextBaseCandidate)
+ {
+ return false;
+ }
+
+ IFinder finder = clazz.GetSolution().GetPsiServices().Finder;
+ var searchDomain = clazz.GetSearchDomain();
+
+ var findResult = new InheritedContextFinder();
+
+ finder.FindInheritors(clazz,
+ searchDomain,
+ findResult.Consumer,
+ NullProgressIndicator.Instance);
+
+ return findResult.Found;
+ }
+
+ class InheritedContextFinder
+ {
+ public InheritedContextFinder()
+ {
+ Found = false;
+
+ Consumer = new FindResultConsumer(result =>
+ {
+ FindResultDeclaredElement foundElement = result as FindResultDeclaredElement;
+ if (foundElement != null)
+ {
+ Found = foundElement.DeclaredElement.IsContext();
+ }
+
+ return Found ? FindExecution.Stop : FindExecution.Continue;
+ });
+ }
+
+ public bool Found
+ {
+ get;
+ private set;
+ }
+
+ public FindResultConsumer Consumer
+ {
+ get;
+ private set;
+ }
+ }
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.