From 83c525c1c29bff7211e675e498c2fc7cd49ec1d4 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Fri, 25 Oct 2019 23:20:51 +0200 Subject: [PATCH] Fix #1758: Input var name conflicting with framework class name --- .../TestCases/Pretty/QualifierTests.cs | 53 ++++++++++++ .../CSharp/CSharpDecompiler.cs | 1 + .../CSharp/ExpressionBuilder.cs | 2 +- .../Transforms/IntroduceUsingDeclarations.cs | 80 ++++++++++++------- .../CSharpHighlightingTokenWriter.cs | 8 +- 5 files changed, 115 insertions(+), 29 deletions(-) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/QualifierTests.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/QualifierTests.cs index 3f3c5cf59..b09df51e7 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/QualifierTests.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/QualifierTests.cs @@ -128,9 +128,45 @@ namespace ICSharpCode.Decompiler.Tests.Pretty } } + private class i + { + public static void Test() + { + } + } + + private class value + { + public static int item; + + public static void Test() + { + } + } + private int fieldConflict; private int innerConflict; + private static int PropertyValueParameterConflictsWithTypeName { + get { + return value.item; + } + set { + QualifierTests.value.item = value; + } + } + + private int this[string[] Array] { + get { + System.Array.Sort(Array); + return 0; + } + set { + System.Array.Sort(Array); + QualifierTests.value.item = value; + } + } + private void NoParameters() { Delegate(Parameter); @@ -209,6 +245,23 @@ namespace ICSharpCode.Decompiler.Tests.Pretty { } + + private void ParameterConflictsWithTypeName(string[] Array) + { + System.Array.Sort(Array); + } + + private void LocalConflictsWithTypeName() + { + for (int i = 0; i < 10; i++) { + QualifierTests.i.Test(); + } + } + + public QualifierTests(string[] Array) + { + System.Array.Sort(Array); + } } internal static class ZExt diff --git a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs index df2cf850f..bb304f77c 100644 --- a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs +++ b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs @@ -1298,6 +1298,7 @@ namespace ICSharpCode.Decompiler.CSharp parameter.AddAnnotation(new ILVariableResolveResult(v, method.Parameters[i].Type)); i++; } + entityDecl.AddAnnotation(function); } var localSettings = settings.Clone(); diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index 19f50310c..9ba6a3677 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -203,7 +203,7 @@ namespace ICSharpCode.Decompiler.CSharp return true; } - foreach (var f in function.LocalFunctions.OfType()) { + foreach (var f in function.LocalFunctions) { if (f.Name == name) return true; } diff --git a/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUsingDeclarations.cs b/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUsingDeclarations.cs index 2aa5efb95..b06686d0f 100644 --- a/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUsingDeclarations.cs +++ b/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUsingDeclarations.cs @@ -25,6 +25,7 @@ using ICSharpCode.Decompiler.CSharp.Syntax; using ICSharpCode.Decompiler.CSharp.TypeSystem; using ICSharpCode.Decompiler.Semantics; using ICSharpCode.Decompiler.TypeSystem; +using ICSharpCode.Decompiler.TypeSystem.Implementation; namespace ICSharpCode.Decompiler.CSharp.Transforms { @@ -55,8 +56,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms for (int i = 1; i < parts.Length; i++) { nsType = new MemberType { Target = nsType, MemberName = parts[i] }; } - var reference = nsType.ToTypeReference(NameLookupMode.TypeInUsingDeclaration) as TypeOrNamespaceReference; - if (reference != null) + if (nsType.ToTypeReference(NameLookupMode.TypeInUsingDeclaration) is TypeOrNamespaceReference reference) usingScope.Usings.Add(reference); rootNode.InsertChildAfter(insertionPoint, new UsingDeclaration { Import = nsType }, SyntaxTree.MemberRole); } @@ -109,28 +109,15 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms } base.VisitNamespaceDeclaration(namespaceDeclaration); currentNamespace = oldNamespace; - }/* - - public override void VisitTypeDeclaration(TypeDeclaration typeDeclaration) - { - string oldNamespace = currentNamespace; - if (!(typeDeclaration.Parent is NamespaceDeclaration || typeDeclaration.Parent is TypeDeclaration)) { - var symbol = typeDeclaration.GetSymbol() as ITypeDefinition; - if (symbol != null) { - currentNamespace = symbol.Namespace; - DeclaredNamespaces.Add(currentNamespace); - } - } - base.VisitTypeDeclaration(typeDeclaration); - currentNamespace = oldNamespace; - }*/ + } } sealed class FullyQualifyAmbiguousTypeNamesVisitor : DepthFirstAstVisitor { - Stack context; + readonly Stack context; + readonly bool ignoreUsingScope; + TypeSystemAstBuilder astBuilder; - bool ignoreUsingScope; public FullyQualifyAmbiguousTypeNamesVisitor(TransformContext context, UsingScope usingScope) { @@ -152,9 +139,17 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms this.astBuilder = CreateAstBuilder(currentContext); } - static TypeSystemAstBuilder CreateAstBuilder(CSharpTypeResolveContext context) + static TypeSystemAstBuilder CreateAstBuilder(CSharpTypeResolveContext context, IL.ILFunction function = null) { - return new TypeSystemAstBuilder(new CSharpResolver(context)) { + CSharpResolver resolver = new CSharpResolver(context); + if (function != null) { + foreach (var v in function.Variables) { + if (v.Kind != IL.VariableKind.Parameter) + resolver = resolver.AddVariable(new DefaultVariable(v.Type, v.Name)); + } + } + + return new TypeSystemAstBuilder(resolver) { AddResolveResultAnnotations = true, UseAliases = true }; @@ -201,24 +196,55 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms } public override void VisitMethodDeclaration(MethodDeclaration methodDeclaration) + { + Visit(methodDeclaration, base.VisitMethodDeclaration); + } + + public override void VisitAccessor(Accessor accessor) + { + Visit(accessor, base.VisitAccessor); + } + + public override void VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration) + { + Visit(constructorDeclaration, base.VisitConstructorDeclaration); + } + + public override void VisitDestructorDeclaration(DestructorDeclaration destructorDeclaration) + { + Visit(destructorDeclaration, base.VisitDestructorDeclaration); + } + + public override void VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration) + { + Visit(operatorDeclaration, base.VisitOperatorDeclaration); + } + + void Visit(T entityDeclaration, Action baseCall) where T : EntityDeclaration { if (ignoreUsingScope) { - base.VisitMethodDeclaration(methodDeclaration); + baseCall(entityDeclaration); return; } - if (methodDeclaration.GetSymbol() is IMethod method && CSharpDecompiler.IsWindowsFormsInitializeComponentMethod(method)) { + if (entityDeclaration.GetSymbol() is IMethod method) { var previousContext = context.Peek(); - var currentContext = new CSharpTypeResolveContext(previousContext.CurrentModule); + CSharpTypeResolveContext currentContext; + if (CSharpDecompiler.IsWindowsFormsInitializeComponentMethod(method)) { + currentContext = new CSharpTypeResolveContext(previousContext.CurrentModule); + } else { + currentContext = previousContext.WithCurrentMember(method); + } context.Push(currentContext); try { - astBuilder = CreateAstBuilder(currentContext); - base.VisitMethodDeclaration(methodDeclaration); + var function = entityDeclaration.Annotation(); + astBuilder = CreateAstBuilder(currentContext, function); + baseCall(entityDeclaration); } finally { astBuilder = CreateAstBuilder(previousContext); context.Pop(); } } else { - base.VisitMethodDeclaration(methodDeclaration); + baseCall(entityDeclaration); } } diff --git a/ILSpy/Languages/CSharpHighlightingTokenWriter.cs b/ILSpy/Languages/CSharpHighlightingTokenWriter.cs index 66fdacbe6..cbf5861f5 100644 --- a/ILSpy/Languages/CSharpHighlightingTokenWriter.cs +++ b/ILSpy/Languages/CSharpHighlightingTokenWriter.cs @@ -318,8 +318,14 @@ namespace ICSharpCode.ILSpy public override void WriteIdentifier(Identifier identifier) { HighlightingColor color = null; - if (identifier.Name == "value" && identifier.Ancestors.OfType().FirstOrDefault() is Accessor accessor && accessor.Role != PropertyDeclaration.GetterRole) + if (identifier.Name == "value" + && identifier.Parent?.GetResolveResult() is ILVariableResolveResult rr + && rr.Variable.Kind == Decompiler.IL.VariableKind.Parameter + && identifier.Ancestors.OfType().FirstOrDefault() is Accessor accessor + && accessor.Role != PropertyDeclaration.GetterRole) + { color = valueKeywordColor; + } if ((identifier.Name == "dynamic" || identifier.Name == "var") && identifier.Parent is AstType) color = queryKeywordsColor; switch (GetCurrentDefinition()) {