Browse Source

Merge remote-tracking branch 'upstream/master' into mansheng

newNRvisualizers
Mansheng Yang 14 years ago
parent
commit
7375967d8f
  1. 22
      ICSharpCode.NRefactory.CSharp.AstVerifier/ICSharpCode.NRefactory.CSharp.AstVerifier.csproj
  2. 21
      ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj
  3. 1
      ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs
  4. 4
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/GeneratePropertyAction.cs
  5. 2
      ICSharpCode.NRefactory.CSharp/Resolver/CSharpAstResolver.cs
  6. 11
      ICSharpCode.NRefactory.CSharp/Resolver/CSharpInvocationResolveResult.cs
  7. 2
      ICSharpCode.NRefactory.CSharp/Resolver/CSharpResolver.cs
  8. 5
      ICSharpCode.NRefactory.CSharp/Resolver/Log.cs
  9. 55
      ICSharpCode.NRefactory.CSharp/Resolver/OverloadResolution.cs
  10. 144
      ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs
  11. 11
      ICSharpCode.NRefactory.CSharp/TypeSystem/TypeSystemConvertVisitor.cs
  12. 18
      ICSharpCode.NRefactory.ConsistencyCheck/ICSharpCode.NRefactory.ConsistencyCheck.csproj
  13. 30
      ICSharpCode.NRefactory.Demo/ICSharpCode.NRefactory.Demo.csproj
  14. 22
      ICSharpCode.NRefactory.GtkDemo/ICSharpCode.NRefactory.GtkDemo.csproj
  15. 6
      ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ContextActionTestBase.cs
  16. 28
      ICSharpCode.NRefactory.Tests/CSharp/CodeActions/GeneratePropertyTests.cs
  17. 19
      ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/PreprocessorDirectiveTests.cs
  18. 70
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/InvocationTests.cs
  19. 41
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/MethodTests.cs
  20. 42
      ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj
  21. 22
      ICSharpCode.NRefactory.Xml/ICSharpCode.NRefactory.Xml.csproj
  22. 25
      ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj
  23. 81
      ICSharpCode.NRefactory/Semantics/NamedArgumentResolveResult.cs
  24. 54
      ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs
  25. 46
      ICSharpCode.NRefactory/TypeSystem/IAttribute.cs
  26. 20
      ICSharpCode.NRefactory/TypeSystem/IFreezable.cs
  27. 22
      ICSharpCode.NRefactory/TypeSystem/IInterningProvider.cs
  28. 26
      ICSharpCode.NRefactory/TypeSystem/ISupportsInterning.cs
  29. 1
      ICSharpCode.NRefactory/TypeSystem/IType.cs
  30. 20
      ICSharpCode.NRefactory/TypeSystem/ITypeDefinition.cs
  31. 18
      ICSharpCode.NRefactory/TypeSystem/ITypeReference.cs
  32. 36
      ICSharpCode.NRefactory/TypeSystem/IVariable.cs
  33. 97
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultAttribute.cs
  34. 41
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs
  35. 3
      ICSharpCode.NRefactory/Utils/LazyInit.cs
  36. 134
      ICSharpCode.NRefactory/Utils/MultiDictionary.cs
  37. 78
      NRefactory.sln

22
ICSharpCode.NRefactory.CSharp.AstVerifier/ICSharpCode.NRefactory.CSharp.AstVerifier.csproj

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -28,6 +28,26 @@ @@ -28,6 +28,26 @@
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net_4_5_Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net_4_5_Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>

21
ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj

@ -47,6 +47,27 @@ @@ -47,6 +47,27 @@
<DebugType>full</DebugType>
<DebugSymbols>True</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'net_4_5_Debug' ">
<OutputPath>..\ICSharpCode.NRefactory\bin\Debug\</OutputPath>
<Optimize>False</Optimize>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<DefineConstants>DEBUG;TRACE;FULL_AST;NET45</DefineConstants>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net_4_5_Debug|AnyCPU' ">
<DebugType>full</DebugType>
<DebugSymbols>True</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'net_4_5_Release' ">
<OutputPath>..\ICSharpCode.NRefactory\bin\Release\</OutputPath>
<Optimize>True</Optimize>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<DefineConstants>TRACE;FULL_AST;NET45</DefineConstants>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net_4_5_Release|AnyCPU' ">
<DebugType>PdbOnly</DebugType>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core">

1
ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs

@ -2172,6 +2172,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -2172,6 +2172,7 @@ namespace ICSharpCode.NRefactory.CSharp
WriteAttributes(indexerDeclaration.Attributes);
WriteModifiers(indexerDeclaration.ModifierTokens);
indexerDeclaration.ReturnType.AcceptVisitor(this);
Space();
WritePrivateImplementationType(indexerDeclaration.PrivateImplementationType);
WriteKeyword(IndexerDeclaration.ThisKeywordRole);
Space(policy.SpaceBeforeMethodDeclarationParentheses);

4
ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/GeneratePropertyAction.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
//
//
// GenerateProperty.cs
//
// Author:
@ -51,7 +51,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -51,7 +51,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
}
}
var field = initializer.Parent as FieldDeclaration;
if (field == null) {
if (field == null || field.HasModifier(Modifiers.Readonly) || field.HasModifier(Modifiers.Const)) {
yield break;
}
var resolveResult = context.Resolve(initializer) as MemberResolveResult;

2
ICSharpCode.NRefactory.CSharp/Resolver/CSharpAstResolver.cs

@ -275,7 +275,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -275,7 +275,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
return true;
}
return (node.NodeType == NodeType.Whitespace || node is ArraySpecifier || node is NamedArgumentExpression);
return (node.NodeType == NodeType.Whitespace || node is ArraySpecifier);
}
}
}

11
ICSharpCode.NRefactory.CSharp/Resolver/CSharpInvocationResolveResult.cs

@ -96,10 +96,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -96,10 +96,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
mappedTo = IsExpandedForm ? Math.Min(i, results.Length - 1) : i;
if (mappedTo >= 0 && mappedTo < results.Length) {
if (IsExpandedForm && mappedTo == results.Length - 1)
if (IsExpandedForm && mappedTo == results.Length - 1) {
paramsArguments.Add(Arguments[i]);
else
results[mappedTo] = Arguments[i];
} else {
var narr = Arguments[i] as NamedArgumentResolveResult;
if (narr != null)
results[mappedTo] = narr.Argument;
else
results[mappedTo] = Arguments[i];
}
}
}
if (IsExpandedForm)

2
ICSharpCode.NRefactory.CSharp/Resolver/CSharpResolver.cs

@ -1954,7 +1954,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1954,7 +1954,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
or.AddCandidate(invokeMethod);
return new CSharpInvocationResolveResult(
target, invokeMethod, //invokeMethod.ReturnType.Resolve(context),
or.GetArgumentsWithConversions(), or.BestCandidateErrors,
or.GetArgumentsWithConversionsAndNames(), or.BestCandidateErrors,
isExpandedForm: or.BestCandidateIsExpandedForm,
isDelegateInvocation: true,
argumentToParameterMap: or.GetArgumentToParameterMap());

5
ICSharpCode.NRefactory.CSharp/Resolver/Log.cs

@ -19,12 +19,7 @@ @@ -19,12 +19,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
namespace ICSharpCode.NRefactory.CSharp.Resolver
{

55
ICSharpCode.NRefactory.CSharp/Resolver/OverloadResolution.cs

@ -781,15 +781,35 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -781,15 +781,35 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return null;
}
/// <summary>
/// Returns the arguments for the method call in the order they were provided (not in the order of the parameters).
/// Arguments are wrapped in a <see cref="ConversionResolveResult"/> if an implicit conversion is being applied
/// to them when calling the method.
/// </summary>
public IList<ResolveResult> GetArgumentsWithConversions()
{
if (bestCandidate == null)
return arguments;
else
return GetArgumentsWithConversions(null);
return GetArgumentsWithConversions(null, null);
}
/// <summary>
/// Returns the arguments for the method call in the order they were provided (not in the order of the parameters).
/// Arguments are wrapped in a <see cref="ConversionResolveResult"/> if an implicit conversion is being applied
/// to them when calling the method.
/// For arguments where an explicit argument name was provided, the argument will
/// be wrapped in a <see cref="NamedArgumentResolveResult"/>.
/// </summary>
public IList<ResolveResult> GetArgumentsWithConversionsAndNames()
{
if (bestCandidate == null)
return arguments;
else
return GetArgumentsWithConversions(null, GetBestCandidateWithSubstitutedTypeArguments());
}
IList<ResolveResult> GetArgumentsWithConversions(ResolveResult targetResolveResult)
IList<ResolveResult> GetArgumentsWithConversions(ResolveResult targetResolveResult, IParameterizedMember bestCandidateForNamedArguments)
{
var conversions = this.ArgumentConversions;
ResolveResult[] args = new ResolveResult[arguments.Length];
@ -797,22 +817,27 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -797,22 +817,27 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
var argument = arguments[i];
if (this.IsExtensionMethodInvocation && i == 0 && targetResolveResult != null)
argument = targetResolveResult;
if (conversions[i] == Conversion.IdentityConversion) {
args[i] = argument;
} else {
int parameterIndex = bestCandidate.ArgumentToParameterMap[i];
IType parameterType;
if (parameterIndex >= 0) {
parameterType = bestCandidate.ParameterTypes[parameterIndex];
} else {
parameterType = SpecialType.UnknownType;
int parameterIndex = bestCandidate.ArgumentToParameterMap[i];
if (parameterIndex >= 0 && conversions[i] != Conversion.IdentityConversion) {
// Wrap argument in ConversionResolveResult
IType parameterType = bestCandidate.ParameterTypes[parameterIndex];
if (parameterType.Kind != TypeKind.Unknown) {
if (arguments[i].IsCompileTimeConstant && conversions[i] != Conversion.None) {
argument = new CSharpResolver(compilation).WithCheckForOverflow(CheckForOverflow).ResolveCast(parameterType, argument);
} else {
argument = new ConversionResolveResult(parameterType, argument, conversions[i], CheckForOverflow);
}
}
if (arguments[i].IsCompileTimeConstant && conversions[i] != Conversion.None) {
args[i] = new CSharpResolver(compilation).WithCheckForOverflow(CheckForOverflow).ResolveCast(parameterType, argument);
}
if (bestCandidateForNamedArguments != null && argumentNames[i] != null) {
// Wrap argument in NamedArgumentResolveResult
if (parameterIndex >= 0) {
argument = new NamedArgumentResolveResult(bestCandidateForNamedArguments.Parameters[parameterIndex], argument, bestCandidateForNamedArguments);
} else {
args[i] = new ConversionResolveResult(parameterType, argument, conversions[i], CheckForOverflow);
argument = new NamedArgumentResolveResult(argumentNames[i], argument);
}
}
args[i] = argument;
}
return args;
}
@ -857,7 +882,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -857,7 +882,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return new CSharpInvocationResolveResult(
this.IsExtensionMethodInvocation ? new TypeResolveResult(member.DeclaringType) : targetResolveResult,
member,
GetArgumentsWithConversions(targetResolveResult),
GetArgumentsWithConversions(targetResolveResult, member),
this.BestCandidateErrors,
this.IsExtensionMethodInvocation,
this.BestCandidateIsExpandedForm,

144
ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs

@ -27,7 +27,6 @@ using ICSharpCode.NRefactory.CSharp.TypeSystem; @@ -27,7 +27,6 @@ using ICSharpCode.NRefactory.CSharp.TypeSystem;
using ICSharpCode.NRefactory.Semantics;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using ICSharpCode.NRefactory.Utils;
namespace ICSharpCode.NRefactory.CSharp.Resolver
{
@ -393,10 +392,21 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -393,10 +392,21 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
}
void MarkUnknownNamedArguments(IEnumerable<Expression> arguments)
{
foreach (var nae in arguments.OfType<NamedArgumentExpression>()) {
StoreCurrentState(nae);
StoreResult(nae, new NamedArgumentResolveResult(nae.Name, resolveResultCache[nae.Expression]));
}
}
void ProcessConversionsInInvocation(Expression target, IEnumerable<Expression> arguments, CSharpInvocationResolveResult invocation)
{
if (invocation == null)
if (invocation == null) {
// we still need to handle the named arguments if invocation==null
MarkUnknownNamedArguments(arguments);
return;
}
int i = 0;
if (invocation.IsExtensionMethodInvocation) {
Debug.Assert(arguments.Count() + 1 == invocation.Arguments.Count);
@ -406,11 +416,17 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -406,11 +416,17 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
Debug.Assert(arguments.Count() == invocation.Arguments.Count);
}
foreach (Expression arg in arguments) {
ResolveResult argRR = invocation.Arguments[i++];
NamedArgumentExpression nae = arg as NamedArgumentExpression;
if (nae != null)
ProcessConversionResult(nae.Expression, invocation.Arguments[i++] as ConversionResolveResult);
else
ProcessConversionResult(arg, invocation.Arguments[i++] as ConversionResolveResult);
NamedArgumentResolveResult nrr = argRR as NamedArgumentResolveResult;
Debug.Assert((nae == null) == (nrr == null));
if (nae != null && nrr != null) {
StoreCurrentState(nae);
StoreResult(nae, nrr);
ProcessConversionResult(nae.Expression, nrr.Argument as ConversionResolveResult);
} else {
ProcessConversionResult(arg, argRR as ConversionResolveResult);
}
}
}
#endregion
@ -659,7 +675,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -659,7 +675,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (node.Role == Roles.Variable) {
IMember member;
if (parsedFile != null) {
member = GetMemberFromLocation(node.StartLocation);
member = GetMemberFromLocation(node);
} else {
string name = ((VariableInitializer)node).Name;
member = AbstractUnresolvedMember.Resolve(resolver.CurrentTypeResolveContext, entityType, name);
@ -676,11 +692,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -676,11 +692,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return voidResult;
}
IMember GetMemberFromLocation(TextLocation location)
IMember GetMemberFromLocation(AstNode node)
{
ITypeDefinition typeDef = resolver.CurrentTypeDefinition;
if (typeDef == null)
return null;
TextLocation location = TypeSystemConvertVisitor.GetStartLocationAfterAttributes(node);
return typeDef.GetMembers(
delegate (IUnresolvedMember m) {
if (m.ParsedFile != parsedFile)
@ -777,7 +794,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -777,7 +794,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
try {
IMember member;
if (parsedFile != null) {
member = GetMemberFromLocation(memberDeclaration.StartLocation);
member = GetMemberFromLocation(memberDeclaration);
} else {
// Re-discover the method:
EntityType entityType = memberDeclaration.EntityType;
@ -840,7 +857,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -840,7 +857,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
try {
IMember member;
if (parsedFile != null) {
member = GetMemberFromLocation(propertyOrIndexerDeclaration.StartLocation);
member = GetMemberFromLocation(propertyOrIndexerDeclaration);
} else {
// Re-discover the property:
string name = propertyOrIndexerDeclaration.Name;
@ -896,7 +913,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -896,7 +913,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
try {
IMember member;
if (parsedFile != null) {
member = GetMemberFromLocation(eventDeclaration.StartLocation);
member = GetMemberFromLocation(eventDeclaration);
} else {
string name = eventDeclaration.Name;
AstType explicitInterfaceAstType = eventDeclaration.PrivateImplementationType;
@ -1019,7 +1036,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1019,7 +1036,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
IMember member = null;
if (parsedFile != null) {
member = GetMemberFromLocation(enumMemberDeclaration.StartLocation);
member = GetMemberFromLocation(enumMemberDeclaration);
} else if (resolver.CurrentTypeDefinition != null) {
string name = enumMemberDeclaration.Name;
member = resolver.CurrentTypeDefinition.GetFields(f => f.Name == name, GetMemberOptions.IgnoreInheritedMembers).FirstOrDefault();
@ -1397,7 +1414,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1397,7 +1414,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ResolveResult IAstVisitor<ResolveResult>.VisitIndexerExpression(IndexerExpression indexerExpression)
{
if (resolverEnabled) {
if (resolverEnabled || NeedsResolvingDueToNamedArguments(indexerExpression)) {
Expression target = indexerExpression.Target;
ResolveResult targetResult = Resolve(target);
string[] argumentNames;
@ -1405,6 +1422,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1405,6 +1422,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ResolveResult rr = resolver.ResolveIndexer(targetResult, arguments, argumentNames);
ArrayAccessResolveResult aarr = rr as ArrayAccessResolveResult;
if (aarr != null) {
MarkUnknownNamedArguments(indexerExpression.Arguments);
ProcessConversionResults(indexerExpression.Arguments, aarr.Indexes);
} else {
ProcessConversionsInInvocation(target, indexerExpression.Arguments, rr as CSharpInvocationResolveResult);
@ -1436,8 +1454,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1436,8 +1454,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
// by calling GetArguments().
// This method gets called only when scanning, or when the named argument is used
// in an invalid context.
Scan(namedArgumentExpression.Expression);
return null;
if (resolverEnabled) {
return new NamedArgumentResolveResult(namedArgumentExpression.Name, Resolve(namedArgumentExpression.Expression));
} else {
Scan(namedArgumentExpression.Expression);
return null;
}
}
// NamedExpression is "identifier = Expression" in object initializers and attributes
@ -1476,48 +1498,44 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1476,48 +1498,44 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ResolveResult IAstVisitor<ResolveResult>.VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression)
{
if (resolverEnabled || !objectCreateExpression.Initializer.IsNull) {
var typeResolveResult = Resolve(objectCreateExpression.Type);
if (typeResolveResult.IsError) {
ScanChildren (objectCreateExpression);
return typeResolveResult;
}
IType type = typeResolveResult.Type;
var typeResolveResult = Resolve(objectCreateExpression.Type);
if (typeResolveResult.IsError) {
ScanChildren (objectCreateExpression);
return typeResolveResult;
}
IType type = typeResolveResult.Type;
List<ResolveResult> initializerStatements = null;
var initializer = objectCreateExpression.Initializer;
if (!initializer.IsNull) {
initializerStatements = new List<ResolveResult>();
HandleObjectInitializer(new InitializedObjectResolveResult(type), initializer, initializerStatements);
}
List<ResolveResult> initializerStatements = null;
var initializer = objectCreateExpression.Initializer;
if (!initializer.IsNull) {
initializerStatements = new List<ResolveResult>();
HandleObjectInitializer(new InitializedObjectResolveResult(type), initializer, initializerStatements);
}
string[] argumentNames;
ResolveResult[] arguments = GetArguments(objectCreateExpression.Arguments, out argumentNames);
ResolveResult rr = resolver.ResolveObjectCreation(type, arguments, argumentNames, false, initializerStatements);
if (arguments.Length == 1 && rr.Type.Kind == TypeKind.Delegate) {
// Apply conversion to argument if it directly wraps the argument
// (but not when creating a delegate from a delegate, as then there would be a MGRR for .Invoke in between)
// This is necessary for lambda type inference.
var crr = rr as ConversionResolveResult;
if (crr != null && crr.Input == arguments[0]) {
ProcessConversionResult(objectCreateExpression.Arguments.Single(), crr);
// wrap the result so that the delegate creation is not handled as a reference
// to the target method - otherwise FindReferencedEntities would produce two results for
// the same delegate creation.
return WrapResult(rr);
} else {
return rr;
}
string[] argumentNames;
ResolveResult[] arguments = GetArguments(objectCreateExpression.Arguments, out argumentNames);
ResolveResult rr = resolver.ResolveObjectCreation(type, arguments, argumentNames, false, initializerStatements);
if (arguments.Length == 1 && rr.Type.Kind == TypeKind.Delegate) {
MarkUnknownNamedArguments(objectCreateExpression.Arguments);
// Apply conversion to argument if it directly wraps the argument
// (but not when creating a delegate from a delegate, as then there would be a MGRR for .Invoke in between)
// This is necessary for lambda type inference.
var crr = rr as ConversionResolveResult;
if (crr != null && crr.Input == arguments[0]) {
ProcessConversionResult(objectCreateExpression.Arguments.Single(), crr);
// wrap the result so that the delegate creation is not handled as a reference
// to the target method - otherwise FindReferencedEntities would produce two results for
// the same delegate creation.
return WrapResult(rr);
} else {
// process conversions in all other cases
ProcessConversionsInInvocation(null, objectCreateExpression.Arguments, rr as CSharpInvocationResolveResult);
return rr;
}
} else {
ScanChildren(objectCreateExpression);
return null;
// process conversions in all other cases
ProcessConversionsInInvocation(null, objectCreateExpression.Arguments, rr as CSharpInvocationResolveResult);
return rr;
}
}
@ -1700,6 +1718,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1700,6 +1718,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return result;
}
/// <summary>
/// Gets and resolves the arguments; unpacking any NamedArgumentExpressions.
/// </summary>
/// <remarks>
/// Callers of GetArguments must also call either ProcessConversionsInInvocation or MarkUnknownNamedArguments
/// to ensure the named arguments get resolved.
/// Also, as named arguments get resolved by the parent node, the parent node must not scan
/// into the argument list without being resolved - see NeedsResolvingDueToNamedArguments().
/// </remarks>
ResolveResult[] GetArguments(IEnumerable<Expression> argumentExpressions, out string[] argumentNames)
{
argumentNames = null;
@ -1721,6 +1748,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1721,6 +1748,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return arguments;
}
bool NeedsResolvingDueToNamedArguments(Expression nodeWithArguments)
{
for (AstNode child = nodeWithArguments.FirstChild; child != null; child = child.NextSibling) {
if (child is NamedArgumentExpression)
return true;
}
return false;
}
static NameLookupMode GetNameLookupMode(Expression expr)
{
InvocationExpression ie = expr.Parent as InvocationExpression;
@ -1839,7 +1875,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1839,7 +1875,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
} else {
// Regular code path
if (resolverEnabled) {
if (resolverEnabled || NeedsResolvingDueToNamedArguments(invocationExpression)) {
ResolveResult target = Resolve(invocationExpression.Target);
return ResolveInvocationOnGivenTarget(target, invocationExpression);
} else {
@ -3778,10 +3814,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -3778,10 +3814,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#region Constructor Initializer
ResolveResult IAstVisitor<ResolveResult>.VisitConstructorInitializer(ConstructorInitializer constructorInitializer)
{
if (!resolverEnabled) {
ScanChildren(constructorInitializer);
return null;
}
ResolveResult target;
if (constructorInitializer.ConstructorInitializerType == ConstructorInitializerType.Base) {
target = resolver.ResolveBaseReference();

11
ICSharpCode.NRefactory.CSharp/TypeSystem/TypeSystemConvertVisitor.cs

@ -22,13 +22,10 @@ using System.Diagnostics; @@ -22,13 +22,10 @@ using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using ICSharpCode.NRefactory.CSharp.Analysis;
using ICSharpCode.NRefactory.CSharp.Resolver;
using ICSharpCode.NRefactory.CSharp.TypeSystem;
using ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using ICSharpCode.NRefactory.Utils;
namespace ICSharpCode.NRefactory.CSharp.TypeSystem
{
@ -99,12 +96,18 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -99,12 +96,18 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
{
if (node == null || node.IsNull)
return DomRegion.Empty;
else
return MakeRegion(GetStartLocationAfterAttributes(node), node.EndLocation);
}
internal static TextLocation GetStartLocationAfterAttributes(AstNode node)
{
AstNode child = node.FirstChild;
// Skip attributes and comments between attributes for the purpose of
// getting a declaration's region.
while (child != null && (child is AttributeSection || child.NodeType == NodeType.Whitespace))
child = child.NextSibling;
return MakeRegion((child ?? node).StartLocation, node.EndLocation);
return (child ?? node).StartLocation;
}
DomRegion MakeBraceRegion(AstNode node)

18
ICSharpCode.NRefactory.ConsistencyCheck/ICSharpCode.NRefactory.ConsistencyCheck.csproj

@ -38,6 +38,24 @@ @@ -38,6 +38,24 @@
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'net_4_5_Debug' ">
<OutputPath>bin\Debug\</OutputPath>
<DebugSymbols>true</DebugSymbols>
<DebugType>Full</DebugType>
<Optimize>False</Optimize>
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'net_4_5_Release' ">
<OutputPath>bin\Release\</OutputPath>
<DebugSymbols>False</DebugSymbols>
<DebugType>None</DebugType>
<Optimize>True</Optimize>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<DefineConstants>TRACE</DefineConstants>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Build" />
<Reference Include="System" />

30
ICSharpCode.NRefactory.Demo/ICSharpCode.NRefactory.Demo.csproj

@ -45,6 +45,36 @@ @@ -45,6 +45,36 @@
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'net_4_5_Debug' ">
<OutputPath>bin\Debug\</OutputPath>
<DebugSymbols>True</DebugSymbols>
<DebugType>Full</DebugType>
<Optimize>False</Optimize>
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net_4_5_Debug|x86' ">
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net_4_5_Debug|AnyCPU' ">
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'net_4_5_Release' ">
<OutputPath>bin\Release\</OutputPath>
<DebugSymbols>False</DebugSymbols>
<DebugType>None</DebugType>
<Optimize>True</Optimize>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<DefineConstants>TRACE</DefineConstants>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net_4_5_Release|x86' ">
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net_4_5_Release|AnyCPU' ">
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core">

22
ICSharpCode.NRefactory.GtkDemo/ICSharpCode.NRefactory.GtkDemo.csproj

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -28,6 +28,26 @@ @@ -28,6 +28,26 @@
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net_4_5_Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net_4_5_Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">

6
ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ContextActionTestBase.cs

@ -84,7 +84,11 @@ namespace ICSharpCode.NRefactory.CSharp.CodeActions @@ -84,7 +84,11 @@ namespace ICSharpCode.NRefactory.CSharp.CodeActions
protected static void TestWrongContext<T> (string input) where T : ICodeActionProvider, new ()
{
ICodeActionProvider action = new T ();
TestWrongContext (new T(), input);
}
protected static void TestWrongContext (ICodeActionProvider action, string input)
{
var context = TestRefactoringContext.Create (input);
bool isValid = action.GetActions (context).Any ();
if (!isValid)

28
ICSharpCode.NRefactory.Tests/CSharp/CodeActions/GeneratePropertyTests.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
//
//
// GeneratePropertyTests.cs
//
// Author:
@ -107,5 +107,31 @@ class TestClass @@ -107,5 +107,31 @@ class TestClass
int myField, myOtherField;
}");
}
[Test]
public void CannotGeneratePropertyForReadOnlyField()
{
TestWrongContext (
new GeneratePropertyAction (),
"using System;" + Environment.NewLine +
"class TestClass" + Environment.NewLine +
"{" + Environment.NewLine +
" readonly int $myField;" + Environment.NewLine +
"}"
);
}
[Test]
public void CannotGeneratePropertyForConst()
{
TestWrongContext (
new GeneratePropertyAction (),
"using System;" + Environment.NewLine +
"class TestClass" + Environment.NewLine +
"{" + Environment.NewLine +
" const int $myField = 0;" + Environment.NewLine +
"}"
);
}
}
}

19
ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/PreprocessorDirectiveTests.cs

@ -245,5 +245,24 @@ class B { } @@ -245,5 +245,24 @@ class B { }
Assert.AreEqual(PreProcessorDirectiveType.Elif, bbb.Type);
Assert.AreEqual("BBB", bbb.Argument);
}
[Test]
[Ignore("parser bug (BBB is missing)")]
public void ConditionalSymbolTest()
{
const string program = @"// Test
#if AAA
#undef AAA
#define CCC
#else
#define DDD
#endif
class C {}";
CSharpParser parser = new CSharpParser();
parser.CompilerSettings.ConditionalSymbols.Add("AAA");
parser.CompilerSettings.ConditionalSymbols.Add("BBB");
var cu = parser.Parse(program, "elif.cs");
Assert.AreEqual(new[] { "BBB", "CCC" }, cu.ConditionalSymbols);
}
}
}

70
ICSharpCode.NRefactory.Tests/CSharp/Resolver/InvocationTests.cs

@ -539,5 +539,75 @@ class D : B { @@ -539,5 +539,75 @@ class D : B {
Assert.IsFalse(rr.IsError);
Assert.IsFalse(rr.IsVirtualCall);
}
[Test]
public void NamedArgument()
{
string program = @"
class Test {
public void F(int x) {}
public void Test() {
F($x: 0$);
}
}";
var narr = Resolve<NamedArgumentResolveResult>(program);
Assert.IsInstanceOf<ConstantResolveResult>(narr.Argument);
Assert.AreEqual("x", narr.ParameterName);
Assert.AreEqual("Test.F", narr.Member.FullName);
Assert.AreSame(narr.Member.Parameters.Single(), narr.Parameter);
}
[Test]
public void NamedArgumentInInvocation()
{
string program = @"
class Test {
public void F(int x) {}
public void Test() {
$F(x: 0)$;
}
}";
var rr = Resolve<CSharpInvocationResolveResult>(program);
Assert.IsInstanceOf<NamedArgumentResolveResult>(rr.Arguments.Single());
var narr = (NamedArgumentResolveResult)rr.Arguments.Single();
Assert.IsInstanceOf<ConstantResolveResult>(narr.Argument);
Assert.AreEqual("x", narr.ParameterName);
Assert.AreEqual("Test.F", narr.Member.FullName);
Assert.AreSame(narr.Member.Parameters.Single(), narr.Parameter);
// but GetArgumentsForCall() should directly return the constant:
Assert.IsInstanceOf<ConstantResolveResult>(rr.GetArgumentsForCall().Single());
}
[Test]
public void UnknownNamedArgument()
{
string program = @"
class Test {
public void F(int x) {}
public void Test() {
F($y: 0$);
}
}";
var narr = Resolve<NamedArgumentResolveResult>(program);
Assert.IsInstanceOf<ConstantResolveResult>(narr.Argument);
Assert.AreEqual("y", narr.ParameterName);
Assert.IsNull(narr.Parameter);
}
[Test]
public void NamedArgumentInMissingMethod()
{
string program = @"
class Test {
public void Test() {
Missing($x: 0$);
}
}";
var narr = Resolve<NamedArgumentResolveResult>(program);
Assert.IsInstanceOf<ConstantResolveResult>(narr.Argument);
Assert.AreEqual("x", narr.ParameterName);
Assert.IsNull(narr.Parameter);
}
}
}

41
ICSharpCode.NRefactory.Tests/CSharp/Resolver/MethodTests.cs

@ -1,14 +1,45 @@ @@ -1,14 +1,45 @@
using System;
using System.Collections.Generic;
// Copyright (c) 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.Text;
using ICSharpCode.NRefactory.Semantics;
using ICSharpCode.NRefactory.TypeSystem;
using NUnit.Framework;
namespace ICSharpCode.NRefactory.CSharp.Resolver {
namespace ICSharpCode.NRefactory.CSharp.Resolver
{
[TestFixture]
public class MethodTests : ResolverTestBase {
public class MethodTests : ResolverTestBase
{
[Test]
public void MethodDeclarationWithAttribute()
{
string code = @"using System;
class TestClass {
$[Obsolete(""test"")]
public void M() {
}$
}";
var mrr = Resolve<MemberResolveResult>(code);
Assert.AreEqual("TestClass.M", mrr.Member.FullName);
}
[Test]
public void ParameterIdentityInNormalMethod()
{

42
ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj

@ -65,6 +65,48 @@ @@ -65,6 +65,48 @@
<PropertyGroup Condition=" '$(Platform)' == 'x86' ">
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'net_4_5_Debug' ">
<OutputPath>bin\Debug\</OutputPath>
<DebugSymbols>true</DebugSymbols>
<DebugType>Full</DebugType>
<Optimize>False</Optimize>
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
<DefineConstants>DEBUG;TRACE;NET45</DefineConstants>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net_4_5_Debug|AnyCPU' ">
<OutputPath>..\ICSharpCode.NRefactory\bin\Debug\</OutputPath>
<RegisterForComInterop>False</RegisterForComInterop>
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
<BaseAddress>4194304</BaseAddress>
<FileAlignment>4096</FileAlignment>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net_4_5_Debug|x86' ">
<OutputPath>..\ICSharpCode.NRefactory\bin\Debug\</OutputPath>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'net_4_5_Release' ">
<OutputPath>bin\Release\</OutputPath>
<DebugSymbols>False</DebugSymbols>
<DebugType>None</DebugType>
<Optimize>True</Optimize>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<DefineConstants>TRACE;NET45</DefineConstants>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net_4_5_Release|AnyCPU' ">
<OutputPath>..\ICSharpCode.NRefactory\bin\Release\</OutputPath>
<RegisterForComInterop>False</RegisterForComInterop>
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
<BaseAddress>4194304</BaseAddress>
<FileAlignment>4096</FileAlignment>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net_4_5_Release|x86' ">
<OutputPath>..\ICSharpCode.NRefactory\bin\Release\</OutputPath>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.CSharp" />
<Reference Include="System" />

22
ICSharpCode.NRefactory.Xml/ICSharpCode.NRefactory.Xml.csproj

@ -47,6 +47,28 @@ @@ -47,6 +47,28 @@
<DebugType>PdbOnly</DebugType>
<DebugSymbols>false</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'net_4_5_Debug' ">
<OutputPath>..\ICSharpCode.NRefactory\bin\Debug\</OutputPath>
<Optimize>False</Optimize>
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
<DefineConstants>DEBUG;TRACE;NET45</DefineConstants>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net_4_5_Debug|AnyCPU' ">
<DebugType>full</DebugType>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'net_4_5_Release' ">
<OutputPath>..\ICSharpCode.NRefactory\bin\Release\</OutputPath>
<Optimize>True</Optimize>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<DefineConstants>TRACE;NET45</DefineConstants>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net_4_5_Release|AnyCPU' ">
<DebugType>PdbOnly</DebugType>
<DebugSymbols>false</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core">

25
ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj

@ -50,6 +50,28 @@ @@ -50,6 +50,28 @@
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'net_4_5_Debug' ">
<OutputPath>bin\Debug\</OutputPath>
<Optimize>False</Optimize>
<DefineConstants>DEBUG;TRACE;NET45</DefineConstants>
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
<StartAction>Project</StartAction>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net_4_5_Debug|AnyCPU' ">
<DebugType>full</DebugType>
<DebugSymbols>True</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'net_4_5_Release' ">
<OutputPath>bin\Release\</OutputPath>
<Optimize>True</Optimize>
<DefineConstants>TRACE;NET45</DefineConstants>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net_4_5_Release|AnyCPU' ">
<DebugType>none</DebugType>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
@ -98,6 +120,7 @@ @@ -98,6 +120,7 @@
<Compile Include="Semantics\InvocationResolveResult.cs" />
<Compile Include="Semantics\LocalResolveResult.cs" />
<Compile Include="Semantics\MemberResolveResult.cs" />
<Compile Include="Semantics\NamedArgumentResolveResult.cs" />
<Compile Include="Semantics\NamespaceResolveResult.cs" />
<Compile Include="Semantics\OperatorResolveResult.cs" />
<Compile Include="Semantics\ResolveResult.cs" />
@ -138,6 +161,7 @@ @@ -138,6 +161,7 @@
<Compile Include="TypeSystem\Implementation\AccessorOwnerMemberReference.cs" />
<Compile Include="TypeSystem\Implementation\BaseTypeCollector.cs" />
<Compile Include="TypeSystem\Implementation\DefaultAssemblyReference.cs" />
<Compile Include="TypeSystem\Implementation\DefaultAttribute.cs" />
<Compile Include="TypeSystem\Implementation\DefaultMemberReference.cs" />
<Compile Include="TypeSystem\Implementation\DefaultParameter.cs" />
<Compile Include="TypeSystem\Implementation\DefaultResolvedEvent.cs" />
@ -219,6 +243,7 @@ @@ -219,6 +243,7 @@
<Compile Include="Utils\ImmutableStack.cs" />
<Compile Include="Utils\KeyComparer.cs" />
<Compile Include="Utils\LazyInit.cs" />
<Compile Include="Utils\MultiDictionary.cs" />
<Compile Include="Utils\Platform.cs" />
<Compile Include="Utils\ProjectedList.cs" />
<Compile Include="Utils\ReferenceComparer.cs" />

81
ICSharpCode.NRefactory/Semantics/NamedArgumentResolveResult.cs

@ -0,0 +1,81 @@ @@ -0,0 +1,81 @@
// Copyright (c) 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 ICSharpCode.NRefactory.TypeSystem;
namespace ICSharpCode.NRefactory.Semantics
{
/// <summary>
/// Represents a named argument.
/// </summary>
public class NamedArgumentResolveResult : ResolveResult
{
/// <summary>
/// Gets the member to which the parameter belongs.
/// This field can be null.
/// </summary>
public readonly IParameterizedMember Member;
/// <summary>
/// Gets the parameter.
/// This field can be null.
/// </summary>
public readonly IParameter Parameter;
/// <summary>
/// Gets the parameter name.
/// </summary>
public readonly string ParameterName;
/// <summary>
/// Gets the argument passed to the parameter.
/// </summary>
public readonly ResolveResult Argument;
public NamedArgumentResolveResult(IParameter parameter, ResolveResult argument, IParameterizedMember member = null)
: base(argument.Type)
{
if (parameter == null)
throw new ArgumentNullException("parameter");
if (argument == null)
throw new ArgumentNullException("argument");
this.Member = member;
this.Parameter = parameter;
this.ParameterName = parameter.Name;
this.Argument = argument;
}
public NamedArgumentResolveResult(string parameterName, ResolveResult argument)
: base(argument.Type)
{
if (parameterName == null)
throw new ArgumentNullException("parameterName");
if (argument == null)
throw new ArgumentNullException("argument");
this.ParameterName = parameterName;
this.Argument = argument;
}
public override IEnumerable<ResolveResult> GetChildResults()
{
return new [] { Argument };
}
}
}

54
ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs

@ -967,7 +967,16 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -967,7 +967,16 @@ namespace ICSharpCode.NRefactory.TypeSystem
return;
}
foreach (var ctorParameter in ctorParameterTypes.Resolve(context)) {
positionalArguments.Add(reader.ReadFixedArg(ctorParameter));
ResolveResult arg = reader.ReadFixedArg(ctorParameter);
positionalArguments.Add(arg);
if (arg.IsError) {
// After a decoding error, we must stop decoding the blob because
// we might have read too few bytes due to the error.
// Just fill up the remaining arguments with ErrorResolveResult:
while (positionalArguments.Count < ctorParameterTypes.Count)
positionalArguments.Add(ErrorResolveResult.UnknownError);
return;
}
}
ushort numNamed = reader.ReadUInt16();
for (int i = 0; i < numNamed; i++) {
@ -1131,6 +1140,9 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -1131,6 +1140,9 @@ namespace ICSharpCode.NRefactory.TypeSystem
ResolveResult[] elements = new ResolveResult[numElem];
for (int i = 0; i < elements.Length; i++) {
elements[i] = ReadElem(elementType);
// Stop decoding when encountering an error:
if (elements[i].IsError)
return ErrorResolveResult.UnknownError;
}
return new ArrayCreateResolveResult(argType, null, elements);
}
@ -1421,11 +1433,10 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -1421,11 +1433,10 @@ namespace ICSharpCode.NRefactory.TypeSystem
namedArgs.Add(namedArg);
}
attributes[i] = new ResolvedSecurityAttribute {
AttributeType = attributeType,
NamedArguments = namedArgs,
PositionalArguments = new ResolveResult[] { securityActionRR }
};
attributes[i] = new DefaultAttribute(
attributeType,
positionalArguments: new ResolveResult[] { securityActionRR },
namedArguments: namedArgs);
}
}
@ -1468,37 +1479,6 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -1468,37 +1479,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
return secDecl.Resolve(context.CurrentAssembly)[index];
}
}
sealed class ResolvedSecurityAttribute : IAttribute
{
public IType AttributeType { get; internal set; }
DomRegion IAttribute.Region {
get { return DomRegion.Empty; }
}
volatile IMethod constructor;
public IMethod Constructor {
get {
IMethod ctor = this.constructor;
if (ctor == null) {
foreach (IMethod candidate in this.AttributeType.GetConstructors(m => m.Parameters.Count == 1)) {
if (candidate.Parameters[0].Type.Equals(this.PositionalArguments[0].Type)) {
ctor = candidate;
break;
}
}
this.constructor = ctor;
}
return ctor;
}
}
public IList<ResolveResult> PositionalArguments { get; internal set; }
public IList<KeyValuePair<IMember, ResolveResult>> NamedArguments { get; internal set; }
}
#endregion
#endregion

46
ICSharpCode.NRefactory/TypeSystem/IAttribute.cs

@ -18,7 +18,6 @@ @@ -18,7 +18,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using ICSharpCode.NRefactory.Semantics;
@ -27,9 +26,6 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -27,9 +26,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// <summary>
/// Represents an unresolved attribute.
/// </summary>
#if WITH_CONTRACTS
[ContractClass(typeof(IUnresolvedAttributeContract))]
#endif
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1711:IdentifiersShouldNotHaveIncorrectSuffix")]
public interface IUnresolvedAttribute
{
@ -38,8 +34,6 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -38,8 +34,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// </summary>
DomRegion Region { get; }
//ITypeReference AttributeType { get; }
/// <summary>
/// Resolves the attribute.
/// </summary>
@ -49,9 +43,6 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -49,9 +43,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// <summary>
/// Represents an attribute.
/// </summary>
#if WITH_CONTRACTS
[ContractClass(typeof(IAttributeContract))]
#endif
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1711:IdentifiersShouldNotHaveIncorrectSuffix")]
public interface IAttribute
{
@ -81,41 +72,4 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -81,41 +72,4 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// </summary>
IList<KeyValuePair<IMember, ResolveResult>> NamedArguments { get; }
}
#if WITH_CONTRACTS
[ContractClassFor(typeof(IAttribute))]
abstract class IAttributeContract : IFreezableContract, IAttribute
{
DomRegion IAttribute.Region {
get { return DomRegion.Empty; }
}
ITypeReference IAttribute.AttributeType {
get {
Contract.Ensures(Contract.Result<ITypeReference>() != null);
return null;
}
}
IList<IConstantValue> IAttribute.GetPositionalArguments(ITypeResolveContext context)
{
Contract.Requires(context != null);
Contract.Ensures(Contract.Result<IList<IConstantValue>>() != null);
return null;
}
IList<KeyValuePair<string, IConstantValue>> IAttribute.GetNamedArguments(ITypeResolveContext context)
{
Contract.Requires(context != null);
Contract.Ensures(Contract.Result<IList<KeyValuePair<string, IConstantValue>>>() != null);
return null;
}
IMethod IAttribute.ResolveConstructor(ITypeResolveContext context)
{
Contract.Requires(context != null);
return null;
}
}
#endif
}

20
ICSharpCode.NRefactory/TypeSystem/IFreezable.cs

@ -17,13 +17,9 @@ @@ -17,13 +17,9 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Diagnostics.Contracts;
namespace ICSharpCode.NRefactory.TypeSystem
{
#if WITH_CONTRACTS
[ContractClass(typeof(IFreezableContract))]
#endif
public interface IFreezable
{
/// <summary>
@ -36,20 +32,4 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -36,20 +32,4 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// </summary>
void Freeze();
}
#if WITH_CONTRACTS
[ContractClassFor(typeof(IFreezable))]
abstract class IFreezableContract : IFreezable
{
bool IFreezable.IsFrozen {
get { return default(bool); }
}
void IFreezable.Freeze()
{
IFreezable self = this;
Contract.Ensures(self.IsFrozen);
}
}
#endif
}

22
ICSharpCode.NRefactory/TypeSystem/IInterningProvider.cs

@ -18,7 +18,6 @@ @@ -18,7 +18,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
namespace ICSharpCode.NRefactory.TypeSystem
{
@ -40,9 +39,6 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -40,9 +39,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// and which are used only within a single type definition. Then a persistent file format could be organized so
/// that shared objects are loaded only once, yet non-shared objects get loaded lazily together with the class.
/// </remarks>
#if WITH_CONTRACTS
[ContractClass(typeof(IInterningProviderContract))]
#endif
public interface IInterningProvider
{
/// <summary>
@ -55,22 +51,4 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -55,22 +51,4 @@ namespace ICSharpCode.NRefactory.TypeSystem
IList<T> InternList<T>(IList<T> list) where T : class;
}
#if WITH_CONTRACTS
[ContractClassFor(typeof(IInterningProvider))]
abstract class IInterningProviderContract : IInterningProvider
{
T IInterningProvider.Intern<T>(T obj)
{
Contract.Ensures((Contract.Result<T>() == null) == (obj == null));
return obj;
}
IList<T> IInterningProvider.InternList<T>(IList<T> list)
{
Contract.Ensures((Contract.Result<IList<T>>() == null) == (list == null));
return list;
}
}
#endif
}

26
ICSharpCode.NRefactory/TypeSystem/ISupportsInterning.cs

@ -17,8 +17,6 @@ @@ -17,8 +17,6 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
namespace ICSharpCode.NRefactory.TypeSystem
{
@ -26,9 +24,6 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -26,9 +24,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// Interface for TypeSystem objects that support interning.
/// See <see cref="IInterningProvider"/> for more information.
/// </summary>
#if WITH_CONTRACTS
[ContractClass(typeof(ISupportsInterningContract))]
#endif
public interface ISupportsInterning
{
/// <summary>
@ -46,25 +41,4 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -46,25 +41,4 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// </summary>
bool EqualsForInterning(ISupportsInterning other);
}
#if WITH_CONTRACTS
[ContractClassFor(typeof(ISupportsInterning))]
abstract class ISupportsInterningContract : ISupportsInterning
{
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
Contract.Requires(provider != null);
}
int ISupportsInterning.GetHashCodeForInterning()
{
return 0;
}
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
{
return false;
}
}
#endif
}

1
ICSharpCode.NRefactory/TypeSystem/IType.cs

@ -18,7 +18,6 @@ @@ -18,7 +18,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
namespace ICSharpCode.NRefactory.TypeSystem
{

20
ICSharpCode.NRefactory/TypeSystem/ITypeDefinition.cs

@ -130,5 +130,25 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -130,5 +130,25 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// </summary>
/// <remarks>This property is used to speed up the search for extension methods.</remarks>
bool HasExtensionMethods { get; }
/// <summary>
/// Determines how this type is implementing the specified interface member.
/// </summary>
/// <returns>
/// The method on this type that implements the interface member;
/// or null if the type does not implement the interface.
/// </returns>
IMember GetInterfaceImplementation(IMember interfaceMember);
/// <summary>
/// Determines how this type is implementing the specified interface members.
/// </summary>
/// <returns>
/// For each interface member, this method returns the class member
/// that implements the interface member.
/// For interface members that are missing an implementation, the
/// result collection will contain a null element.
/// </returns>
IList<IMember> GetInterfaceImplementation(IList<IMember> interfaceMembers);
}
}

18
ICSharpCode.NRefactory/TypeSystem/ITypeReference.cs

@ -17,8 +17,6 @@ @@ -17,8 +17,6 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
namespace ICSharpCode.NRefactory.TypeSystem
{
@ -26,9 +24,6 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -26,9 +24,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// Represents a reference to a type.
/// Must be resolved before it can be used as type.
/// </summary>
#if WITH_CONTRACTS
[ContractClass(typeof(ITypeReferenceContract))]
#endif
public interface ITypeReference
{
// Keep this interface simple: I decided against having GetMethods/GetEvents etc. here,
@ -81,17 +76,4 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -81,17 +76,4 @@ namespace ICSharpCode.NRefactory.TypeSystem
ITypeResolveContext WithCurrentTypeDefinition(ITypeDefinition typeDefinition);
ITypeResolveContext WithCurrentMember(IMember member);
}
#if WITH_CONTRACTS
[ContractClassFor(typeof(ITypeReference))]
abstract class ITypeReferenceContract : ITypeReference
{
IType ITypeReference.Resolve(ITypeResolveContext context)
{
Contract.Requires(context != null);
Contract.Ensures(Contract.Result<IType>() != null);
return null;
}
}
#endif
}

36
ICSharpCode.NRefactory/TypeSystem/IVariable.cs

@ -17,16 +17,12 @@ @@ -17,16 +17,12 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Diagnostics.Contracts;
namespace ICSharpCode.NRefactory.TypeSystem
{
/// <summary>
/// Represents a variable (name/type pair).
/// </summary>
#if WITH_CONTRACTS
[ContractClass(typeof(IVariableContract))]
#endif
public interface IVariable
{
/// <summary>
@ -55,36 +51,4 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -55,36 +51,4 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// </summary>
object ConstantValue { get; }
}
#if WITH_CONTRACTS
[ContractClassFor(typeof(IVariable))]
abstract class IVariableContract : IVariable
{
string IVariable.Name {
get {
Contract.Ensures(Contract.Result<string>() != null);
return null;
}
}
ITypeReference IVariable.Type {
get {
Contract.Ensures(Contract.Result<ITypeReference>() != null);
return null;
}
}
bool IVariable.IsConst {
get {
IVariable @this = this;
Contract.Ensures(Contract.Result<bool>() == (@this.ConstantValue != null));
return false;
}
}
object IVariable.ConstantValue {
get { return null; }
}
}
#endif
}

97
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultAttribute.cs

@ -0,0 +1,97 @@ @@ -0,0 +1,97 @@
// Copyright (c) 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.Linq;
using ICSharpCode.NRefactory.Semantics;
namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{
/// <summary>
/// IAttribute implementation for already-resolved attributes.
/// </summary>
public class DefaultAttribute : IAttribute
{
readonly IType attributeType;
readonly IList<ResolveResult> positionalArguments;
readonly IList<KeyValuePair<IMember, ResolveResult>> namedArguments;
readonly DomRegion region;
volatile IMethod constructor;
public DefaultAttribute(IType attributeType, IList<ResolveResult> positionalArguments = null,
IList<KeyValuePair<IMember, ResolveResult>> namedArguments = null,
DomRegion region = default(DomRegion))
{
if (attributeType == null)
throw new ArgumentNullException("attributeType");
this.attributeType = attributeType;
this.positionalArguments = positionalArguments ?? EmptyList<ResolveResult>.Instance;
this.namedArguments = namedArguments ?? EmptyList<KeyValuePair<IMember, ResolveResult>>.Instance;
this.region = region;
}
public DefaultAttribute(IMethod constructor, IList<ResolveResult> positionalArguments = null,
IList<KeyValuePair<IMember, ResolveResult>> namedArguments = null,
DomRegion region = default(DomRegion))
{
if (constructor == null)
throw new ArgumentNullException("constructor");
this.constructor = constructor;
this.attributeType = constructor.DeclaringType;
this.positionalArguments = positionalArguments ?? EmptyList<ResolveResult>.Instance;
this.namedArguments = namedArguments ?? EmptyList<KeyValuePair<IMember, ResolveResult>>.Instance;
this.region = region;
if (this.positionalArguments.Count != constructor.Parameters.Count) {
throw new ArgumentException("Positional argument count must match the constructor's parameter count");
}
}
public IType AttributeType {
get { return attributeType; }
}
public DomRegion Region {
get { return region; }
}
public IMethod Constructor {
get {
IMethod ctor = this.constructor;
if (ctor == null) {
foreach (IMethod candidate in this.AttributeType.GetConstructors(m => m.Parameters.Count == positionalArguments.Count)) {
if (candidate.Parameters.Select(p => p.Type).SequenceEqual(this.PositionalArguments.Select(a => a.Type))) {
ctor = candidate;
break;
}
}
this.constructor = ctor;
}
return ctor;
}
}
public IList<ResolveResult> PositionalArguments {
get { return positionalArguments; }
}
public IList<KeyValuePair<IMember, ResolveResult>> NamedArguments {
get { return namedArguments; }
}
}
}

41
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs

@ -18,7 +18,6 @@ @@ -18,7 +18,6 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using ICSharpCode.NRefactory.Documentation;
using ICSharpCode.NRefactory.Utils;
@ -861,6 +860,46 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -861,6 +860,46 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
}
#endregion
#region GetInterfaceImplementation
public IMember GetInterfaceImplementation(IMember interfaceMember)
{
return GetInterfaceImplementation(new[] { interfaceMember })[0];
}
public IList<IMember> GetInterfaceImplementation(IList<IMember> interfaceMembers)
{
// TODO: review the subtle rules for interface reimplementation,
// write tests and fix this method.
// Also virtual/override is going to be tricky -
// I think we'll need to consider the 'virtual' method first for
// reimplemenatation purposes, but then actually return the 'override'
// (as that's the method that ends up getting called)
interfaceMembers = interfaceMembers.ToList(); // avoid evaluating more than once
var result = new IMember[interfaceMembers.Count];
var signatureToIndexDict = new MultiDictionary<IMember, int>(SignatureComparer.Ordinal);
for (int i = 0; i < interfaceMembers.Count; i++) {
signatureToIndexDict.Add(interfaceMembers[i], i);
}
foreach (var member in GetMembers(m => !m.IsExplicitInterfaceImplementation)) {
foreach (int interfaceMemberIndex in signatureToIndexDict[member]) {
result[interfaceMemberIndex] = member;
}
}
foreach (var explicitImpl in GetMembers(m => m.IsExplicitInterfaceImplementation)) {
foreach (var interfaceMember in explicitImpl.ImplementedInterfaceMembers) {
foreach (int potentialMatchingIndex in signatureToIndexDict[interfaceMember]) {
if (interfaceMember.Equals(interfaceMembers[potentialMatchingIndex])) {
result[potentialMatchingIndex] = explicitImpl;
}
}
}
}
return result;
}
#endregion
public bool Equals(IType other)
{
return this == other;

3
ICSharpCode.NRefactory/Utils/LazyInit.cs

@ -17,10 +17,7 @@ @@ -17,10 +17,7 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using ICSharpCode.NRefactory.TypeSystem;
namespace ICSharpCode.NRefactory.Utils
{

134
ICSharpCode.NRefactory/Utils/MultiDictionary.cs

@ -0,0 +1,134 @@ @@ -0,0 +1,134 @@
// Copyright (c) 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.Linq;
namespace ICSharpCode.NRefactory.Utils
{
/// <summary>
/// A dictionary that allows multiple pairs with the same key.
/// </summary>
public class MultiDictionary<TKey, TValue> : ILookup<TKey, TValue>
{
readonly Dictionary<TKey, List<TValue>> dict;
public MultiDictionary()
{
dict = new Dictionary<TKey, List<TValue>>();
}
public MultiDictionary(IEqualityComparer<TKey> comparer)
{
dict = new Dictionary<TKey, List<TValue>>(comparer);
}
public void Add(TKey key, TValue value)
{
List<TValue> valueList;
if (!dict.TryGetValue(key, out valueList)) {
valueList = new List<TValue>();
dict.Add(key, valueList);
}
valueList.Add(value);
}
public bool Remove(TKey key, TValue value)
{
List<TValue> valueList;
if (dict.TryGetValue(key, out valueList)) {
if (valueList.Remove(value)) {
if (valueList.Count == 0)
dict.Remove(key);
return true;
}
}
return false;
}
public void Clear()
{
dict.Clear();
}
#if NET45
public IReadOnlyList<TValue> this[TKey key] {
#else
public IList<TValue> this[TKey key] {
#endif
get {
List<TValue> list;
if (dict.TryGetValue(key, out list))
return list;
else
return EmptyList<TValue>.Instance;
}
}
public int Count {
get { return dict.Count; }
}
IEnumerable<TValue> ILookup<TKey, TValue>.this[TKey key] {
get { return this[key]; }
}
bool ILookup<TKey, TValue>.Contains(TKey key)
{
return dict.ContainsKey(key);
}
public IEnumerator<IGrouping<TKey, TValue>> GetEnumerator()
{
foreach (var pair in dict)
yield return new Grouping(pair.Key, pair.Value);
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
sealed class Grouping : IGrouping<TKey, TValue>
{
readonly TKey key;
readonly List<TValue> values;
public Grouping(TKey key, List<TValue> values)
{
this.key = key;
this.values = values;
}
public TKey Key {
get { return key; }
}
public IEnumerator<TValue> GetEnumerator()
{
return values.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return values.GetEnumerator();
}
}
}
}

78
NRefactory.sln

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
# SharpDevelop 4.2.0.8783
# SharpDevelop 4.3
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{DC98210E-1646-483B-819A-2BB8272461E4}"
ProjectSection(SolutionItems) = preProject
Packages\ICSharpCode.NRefactory.nuspec = Packages\ICSharpCode.NRefactory.nuspec
@ -34,6 +34,10 @@ Global @@ -34,6 +34,10 @@ Global
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x86 = Release|x86
net_4_5_Debug|Any CPU = net_4_5_Debug|Any CPU
net_4_5_Debug|x86 = net_4_5_Debug|x86
net_4_5_Release|Any CPU = net_4_5_Release|Any CPU
net_4_5_Release|x86 = net_4_5_Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
@ -108,6 +112,78 @@ Global @@ -108,6 +112,78 @@ Global
{9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.Release|x86.Build.0 = Release|x86
{9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.Release|x86.ActiveCfg = Release|x86
{9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.net_4_5_Debug|Any CPU.Build.0 = net_4_5_Debug|Any CPU
{9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.net_4_5_Debug|Any CPU.ActiveCfg = net_4_5_Debug|Any CPU
{961DADFA-7CE6-429F-BC22-47630D6DB826}.net_4_5_Debug|Any CPU.Build.0 = net_4_5_Debug|Any CPU
{961DADFA-7CE6-429F-BC22-47630D6DB826}.net_4_5_Debug|Any CPU.ActiveCfg = net_4_5_Debug|Any CPU
{DC393B66-92ED-4CAD-AB25-CFEF23F3D7C6}.net_4_5_Debug|Any CPU.Build.0 = net_4_5_Debug|Any CPU
{DC393B66-92ED-4CAD-AB25-CFEF23F3D7C6}.net_4_5_Debug|Any CPU.ActiveCfg = net_4_5_Debug|Any CPU
{D81206EF-3DCA-4A30-897B-E262A2AD9EE3}.net_4_5_Debug|Any CPU.Build.0 = net_4_5_Debug|Any CPU
{D81206EF-3DCA-4A30-897B-E262A2AD9EE3}.net_4_5_Debug|Any CPU.ActiveCfg = net_4_5_Debug|Any CPU
{A7EEF7F8-238F-459D-95A9-96467539641D}.net_4_5_Debug|Any CPU.Build.0 = net_4_5_Debug|Any CPU
{A7EEF7F8-238F-459D-95A9-96467539641D}.net_4_5_Debug|Any CPU.ActiveCfg = net_4_5_Debug|Any CPU
{53DCA265-3C3C-42F9-B647-F72BA678122B}.net_4_5_Debug|Any CPU.Build.0 = net_4_5_Debug|Any CPU
{53DCA265-3C3C-42F9-B647-F72BA678122B}.net_4_5_Debug|Any CPU.ActiveCfg = net_4_5_Debug|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.net_4_5_Debug|Any CPU.Build.0 = winphone_Release|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.net_4_5_Debug|Any CPU.ActiveCfg = net_4_0_Debug|Any CPU
{63D3B27A-D966-4902-90B3-30290E1692F1}.net_4_5_Debug|Any CPU.Build.0 = net_4_5_Debug|Any CPU
{63D3B27A-D966-4902-90B3-30290E1692F1}.net_4_5_Debug|Any CPU.ActiveCfg = net_4_5_Debug|Any CPU
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.net_4_5_Debug|Any CPU.Build.0 = net_4_5_Debug|Any CPU
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.net_4_5_Debug|Any CPU.ActiveCfg = net_4_5_Debug|Any CPU
{9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.net_4_5_Debug|x86.Build.0 = net_4_5_Debug|x86
{9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.net_4_5_Debug|x86.ActiveCfg = net_4_5_Debug|x86
{961DADFA-7CE6-429F-BC22-47630D6DB826}.net_4_5_Debug|x86.Build.0 = net_4_5_Debug|Any CPU
{961DADFA-7CE6-429F-BC22-47630D6DB826}.net_4_5_Debug|x86.ActiveCfg = net_4_5_Debug|Any CPU
{DC393B66-92ED-4CAD-AB25-CFEF23F3D7C6}.net_4_5_Debug|x86.Build.0 = net_4_5_Debug|Any CPU
{DC393B66-92ED-4CAD-AB25-CFEF23F3D7C6}.net_4_5_Debug|x86.ActiveCfg = net_4_5_Debug|Any CPU
{D81206EF-3DCA-4A30-897B-E262A2AD9EE3}.net_4_5_Debug|x86.Build.0 = net_4_5_Debug|x86
{D81206EF-3DCA-4A30-897B-E262A2AD9EE3}.net_4_5_Debug|x86.ActiveCfg = net_4_5_Debug|x86
{A7EEF7F8-238F-459D-95A9-96467539641D}.net_4_5_Debug|x86.Build.0 = net_4_5_Debug|Any CPU
{A7EEF7F8-238F-459D-95A9-96467539641D}.net_4_5_Debug|x86.ActiveCfg = net_4_5_Debug|Any CPU
{53DCA265-3C3C-42F9-B647-F72BA678122B}.net_4_5_Debug|x86.Build.0 = net_4_5_Debug|Any CPU
{53DCA265-3C3C-42F9-B647-F72BA678122B}.net_4_5_Debug|x86.ActiveCfg = net_4_5_Debug|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.net_4_5_Debug|x86.Build.0 = winphone_Release|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.net_4_5_Debug|x86.ActiveCfg = net_4_0_Debug|Any CPU
{63D3B27A-D966-4902-90B3-30290E1692F1}.net_4_5_Debug|x86.Build.0 = net_4_5_Debug|x86
{63D3B27A-D966-4902-90B3-30290E1692F1}.net_4_5_Debug|x86.ActiveCfg = net_4_5_Debug|x86
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.net_4_5_Debug|x86.Build.0 = net_4_5_Debug|Any CPU
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.net_4_5_Debug|x86.ActiveCfg = net_4_5_Debug|Any CPU
{9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.net_4_5_Release|Any CPU.Build.0 = net_4_5_Release|Any CPU
{9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.net_4_5_Release|Any CPU.ActiveCfg = net_4_5_Release|Any CPU
{961DADFA-7CE6-429F-BC22-47630D6DB826}.net_4_5_Release|Any CPU.Build.0 = net_4_5_Release|Any CPU
{961DADFA-7CE6-429F-BC22-47630D6DB826}.net_4_5_Release|Any CPU.ActiveCfg = net_4_5_Release|Any CPU
{DC393B66-92ED-4CAD-AB25-CFEF23F3D7C6}.net_4_5_Release|Any CPU.Build.0 = net_4_5_Release|Any CPU
{DC393B66-92ED-4CAD-AB25-CFEF23F3D7C6}.net_4_5_Release|Any CPU.ActiveCfg = net_4_5_Release|Any CPU
{D81206EF-3DCA-4A30-897B-E262A2AD9EE3}.net_4_5_Release|Any CPU.Build.0 = net_4_5_Release|Any CPU
{D81206EF-3DCA-4A30-897B-E262A2AD9EE3}.net_4_5_Release|Any CPU.ActiveCfg = net_4_5_Release|Any CPU
{A7EEF7F8-238F-459D-95A9-96467539641D}.net_4_5_Release|Any CPU.Build.0 = net_4_5_Release|Any CPU
{A7EEF7F8-238F-459D-95A9-96467539641D}.net_4_5_Release|Any CPU.ActiveCfg = net_4_5_Release|Any CPU
{53DCA265-3C3C-42F9-B647-F72BA678122B}.net_4_5_Release|Any CPU.Build.0 = net_4_5_Release|Any CPU
{53DCA265-3C3C-42F9-B647-F72BA678122B}.net_4_5_Release|Any CPU.ActiveCfg = net_4_5_Release|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.net_4_5_Release|Any CPU.Build.0 = winphone_Release|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.net_4_5_Release|Any CPU.ActiveCfg = net_4_0_Release|Any CPU
{63D3B27A-D966-4902-90B3-30290E1692F1}.net_4_5_Release|Any CPU.Build.0 = net_4_5_Release|Any CPU
{63D3B27A-D966-4902-90B3-30290E1692F1}.net_4_5_Release|Any CPU.ActiveCfg = net_4_5_Release|Any CPU
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.net_4_5_Release|Any CPU.Build.0 = net_4_5_Release|Any CPU
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.net_4_5_Release|Any CPU.ActiveCfg = net_4_5_Release|Any CPU
{9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.net_4_5_Release|x86.Build.0 = net_4_5_Release|x86
{9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.net_4_5_Release|x86.ActiveCfg = net_4_5_Release|x86
{961DADFA-7CE6-429F-BC22-47630D6DB826}.net_4_5_Release|x86.Build.0 = net_4_5_Release|Any CPU
{961DADFA-7CE6-429F-BC22-47630D6DB826}.net_4_5_Release|x86.ActiveCfg = net_4_5_Release|Any CPU
{DC393B66-92ED-4CAD-AB25-CFEF23F3D7C6}.net_4_5_Release|x86.Build.0 = net_4_5_Release|Any CPU
{DC393B66-92ED-4CAD-AB25-CFEF23F3D7C6}.net_4_5_Release|x86.ActiveCfg = net_4_5_Release|Any CPU
{D81206EF-3DCA-4A30-897B-E262A2AD9EE3}.net_4_5_Release|x86.Build.0 = net_4_5_Release|x86
{D81206EF-3DCA-4A30-897B-E262A2AD9EE3}.net_4_5_Release|x86.ActiveCfg = net_4_5_Release|x86
{A7EEF7F8-238F-459D-95A9-96467539641D}.net_4_5_Release|x86.Build.0 = net_4_5_Release|Any CPU
{A7EEF7F8-238F-459D-95A9-96467539641D}.net_4_5_Release|x86.ActiveCfg = net_4_5_Release|Any CPU
{53DCA265-3C3C-42F9-B647-F72BA678122B}.net_4_5_Release|x86.Build.0 = net_4_5_Release|Any CPU
{53DCA265-3C3C-42F9-B647-F72BA678122B}.net_4_5_Release|x86.ActiveCfg = net_4_5_Release|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.net_4_5_Release|x86.Build.0 = winphone_Release|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.net_4_5_Release|x86.ActiveCfg = net_4_0_Release|Any CPU
{63D3B27A-D966-4902-90B3-30290E1692F1}.net_4_5_Release|x86.Build.0 = net_4_5_Release|x86
{63D3B27A-D966-4902-90B3-30290E1692F1}.net_4_5_Release|x86.ActiveCfg = net_4_5_Release|x86
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.net_4_5_Release|x86.Build.0 = net_4_5_Release|Any CPU
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.net_4_5_Release|x86.ActiveCfg = net_4_5_Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

Loading…
Cancel
Save