Browse Source

Implemented resolver for LINQ queries.

newNRvisualizers
Daniel Grunwald 14 years ago
parent
commit
3fdf0ee6c6
  1. 18
      ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/QueryExpressionTests.cs
  2. 2
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/LinqTests.cs
  3. 2
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs
  4. 29
      ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj
  5. 18
      ICSharpCode.NRefactory.VB.Tests/ICSharpCode.NRefactory.VB.Tests.csproj
  6. 16
      ICSharpCode.NRefactory/CSharp/Ast/Expressions/QueryExpression.cs
  7. 4
      ICSharpCode.NRefactory/CSharp/Parser/CSharpParser.cs
  8. 1
      ICSharpCode.NRefactory/CSharp/Resolver/CSharpResolver.cs
  9. 311
      ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs
  10. 2
      ICSharpCode.NRefactory/CSharp/Resolver/TypeInference.cs
  11. 18
      ICSharpCode.NRefactory/TypeSystem/ArrayType.cs
  12. 4
      ICSharpCode.NRefactory/TypeSystem/Implementation/SimpleInterningProvider.cs
  13. 2
      ICSharpCode.NRefactory/TypeSystem/Implementation/TypeWithElementType.cs
  14. 30
      ICSharpCode.NRefactory/TypeSystem/ParameterizedType.cs
  15. 72
      NRefactory.sln

18
ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/QueryExpressionTests.cs

@ -295,5 +295,23 @@ select new { c.Name, o.OrderID, o.Total }", @@ -295,5 +295,23 @@ select new { c.Name, o.OrderID, o.Total }",
new QuerySelectClause { Expression = new IdentifierExpression("g") }
}});
}
[Test]
public void QueryWithGroupBy()
{
ParseUtilCSharp.AssertExpression(
"from a in b group c by d",
new QueryExpression {
Clauses = {
new QueryFromClause {
Identifier = "a",
Expression = new IdentifierExpression("b")
},
new QueryGroupClause {
Projection = new IdentifierExpression("c"),
Key = new IdentifierExpression("d")
}
}});
}
}
}

2
ICSharpCode.NRefactory.Tests/CSharp/Resolver/LinqTests.cs

@ -22,7 +22,7 @@ using NUnit.Framework; @@ -22,7 +22,7 @@ using NUnit.Framework;
namespace ICSharpCode.NRefactory.CSharp.Resolver
{
[TestFixture, Ignore("LINQ not yet implemented")]
[TestFixture]
public class LinqTests : ResolverTestBase
{
[Test]

2
ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs

@ -42,7 +42,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -42,7 +42,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
public virtual void SetUp()
{
project = new SimpleProjectContent();
context = new CompositeTypeResolveContext(new [] { project, mscorlib });
context = new CompositeTypeResolveContext(new [] { project, mscorlib, CecilLoaderTests.SystemCore });
resolver = new CSharpResolver(context);
resolver.UsingScope = MakeUsingScope("");
}

29
ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj

@ -12,13 +12,14 @@ @@ -12,13 +12,14 @@
<ProductVersion>10.0.0</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' ">
<PlatformTarget>x86</PlatformTarget>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<NoStdLib>False</NoStdLib>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<OutputPath>bin\Debug\</OutputPath>
<DebugSymbols>True</DebugSymbols>
<DebugSymbols>true</DebugSymbols>
<DebugType>Full</DebugType>
<Optimize>False</Optimize>
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
@ -42,6 +43,26 @@ @@ -42,6 +43,26 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<OutputPath>..\ICSharpCode.NRefactory\bin\Release\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<RegisterForComInterop>False</RegisterForComInterop>
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
<BaseAddress>4194304</BaseAddress>
<FileAlignment>4096</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<OutputPath>..\ICSharpCode.NRefactory\bin\Debug\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<OutputPath>..\ICSharpCode.NRefactory\bin\Release\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Platform)' == 'x86' ">
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.CSharp" />
<Reference Include="System" />

18
ICSharpCode.NRefactory.VB.Tests/ICSharpCode.NRefactory.VB.Tests.csproj

@ -15,7 +15,6 @@ @@ -15,7 +15,6 @@
<OutputType>Library</OutputType>
<OutputPath>..\..\..\..\bin\UnitTests\</OutputPath>
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
<PlatformTarget>x86</PlatformTarget>
<WarningLevel>4</WarningLevel>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
@ -43,6 +42,23 @@ @@ -43,6 +42,23 @@
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
<BaseAddress>4194304</BaseAddress>
<FileAlignment>4096</FileAlignment>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
<DefineConstants>DEBUG</DefineConstants>
<Optimize>False</Optimize>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<Optimize>True</Optimize>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
</PropertyGroup>
<PropertyGroup Condition=" '$(Platform)' == 'x86' ">
<RegisterForComInterop>False</RegisterForComInterop>
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
<BaseAddress>4194304</BaseAddress>
<FileAlignment>4096</FileAlignment>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="nunit.framework">

16
ICSharpCode.NRefactory/CSharp/Ast/Expressions/QueryExpression.cs

@ -108,6 +108,10 @@ namespace ICSharpCode.NRefactory.CSharp @@ -108,6 +108,10 @@ namespace ICSharpCode.NRefactory.CSharp
}
}
public Identifier IdentifierToken {
get { return GetChildByRole (Roles.Identifier); }
}
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitQueryContinuationClause (this, data);
@ -139,6 +143,10 @@ namespace ICSharpCode.NRefactory.CSharp @@ -139,6 +143,10 @@ namespace ICSharpCode.NRefactory.CSharp
}
}
public Identifier IdentifierToken {
get { return GetChildByRole(Roles.Identifier); }
}
public Expression Expression {
get { return GetChildByRole (Roles.Expression); }
set { SetChildByRole (Roles.Expression, value); }
@ -172,6 +180,10 @@ namespace ICSharpCode.NRefactory.CSharp @@ -172,6 +180,10 @@ namespace ICSharpCode.NRefactory.CSharp
}
}
public Identifier IdentifierToken {
get { return GetChildByRole(Roles.Identifier); }
}
public CSharpTokenNode AssignToken {
get { return GetChildByRole(Roles.Assign); }
}
@ -256,6 +268,10 @@ namespace ICSharpCode.NRefactory.CSharp @@ -256,6 +268,10 @@ namespace ICSharpCode.NRefactory.CSharp
}
}
public Identifier JoinIdentifierToken {
get { return GetChildByRole(JoinIdentifierRole); }
}
public CSharpTokenNode InKeyword {
get { return GetChildByRole (InKeywordRole); }
}

4
ICSharpCode.NRefactory/CSharp/Parser/CSharpParser.cs

@ -2853,10 +2853,10 @@ namespace ICSharpCode.NRefactory.CSharp @@ -2853,10 +2853,10 @@ namespace ICSharpCode.NRefactory.CSharp
var result = new QueryGroupClause ();
var location = LocationsBag.GetLocations (groupBy);
result.AddChild (new CSharpTokenNode (Convert (groupBy.Location), "group".Length), QueryGroupClause.GroupKeywordRole);
result.AddChild ((Expression)groupBy.ElementSelector.Accept (this), QueryGroupClause.KeyRole);
result.AddChild ((Expression)groupBy.ElementSelector.Accept (this), QueryGroupClause.ProjectionRole);
if (location != null)
result.AddChild (new CSharpTokenNode (Convert (location[0]), "by".Length), QueryGroupClause.ByKeywordRole);
result.AddChild ((Expression)groupBy.Expr.Accept (this), QueryGroupClause.ProjectionRole);
result.AddChild ((Expression)groupBy.Expr.Accept (this), QueryGroupClause.KeyRole);
return result;
}

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

@ -197,6 +197,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -197,6 +197,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// <summary>
/// Opens a new scope for local variables.
/// This works like <see cref="PushBlock"/>, but additionally sets <see cref="IsWithinLambdaExpression"/> to true.
/// </summary>
public void PushLambdaBlock()
{

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

@ -59,6 +59,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -59,6 +59,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
CSharpResolver resolver;
SimpleNameLookupMode currentTypeLookupMode = SimpleNameLookupMode.Type;
/// <summary>Resolve result of the current LINQ query</summary>
ResolveResult currentQueryResult;
readonly ParsedFile parsedFile;
readonly Dictionary<AstNode, ResolveResult> resolveResultCache = new Dictionary<AstNode, ResolveResult>();
readonly Dictionary<AstNode, CSharpResolver> resolverBeforeDict = new Dictionary<AstNode, CSharpResolver>();
@ -123,16 +125,19 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -123,16 +125,19 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
var oldMode = this.mode;
var oldResolver = this.resolver;
var oldTypeLookupMode = this.currentTypeLookupMode;
var oldQueryType = this.currentQueryResult;
try {
this.mode = (navigator == null) ? ResolveVisitorNavigationMode.ResolveAll : ResolveVisitorNavigationMode.Resolve;
this.resolver = storedContext;
this.currentTypeLookupMode = SimpleNameLookupMode.Type;
this.currentQueryResult = null;
action();
} finally {
this.mode = oldMode;
this.resolver = oldResolver;
this.currentTypeLookupMode = oldTypeLookupMode;
this.currentQueryResult = oldQueryType;
}
}
#endregion
@ -222,6 +227,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -222,6 +227,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
protected override ResolveResult VisitChildren(AstNode node, object data)
{
Log.WriteLine("ResolveVisitor: unhandled node " + node.GetType().Name);
Console.WriteLine("ResolveVisitor: unhandled node " + node.GetType().Name);
ScanChildren(node);
return null;
}
@ -2052,6 +2058,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2052,6 +2058,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return voidResult;
}
public override ResolveResult VisitSwitchStatement(SwitchStatement switchStatement, object data)
{
resolver.PushBlock();
ScanChildren(switchStatement);
resolver.PopBlock();
return voidResult;
}
public override ResolveResult VisitCatchClause(CatchClause catchClause, object data)
{
resolver.PushBlock();
@ -2181,6 +2195,60 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2181,6 +2195,60 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ScanChildren(expressionStatement);
return voidResult;
}
public override ResolveResult VisitLockStatement(LockStatement lockStatement, object data)
{
ScanChildren(lockStatement);
return voidResult;
}
public override ResolveResult VisitEmptyStatement(EmptyStatement emptyStatement, object data)
{
return voidResult;
}
public override ResolveResult VisitBreakStatement(BreakStatement breakStatement, object data)
{
return voidResult;
}
public override ResolveResult VisitContinueStatement(ContinueStatement continueStatement, object data)
{
return voidResult;
}
public override ResolveResult VisitThrowStatement(ThrowStatement throwStatement, object data)
{
Scan(throwStatement.Expression);
return voidResult;
}
public override ResolveResult VisitTryCatchStatement(TryCatchStatement tryCatchStatement, object data)
{
ScanChildren(tryCatchStatement);
return voidResult;
}
public override ResolveResult VisitGotoCaseStatement(GotoCaseStatement gotoCaseStatement, object data)
{
ScanChildren(gotoCaseStatement);
return voidResult;
}
public override ResolveResult VisitGotoDefaultStatement(GotoDefaultStatement gotoDefaultStatement, object data)
{
return voidResult;
}
public override ResolveResult VisitGotoStatement(GotoStatement gotoStatement, object data)
{
return voidResult;
}
public override ResolveResult VisitLabelStatement(LabelStatement labelStatement, object data)
{
return voidResult;
}
#endregion
#region Local Variable Type Inference
@ -2331,6 +2399,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2331,6 +2399,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return null;
}
}
public override ResolveResult VisitAttributeSection(AttributeSection attributeSection, object data)
{
ScanChildren(attributeSection);
return voidResult;
}
#endregion
#region Using Declaration
@ -2430,7 +2504,214 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2430,7 +2504,214 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#region Query Expressions
public override ResolveResult VisitQueryExpression(QueryExpression queryExpression, object data)
{
throw new NotImplementedException();
resolver.PushBlock();
ResolveResult oldQueryResult = currentQueryResult;
try {
currentQueryResult = null;
foreach (var clause in queryExpression.Clauses) {
currentQueryResult = Resolve(clause);
}
return new ResolveResult(currentQueryResult != null ? currentQueryResult.Type : SharedTypes.UnknownType);
} finally {
currentQueryResult = oldQueryResult;
resolver.PopBlock();
}
}
IType GetTypeForQueryVariable(IType type)
{
// This assumes queries are only used on IEnumerable.
// We might want to look at the signature of a LINQ method (e.g. Select) instead.
return GetElementType(type, resolver.Context, false);
}
sealed class QueryExpressionLambda : LambdaResolveResult
{
readonly IParameter[] parameters;
readonly IType lambdaReturnType;
public QueryExpressionLambda(int parameterCount, IType returnType)
{
this.parameters = new IParameter[parameterCount];
for (int i = 0; i < parameterCount; i++) {
parameters[i] = new DefaultParameter(SharedTypes.UnknownType, "x" + i);
}
this.lambdaReturnType = returnType;
}
public override IList<IParameter> Parameters {
get { return parameters; }
}
public override Conversion IsValid(IType[] parameterTypes, IType returnType, Conversions conversions)
{
return conversions.ImplicitConversion(lambdaReturnType, returnType);
}
public override bool IsImplicitlyTyped {
get { return true; }
}
public override bool IsAnonymousMethod {
get { return false; }
}
public override bool HasParameterList {
get { return true; }
}
public override IType GetInferredReturnType(IType[] parameterTypes)
{
return lambdaReturnType;
}
public override string ToString()
{
return string.Format("[QueryExpressionLambda ({0}) => {1}]", string.Join(",", parameters.Select(p => p.Name)), lambdaReturnType);
}
}
public override ResolveResult VisitQueryFromClause(QueryFromClause queryFromClause, object data)
{
ResolveResult result = null;
ResolveResult expr = Resolve(queryFromClause.Expression);
IType variableType;
if (queryFromClause.Type.IsNull) {
variableType = GetTypeForQueryVariable(expr.Type);
result = expr;
} else {
variableType = ResolveType(queryFromClause.Type);
if (resolverEnabled) {
// resolve the .Cast<>() call
ResolveResult methodGroup = resolver.ResolveMemberAccess(expr, "Cast", new[] { variableType }, true);
result = resolver.ResolveInvocation(methodGroup, new ResolveResult[0]);
}
}
if (resolverEnabled && currentQueryResult != null) {
// this is a second 'from': resolve the .SelectMany() call
ResolveResult methodGroup = resolver.ResolveMemberAccess(currentQueryResult, "SelectMany", EmptyList<IType>.Instance, true);
ResolveResult[] arguments = {
new QueryExpressionLambda(1, result.Type),
new QueryExpressionLambda(2, SharedTypes.UnboundTypeArgument)
};
result = resolver.ResolveInvocation(methodGroup, arguments);
}
DomRegion region = MakeRegion(queryFromClause.IdentifierToken);
IVariable v = resolver.AddVariable(variableType, region, queryFromClause.Identifier);
StoreResult(queryFromClause.IdentifierToken, new LocalResolveResult(v, variableType));
return result;
}
public override ResolveResult VisitQueryContinuationClause(QueryContinuationClause queryContinuationClause, object data)
{
ResolveResult rr = Resolve(queryContinuationClause.PrecedingQuery);
IType variableType = GetTypeForQueryVariable(rr.Type);
DomRegion region = MakeRegion(queryContinuationClause.IdentifierToken);
IVariable v = resolver.AddVariable(variableType, region, queryContinuationClause.Identifier);
StoreResult(queryContinuationClause.IdentifierToken, new LocalResolveResult(v, variableType));
return rr;
}
public override ResolveResult VisitQueryLetClause(QueryLetClause queryLetClause, object data)
{
ResolveResult expr = Resolve(queryLetClause.Expression);
DomRegion region = MakeRegion(queryLetClause.IdentifierToken);
IVariable v = resolver.AddVariable(expr.Type, region, queryLetClause.Identifier);
StoreResult(queryLetClause.IdentifierToken, new LocalResolveResult(v, expr.Type));
if (resolverEnabled && currentQueryResult != null) {
// resolve the .Select() call
ResolveResult methodGroup = resolver.ResolveMemberAccess(currentQueryResult, "Select", EmptyList<IType>.Instance, true);
ResolveResult[] arguments = { new QueryExpressionLambda(1, SharedTypes.UnboundTypeArgument) };
return resolver.ResolveInvocation(currentQueryResult, arguments);
} else {
return null;
}
}
public override ResolveResult VisitQueryJoinClause(QueryJoinClause queryJoinClause, object data)
{
// join v in expr on onExpr equals equalsExpr [into g]
ResolveResult inResult = null;
ResolveResult expr = Resolve(queryJoinClause.InExpression);
IType variableType;
if (queryJoinClause.Type.IsNull) {
variableType = GetTypeForQueryVariable(expr.Type);
if (resolverEnabled)
inResult = (currentQueryResult != null ? expr : new ResolveResult(variableType));
} else {
variableType = ResolveType(queryJoinClause.Type);
if (resolverEnabled) {
// resolve the .Cast<>() call
ResolveResult methodGroup = resolver.ResolveMemberAccess(expr, "Cast", new[] { variableType }, true);
inResult = resolver.ResolveInvocation(methodGroup, new ResolveResult[0]);
}
}
// scan the 'On' expression in a context that contains only the previously existing range variables:
// (before adding any variable)
Scan(queryJoinClause.OnExpression);
// scan the 'Equals' expression in a context that contains only the variable 'v'
CSharpResolver resolverOutsideQuery = resolver.Clone();
resolverOutsideQuery.PopBlock(); // pop all variables from the current query expression
DomRegion joinIdentifierRegion = MakeRegion(queryJoinClause.JoinIdentifierToken);
IVariable v = resolverOutsideQuery.AddVariable(variableType, joinIdentifierRegion, queryJoinClause.JoinIdentifier);
ResetContext(resolverOutsideQuery, delegate { Scan(queryJoinClause.EqualsExpression); });
StoreResult(queryJoinClause.JoinIdentifierToken, new LocalResolveResult(v, variableType));
if (queryJoinClause.IsGroupJoin) {
throw new NotImplementedException();
} else {
resolver.AddVariable(variableType, joinIdentifierRegion, queryJoinClause.JoinIdentifier);
if (resolverEnabled)
throw new NotImplementedException();
else
return null;
}
}
public override ResolveResult VisitQueryWhereClause(QueryWhereClause queryWhereClause, object data)
{
ResolveAndProcessConversion(queryWhereClause.Condition, KnownTypeReference.Boolean.Resolve(resolver.Context));
if (resolverEnabled && currentQueryResult != null) {
var methodGroup = resolver.ResolveMemberAccess(currentQueryResult, "Where", EmptyList<IType>.Instance);
ResolveResult[] arguments = { new QueryExpressionLambda(1, KnownTypeReference.Boolean.Resolve(resolver.Context)) };
return resolver.ResolveInvocation(methodGroup, arguments);
} else {
return null;
}
}
public override ResolveResult VisitQuerySelectClause(QuerySelectClause querySelectClause, object data)
{
if (resolverEnabled && currentQueryResult != null) {
ResolveResult expr = Resolve(querySelectClause.Expression);
var methodGroup = resolver.ResolveMemberAccess(currentQueryResult, "Select", EmptyList<IType>.Instance);
ResolveResult[] arguments = { new QueryExpressionLambda(1, expr.Type) };
return resolver.ResolveInvocation(methodGroup, arguments);
} else {
Scan(querySelectClause.Expression);
return null;
}
}
public override ResolveResult VisitQueryGroupClause(QueryGroupClause queryGroupClause, object data)
{
if (resolverEnabled && currentQueryResult != null) {
// ... group projection by key
ResolveResult projection = Resolve(queryGroupClause.Projection);
ResolveResult key = Resolve(queryGroupClause.Key);
var methodGroup = resolver.ResolveMemberAccess(currentQueryResult, "GroupBy", EmptyList<IType>.Instance);
ResolveResult[] arguments = {
new QueryExpressionLambda(1, key.Type),
new QueryExpressionLambda(1, projection.Type)
};
return resolver.ResolveInvocation(methodGroup, arguments);
} else {
ScanChildren(queryGroupClause);
return null;
}
}
#endregion
@ -2453,7 +2734,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2453,7 +2734,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
#endregion
#region Token Nodes
#region Other Nodes
// Token nodes
public override ResolveResult VisitIdentifier(Identifier identifier, object data)
{
return null;
@ -2468,6 +2750,31 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2468,6 +2750,31 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
{
return null;
}
// Nodes where we just need to visit the children:
public override ResolveResult VisitAccessor(Accessor accessor, object data)
{
ScanChildren(accessor);
return voidResult;
}
public override ResolveResult VisitSwitchSection(SwitchSection switchSection, object data)
{
ScanChildren(switchSection);
return voidResult;
}
public override ResolveResult VisitCaseLabel(CaseLabel caseLabel, object data)
{
ScanChildren(caseLabel);
return voidResult;
}
public override ResolveResult VisitConstraint(Constraint constraint, object data)
{
ScanChildren(constraint);
return voidResult;
}
#endregion
}
}

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

@ -908,7 +908,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -908,7 +908,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
// Finds a type X so that "LB <: X <: UB"
Log.WriteCollection("FindTypesInBound, LowerBounds=", lowerBounds);
Log.WriteCollection("FindTypesInBound, UpperBounds=", upperBounds);
Log.Indent();
// First try the Fixing algorithm from the C# spec (§7.5.2.11)
List<IType> candidateTypes = lowerBounds.Union(upperBounds)
@ -930,6 +929,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -930,6 +929,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
candidateTypes.Clear();
// Now try the improved algorithm
Log.Indent();
List<ITypeDefinition> candidateTypeDefinitions;
if (lowerBounds.Count > 0) {
// Find candidates by using the lower bounds:

18
ICSharpCode.NRefactory/TypeSystem/ArrayType.cs

@ -26,7 +26,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -26,7 +26,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// Represents an array type.
/// </summary>
[Serializable]
public sealed class ArrayType : TypeWithElementType
public sealed class ArrayType : TypeWithElementType, ISupportsInterning
{
readonly int dimensions;
@ -134,6 +134,22 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -134,6 +134,22 @@ namespace ICSharpCode.NRefactory.TypeSystem
else
return new ArrayType(e, dimensions);
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
elementType = provider.Intern(elementType);
}
int ISupportsInterning.GetHashCodeForInterning()
{
return elementType.GetHashCode() ^ dimensions;
}
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
{
ArrayType o = other as ArrayType;
return o != null && elementType == o.elementType && dimensions == o.dimensions;
}
}
[Serializable]

4
ICSharpCode.NRefactory/TypeSystem/Implementation/SimpleInterningProvider.cs

@ -122,7 +122,9 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -122,7 +122,9 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
else
supportsInternDict.Add(s, s);
}
} else if (obj is IType || Type.GetTypeCode(obj.GetType()) >= TypeCode.Boolean) {
} else if (Type.GetTypeCode(obj.GetType()) >= TypeCode.Boolean) {
// IType cannot be interned by value because ITypeParameters with different names are considered
// equal (for object.Equals), but should not be interned.
object output;
if (byValueDict.TryGetValue(obj, out output))
obj = (T)output;

2
ICSharpCode.NRefactory/TypeSystem/Implementation/TypeWithElementType.cs

@ -23,7 +23,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -23,7 +23,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
[Serializable]
public abstract class TypeWithElementType : AbstractType
{
protected readonly IType elementType;
protected IType elementType;
protected TypeWithElementType(IType elementType)
{

30
ICSharpCode.NRefactory/TypeSystem/ParameterizedType.cs

@ -37,7 +37,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -37,7 +37,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// the type arguments.
/// </remarks>
[Serializable]
public sealed class ParameterizedType : Immutable, IType
public sealed class ParameterizedType : Immutable, IType, ISupportsInterning
{
readonly ITypeDefinition genericType;
readonly IType[] typeArguments;
@ -322,8 +322,33 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -322,8 +322,33 @@ namespace ICSharpCode.NRefactory.TypeSystem
else
return new ParameterizedType(def, ta);
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
{
for (int i = 0; i < typeArguments.Length; i++) {
typeArguments[i] = provider.Intern(typeArguments[i]);
}
}
int ISupportsInterning.GetHashCodeForInterning()
{
return GetHashCode();
}
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
{
ParameterizedType o = other as ParameterizedType;
if (o != null && genericType == o.genericType && typeArguments.Length == o.typeArguments.Length) {
for (int i = 0; i < typeArguments.Length; i++) {
if (typeArguments[i] != o.typeArguments[i])
return false;
}
return true;
}
return false;
}
}
/// <summary>
/// ParameterizedTypeReference is a reference to generic class that specifies the type parameters.
/// Example: List&lt;string&gt;
@ -443,7 +468,6 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -443,7 +468,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
return true;
}
return false;
}
}
}

72
NRefactory.sln

@ -1,9 +1,8 @@ @@ -1,9 +1,8 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
# SharpDevelop 4.1.0.7854-beta
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{DC98210E-1646-483B-819A-2BB8272461E4}"
ProjectSection(SolutionItems) = postProject
ProjectSection(SolutionItems) = preProject
README = README
doc\TODO = doc\TODO
EndProjectSection
@ -25,59 +24,70 @@ EndProject @@ -25,59 +24,70 @@ EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.Debug|x86.ActiveCfg = Debug|Any CPU
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.Debug|x86.Build.0 = Debug|Any CPU
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.Release|Any CPU.Build.0 = Release|Any CPU
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.Release|x86.ActiveCfg = Release|Any CPU
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.Release|x86.Build.0 = Release|Any CPU
{63D3B27A-D966-4902-90B3-30290E1692F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{63D3B27A-D966-4902-90B3-30290E1692F1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{63D3B27A-D966-4902-90B3-30290E1692F1}.Debug|x86.ActiveCfg = Debug|x86
{63D3B27A-D966-4902-90B3-30290E1692F1}.Debug|x86.Build.0 = Debug|x86
{63D3B27A-D966-4902-90B3-30290E1692F1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{63D3B27A-D966-4902-90B3-30290E1692F1}.Release|Any CPU.Build.0 = Release|Any CPU
{7B82B671-419F-45F4-B778-D9286F996EFA}.Debug|Any CPU.Build.0 = Debug|x86
{7B82B671-419F-45F4-B778-D9286F996EFA}.Debug|Any CPU.ActiveCfg = Debug|x86
{7B82B671-419F-45F4-B778-D9286F996EFA}.Debug|x86.Build.0 = Debug|x86
{7B82B671-419F-45F4-B778-D9286F996EFA}.Debug|x86.ActiveCfg = Debug|x86
{7B82B671-419F-45F4-B778-D9286F996EFA}.Release|Any CPU.Build.0 = Release|x86
{7B82B671-419F-45F4-B778-D9286F996EFA}.Release|Any CPU.ActiveCfg = Release|x86
{7B82B671-419F-45F4-B778-D9286F996EFA}.Release|x86.Build.0 = Release|x86
{7B82B671-419F-45F4-B778-D9286F996EFA}.Release|x86.ActiveCfg = Release|x86
{870115DD-960A-4406-A6B9-600BCDC36A03}.Debug|Any CPU.Build.0 = Debug|Any CPU
{63D3B27A-D966-4902-90B3-30290E1692F1}.Release|x86.ActiveCfg = Release|x86
{63D3B27A-D966-4902-90B3-30290E1692F1}.Release|x86.Build.0 = Release|x86
{7B82B671-419F-45F4-B778-D9286F996EFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7B82B671-419F-45F4-B778-D9286F996EFA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7B82B671-419F-45F4-B778-D9286F996EFA}.Debug|x86.ActiveCfg = Debug|Any CPU
{7B82B671-419F-45F4-B778-D9286F996EFA}.Debug|x86.Build.0 = Debug|Any CPU
{7B82B671-419F-45F4-B778-D9286F996EFA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7B82B671-419F-45F4-B778-D9286F996EFA}.Release|Any CPU.Build.0 = Release|Any CPU
{7B82B671-419F-45F4-B778-D9286F996EFA}.Release|x86.ActiveCfg = Release|Any CPU
{7B82B671-419F-45F4-B778-D9286F996EFA}.Release|x86.Build.0 = Release|Any CPU
{870115DD-960A-4406-A6B9-600BCDC36A03}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{870115DD-960A-4406-A6B9-600BCDC36A03}.Debug|x86.Build.0 = Debug|Any CPU
{870115DD-960A-4406-A6B9-600BCDC36A03}.Debug|x86.ActiveCfg = Debug|Any CPU
{870115DD-960A-4406-A6B9-600BCDC36A03}.Release|Any CPU.Build.0 = Release|Any CPU
{870115DD-960A-4406-A6B9-600BCDC36A03}.Debug|Any CPU.Build.0 = Debug|Any CPU
{870115DD-960A-4406-A6B9-600BCDC36A03}.Debug|x86.ActiveCfg = Debug|x86
{870115DD-960A-4406-A6B9-600BCDC36A03}.Debug|x86.Build.0 = Debug|x86
{870115DD-960A-4406-A6B9-600BCDC36A03}.Release|Any CPU.ActiveCfg = Release|Any CPU
{870115DD-960A-4406-A6B9-600BCDC36A03}.Release|x86.Build.0 = Release|Any CPU
{870115DD-960A-4406-A6B9-600BCDC36A03}.Release|x86.ActiveCfg = Release|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Debug|Any CPU.Build.0 = net_4_0_Debug|Any CPU
{870115DD-960A-4406-A6B9-600BCDC36A03}.Release|Any CPU.Build.0 = Release|Any CPU
{870115DD-960A-4406-A6B9-600BCDC36A03}.Release|x86.ActiveCfg = Release|x86
{870115DD-960A-4406-A6B9-600BCDC36A03}.Release|x86.Build.0 = Release|x86
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Debug|Any CPU.ActiveCfg = net_4_0_Debug|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Debug|x86.Build.0 = net_4_0_Debug|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Debug|Any CPU.Build.0 = net_4_0_Debug|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Debug|x86.ActiveCfg = net_4_0_Debug|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Release|Any CPU.Build.0 = net_4_0_Debug|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Debug|x86.Build.0 = net_4_0_Debug|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Release|Any CPU.ActiveCfg = net_4_0_Release|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Release|x86.Build.0 = net_4_0_Debug|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Release|Any CPU.Build.0 = net_4_0_Release|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Release|x86.ActiveCfg = net_4_0_Release|Any CPU
{9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.Debug|Any CPU.Build.0 = Debug|x86
{9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPUh
{9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.Debug|x86.Build.0 = Debug|x86
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Release|x86.Build.0 = net_4_0_Release|Any CPU
{9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.Debug|x86.ActiveCfg = Debug|x86
{9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.Release|Any CPU.Build.0 = Release|x86
{9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.Release|Any CPU.ActiveCfg = Release|Any CPUh
{9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.Release|x86.Build.0 = Release|x86
{9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.Debug|x86.Build.0 = Debug|x86
{9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.Release|Any CPU.Build.0 = Release|Any CPU
{9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.Release|x86.ActiveCfg = Release|x86
{F054A788-B591-4561-A8BA-AE745BBEB817}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.Release|x86.Build.0 = Release|x86
{F054A788-B591-4561-A8BA-AE745BBEB817}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F054A788-B591-4561-A8BA-AE745BBEB817}.Debug|x86.Build.0 = Debug|Any CPU
{F054A788-B591-4561-A8BA-AE745BBEB817}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F054A788-B591-4561-A8BA-AE745BBEB817}.Debug|x86.ActiveCfg = Debug|Any CPU
{F054A788-B591-4561-A8BA-AE745BBEB817}.Release|Any CPU.Build.0 = Release|Any CPU
{F054A788-B591-4561-A8BA-AE745BBEB817}.Debug|x86.Build.0 = Debug|Any CPU
{F054A788-B591-4561-A8BA-AE745BBEB817}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F054A788-B591-4561-A8BA-AE745BBEB817}.Release|x86.Build.0 = Release|Any CPU
{F054A788-B591-4561-A8BA-AE745BBEB817}.Release|Any CPU.Build.0 = Release|Any CPU
{F054A788-B591-4561-A8BA-AE745BBEB817}.Release|x86.ActiveCfg = Release|Any CPU
{F054A788-B591-4561-A8BA-AE745BBEB817}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = ICSharpCode.NRefactory\ICSharpCode.NRefactory.csproj

Loading…
Cancel
Save