Browse Source

fix bug in IntroduceUsingDeclarations: use matching ITypeResolveContext for each namespace and type

pull/728/head
Siegfried Pammer 10 years ago
parent
commit
80cebbe448
  1. 74
      ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUsingDeclarations.cs
  2. 2
      ICSharpCode.Decompiler/Tests/TestRunner.cs

74
ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUsingDeclarations.cs

@ -65,21 +65,9 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
if (!FullyQualifyAmbiguousTypeNames) if (!FullyQualifyAmbiguousTypeNames)
return; return;
var astBuilder = CreateAstBuilderWithUsingScope(context, usingScope);
// verify that the SimpleTypes refer to the correct type (no ambiguities)
compilationUnit.AcceptVisitor(new FullyQualifyAmbiguousTypeNamesVisitor(astBuilder), null);
}
TypeSystemAstBuilder CreateAstBuilderWithUsingScope(TransformContext context, UsingScope usingScope) // verify that the SimpleTypes refer to the correct type (no ambiguities)
{ compilationUnit.AcceptVisitor(new FullyQualifyAmbiguousTypeNamesVisitor(context, usingScope), null);
var resolveContext = new CSharpTypeResolveContext(context.TypeSystem.MainAssembly, usingScope.Resolve(context.TypeSystem.Compilation), context.DecompiledTypeDefinition, context.DecompiledMember);
var resolver = new CSharpResolver(resolveContext);
return new TypeSystemAstBuilder(resolver) {
AddResolveResultAnnotations = true,
UseAliases = true
};
} }
sealed class FindRequiredImports : DepthFirstAstVisitor sealed class FindRequiredImports : DepthFirstAstVisitor
@ -130,37 +118,57 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
sealed class FullyQualifyAmbiguousTypeNamesVisitor : DepthFirstAstVisitor<object, object> sealed class FullyQualifyAmbiguousTypeNamesVisitor : DepthFirstAstVisitor<object, object>
{ {
readonly TypeSystemAstBuilder astBuilder; Stack<CSharpTypeResolveContext> context;
TypeSystemAstBuilder astBuilder;
public FullyQualifyAmbiguousTypeNamesVisitor(TypeSystemAstBuilder astBuilder) public FullyQualifyAmbiguousTypeNamesVisitor(TransformContext context, UsingScope usingScope)
{ {
this.astBuilder = astBuilder; this.context = new Stack<CSharpTypeResolveContext>();
var currentContext = new CSharpTypeResolveContext(context.TypeSystem.MainAssembly, usingScope.Resolve(context.TypeSystem.Compilation));
this.context.Push(currentContext);
this.astBuilder = CreateAstBuilder(currentContext);
}
static TypeSystemAstBuilder CreateAstBuilder(CSharpTypeResolveContext context)
{
return new TypeSystemAstBuilder(new CSharpResolver(context)) {
AddResolveResultAnnotations = true,
UseAliases = true
};
} }
public override object VisitSimpleType(SimpleType simpleType, object data) public override object VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration, object data)
{ {
TypeResolveResult rr; var previousContext = context.Peek();
if (simpleType.Ancestors.OfType<UsingDeclaration>().Any() || (rr = simpleType.Annotation<TypeResolveResult>()) == null) var currentUsingScope = new UsingScope(previousContext.CurrentUsingScope.UnresolvedUsingScope, namespaceDeclaration.Identifiers.Last());
return base.VisitSimpleType(simpleType, data); var currentContext = new CSharpTypeResolveContext(previousContext.CurrentAssembly, currentUsingScope.Resolve(previousContext.Compilation));
simpleType.ReplaceWith(astBuilder.ConvertType(rr.Type)); context.Push(currentContext);
return null; try {
astBuilder = CreateAstBuilder(currentContext);
return base.VisitNamespaceDeclaration(namespaceDeclaration, data);
} finally {
context.Pop();
}
} }
public override object VisitMemberType(MemberType memberType, object data) public override object VisitTypeDeclaration(TypeDeclaration typeDeclaration, object data)
{ {
TypeResolveResult rr; var currentContext = context.Peek().WithCurrentTypeDefinition(typeDeclaration.GetSymbol() as ITypeDefinition);
if (memberType.Ancestors.OfType<UsingDeclaration>().Any() || (rr = memberType.Annotation<TypeResolveResult>()) == null) context.Push(currentContext);
return base.VisitMemberType(memberType, data); try {
memberType.ReplaceWith(astBuilder.ConvertType(rr.Type)); astBuilder = CreateAstBuilder(currentContext);
return null; return base.VisitTypeDeclaration(typeDeclaration, data);
} finally {
context.Pop();
}
} }
public override object VisitComposedType(ComposedType composedType, object data) public override object VisitSimpleType(SimpleType simpleType, object data)
{ {
TypeResolveResult rr; TypeResolveResult rr;
if (composedType.Ancestors.OfType<UsingDeclaration>().Any() || (rr = composedType.Annotation<TypeResolveResult>()) == null) if (simpleType.Ancestors.OfType<UsingDeclaration>().Any() || (rr = simpleType.Annotation<TypeResolveResult>()) == null)
return base.VisitComposedType(composedType, data); return base.VisitSimpleType(simpleType, data);
composedType.ReplaceWith(astBuilder.ConvertType(rr.Type)); simpleType.ReplaceWith(astBuilder.ConvertType(rr.Type));
return null; return null;
} }
} }

2
ICSharpCode.Decompiler/Tests/TestRunner.cs

@ -70,7 +70,7 @@ namespace ICSharpCode.Decompiler.Tests
TestCompileDecompileCompileOutputAll("ValueTypeCall.cs"); TestCompileDecompileCompileOutputAll("ValueTypeCall.cs");
} }
[Test, Ignore("broken")] [Test]
public void InitializerTests() public void InitializerTests()
{ {
TestCompileDecompileCompileOutputAll("InitializerTests.cs"); TestCompileDecompileCompileOutputAll("InitializerTests.cs");

Loading…
Cancel
Save