Browse Source

Fix ResolveVisitor.GetResolverStateBefore(): ensure that the resolver always registers the state before it caches a result.

newNRvisualizers
Daniel Grunwald 14 years ago
parent
commit
f043e30fbf
  1. 54
      ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs

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

@ -168,7 +168,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -168,7 +168,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (resolverBeforeDict.Count == 0) {
// If we're just starting to resolve and haven't any context cached yet,
// make sure to cache the root node.
StoreState(node, resolver.Clone());
StoreCurrentState(node);
}
break;
case ResolveVisitorNavigationMode.Scan:
@ -184,7 +184,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -184,7 +184,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
bool oldResolverEnabled = resolverEnabled;
resolverEnabled = false;
StoreState(node, resolver.Clone());
StoreCurrentState(node);
node.AcceptVisitor(this, null);
resolverEnabled = oldResolverEnabled;
break;
@ -215,7 +215,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -215,7 +215,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ResolveResult result;
if (!resolveResultCache.TryGetValue(node, out result)) {
resolver.cancellationToken.ThrowIfCancellationRequested();
StoreState(node, resolver.Clone());
StoreCurrentState(node);
result = node.AcceptVisitor(this, null) ?? errorResult;
Log.WriteLine("Resolved '{0}' to {1}", node, result);
StoreResult(node, result);
@ -229,12 +229,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -229,12 +229,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return Resolve(type).Type;
}
void StoreState(AstNode node, CSharpResolver resolverState)
void StoreCurrentState(AstNode node)
{
Debug.Assert(resolverState != null);
// It's possible that we re-visit an expression that we scanned over earlier,
// so we might have to overwrite an existing state.
resolverBeforeDict[node] = resolverState;
resolverBeforeDict[node] = resolver.Clone();
}
void StoreResult(AstNode node, ResolveResult result)
@ -242,6 +241,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -242,6 +241,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
Debug.Assert(result != null);
if (node.IsNull)
return;
// The state should be stored before the result is.
Debug.Assert(resolverBeforeDict.ContainsKey(node));
// Don't store results twice.
Debug.Assert(!resolveResultCache.ContainsKey(node));
resolveResultCache.Add(node, result);
if (navigator != null)
@ -621,7 +623,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -621,7 +623,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
ArrayType arrayType = result.Type as ArrayType;
if (aie != null && arrayType != null) {
StoreState(aie, resolver.Clone());
StoreCurrentState(aie);
List<Expression> initializerElements = new List<Expression>();
UnpackArrayInitializer(initializerElements, aie, arrayType.Dimensions, true);
ResolveResult[] initializerElementResults = new ResolveResult[initializerElements.Count];
@ -966,6 +968,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -966,6 +968,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
initializerElements = null;
initializerElementResults = null;
} else {
StoreCurrentState(arrayCreateExpression.Initializer);
initializerElements = new List<Expression>();
UnpackArrayInitializer(initializerElements, arrayCreateExpression.Initializer, dimensions, true);
initializerElementResults = new ResolveResult[initializerElements.Count];
@ -996,8 +1000,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -996,8 +1000,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
foreach (var node in initializer.Elements) {
ArrayInitializerExpression aie = node as ArrayInitializerExpression;
if (aie != null) {
if (resolveNestedInitializesToVoid)
if (resolveNestedInitializesToVoid) {
StoreCurrentState(aie);
StoreResult(aie, voidResult);
}
UnpackArrayInitializer(elementList, aie, dimensions - 1, resolveNestedInitializesToVoid);
} else {
elementList.Add(node);
@ -1239,6 +1245,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1239,6 +1245,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
void HandleObjectInitializer(IType type, ArrayInitializerExpression initializer)
{
StoreCurrentState(initializer);
resolver.PushInitializerType(type);
foreach (Expression element in initializer.Elements) {
ArrayInitializerExpression aie = element as ArrayInitializerExpression;
@ -1247,7 +1254,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1247,7 +1254,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
// Don't resolve the add call again if we already did so
continue;
}
StoreState(aie, resolver.Clone());
StoreCurrentState(aie);
// constructor argument list in collection initializer
ResolveResult[] addArguments = new ResolveResult[aie.Elements.Count];
int i = 0;
@ -1505,7 +1512,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1505,7 +1512,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
&& !resolveResultCache.ContainsKey(identifierExpression))
{
// Special handling for §7.6.4.1 Identicial simple names and type names
StoreState(identifierExpression, resolver.Clone());
StoreCurrentState(identifierExpression);
ResolveResult target = resolver.ResolveSimpleName(identifierExpression.Identifier, EmptyList<IType>.Instance);
TypeResolveResult trr;
if (IsVariableReferenceWithSameType(target, identifierExpression.Identifier, out trr)) {
@ -1563,6 +1570,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1563,6 +1570,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
&& !resolveResultCache.ContainsKey(identifierExpression))
{
// Special handling for §7.6.4.1 Identicial simple names and type names
StoreCurrentState(identifierExpression);
StoreCurrentState(mre);
ResolveResult idRR = resolver.ResolveSimpleName(identifierExpression.Identifier, EmptyList<IType>.Instance);
ResolveResult target = ResolveMemberReferenceOnGivenTarget(idRR, mre);
Log.WriteLine("Member reference '{0}' on potentially-ambiguous simple-name was resolved to {1}", mre, target);
@ -2111,12 +2122,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2111,12 +2122,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
visitor.MergeUndecidedLambdas();
Log.WriteLine("Merging " + ToString());
foreach (var pair in visitor.resolverBeforeDict) {
parentVisitor.resolverBeforeDict[pair.Key] = pair.Value;
}
foreach (var pair in visitor.resolveResultCache) {
parentVisitor.StoreResult(pair.Key, pair.Value);
}
foreach (var pair in visitor.resolverBeforeDict) {
parentVisitor.StoreState(pair.Key, pair.Value);
}
parentVisitor.undecidedLambdas.Remove(lambda);
}
@ -2416,6 +2427,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2416,6 +2427,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
Scan(foreachStatement.InExpression);
type = ResolveType(foreachStatement.VariableType);
}
StoreCurrentState(foreachStatement.VariableNameToken);
IVariable v = resolver.AddVariable(type, MakeRegion(foreachStatement.VariableNameToken), foreachStatement.VariableName);
StoreResult(foreachStatement.VariableNameToken, new LocalResolveResult(v, v.Type.Resolve(resolver.Context)));
Scan(foreachStatement.EmbeddedStatement);
@ -2437,6 +2449,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2437,6 +2449,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (!string.IsNullOrEmpty(catchClause.VariableName)) {
ITypeReference variableType = MakeTypeReference(catchClause.Type);
DomRegion region = MakeRegion(catchClause.VariableNameToken);
StoreCurrentState(catchClause.VariableNameToken);
IVariable v = resolver.AddVariable(variableType, region, catchClause.VariableName);
StoreResult(catchClause.VariableNameToken, new LocalResolveResult(v, v.Type.Resolve(resolver.Context)));
}
@ -2457,6 +2470,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2457,6 +2470,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
|| navigator.Scan(vi) == ResolveVisitorNavigationMode.Resolve;
ITypeReference type;
if (needResolve) {
StoreCurrentState(variableDeclarationStatement.Type);
type = Resolve(vi.Initializer).Type;
if (!resolveResultCache.ContainsKey(variableDeclarationStatement.Type)) {
StoreResult(variableDeclarationStatement.Type, new TypeResolveResult(type.Resolve(resolver.Context)));
@ -2466,7 +2480,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2466,7 +2480,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
type = MakeVarTypeReference(vi.Initializer, false);
}
IVariable v = resolver.AddVariable(type, MakeRegion(vi), vi.Name);
StoreState(vi, resolver.Clone());
StoreCurrentState(vi);
if (needResolve) {
ResolveResult result;
if (!resolveResultCache.TryGetValue(vi, out result)) {
@ -2834,6 +2848,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2834,6 +2848,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ResolveResult target;
if (memberType.IsDoubleColon && memberType.Target is SimpleType) {
SimpleType t = (SimpleType)memberType.Target;
StoreCurrentState(t);
target = resolver.ResolveAlias(t.Identifier);
StoreResult(t, target);
} else {
@ -2984,6 +2999,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2984,6 +2999,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
}
StoreCurrentState(queryFromClause.IdentifierToken);
DomRegion region = MakeRegion(queryFromClause.IdentifierToken);
IVariable v = resolver.AddVariable(variableType, region, queryFromClause.Identifier);
StoreResult(queryFromClause.IdentifierToken, new LocalResolveResult(v, variableType));
@ -3014,6 +3030,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -3014,6 +3030,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ResolveResult rr = Resolve(queryContinuationClause.PrecedingQuery);
IType variableType = GetTypeForQueryVariable(rr.Type);
DomRegion region = MakeRegion(queryContinuationClause.IdentifierToken);
StoreCurrentState(queryContinuationClause.IdentifierToken);
IVariable v = resolver.AddVariable(variableType, region, queryContinuationClause.Identifier);
StoreResult(queryContinuationClause.IdentifierToken, new LocalResolveResult(v, variableType));
return rr;
@ -3023,6 +3040,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -3023,6 +3040,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
{
ResolveResult expr = Resolve(queryLetClause.Expression);
DomRegion region = MakeRegion(queryLetClause.IdentifierToken);
StoreCurrentState(queryLetClause.IdentifierToken);
IVariable v = resolver.AddVariable(expr.Type, region, queryLetClause.Identifier);
StoreResult(queryLetClause.IdentifierToken, new LocalResolveResult(v, expr.Type));
if (resolverEnabled && currentQueryResult != null) {
@ -3066,6 +3084,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -3066,6 +3084,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ResetContext(resolverOutsideQuery, delegate {
equalsResult = Resolve(queryJoinClause.EqualsExpression);
});
StoreCurrentState(queryJoinClause.JoinIdentifierToken);
StoreResult(queryJoinClause.JoinIdentifierToken, new LocalResolveResult(v, variableType));
if (queryJoinClause.IsGroupJoin) {
@ -3144,10 +3163,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -3144,10 +3163,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
implicitlyTypedLambda.EnforceMerge(this);
if (implicitlyTypedLambda.winningHypothesis.parameterTypes.Length == 2)
if (implicitlyTypedLambda.winningHypothesis.parameterTypes.Length == 2) {
StoreCurrentState(queryJoinClause.IntoIdentifierToken);
groupVariable = implicitlyTypedLambda.winningHypothesis.lambdaParameters[1];
else
} else {
groupVariable = null;
}
} else {
Debug.Assert(groupJoinLambda is QueryExpressionLambda);
@ -3172,6 +3193,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -3172,6 +3193,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
else
groupParameterType = SharedTypes.UnknownType;
StoreCurrentState(queryJoinClause.IntoIdentifierToken);
groupVariable = resolver.AddVariable(groupParameterType, intoIdentifierRegion, queryJoinClause.IntoIdentifier);
}

Loading…
Cancel
Save