From 7d5f1e0885bd8e091b42f248374b0f03677d698e Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Wed, 25 Jul 2012 21:05:27 +0200 Subject: [PATCH 1/9] Make CecilResolvedAttribute.DecodeBlob() more robust. Avoid exception when arguments types are unavailable and return ErrorResolveResult instead. --- ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs b/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs index 0eb735a759..2f445196db 100644 --- a/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs +++ b/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs @@ -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 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); } From 60607bcc657e4d88056059ecc111ec763e233c12 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Fri, 27 Jul 2012 20:56:33 +0200 Subject: [PATCH 2/9] Fix icsharpcode/NRefactory#86: method declaration with attributes fails to resolve since 2926e24. --- .../Resolver/ResolveVisitor.cs | 13 +++--- .../TypeSystem/TypeSystemConvertVisitor.cs | 11 +++-- .../CSharp/Resolver/MethodTests.cs | 41 ++++++++++++++++--- 3 files changed, 50 insertions(+), 15 deletions(-) diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs b/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs index bf8331d7d8..8f428e1494 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs @@ -659,7 +659,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 +676,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 +778,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 +841,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 +897,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 +1020,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(); diff --git a/ICSharpCode.NRefactory.CSharp/TypeSystem/TypeSystemConvertVisitor.cs b/ICSharpCode.NRefactory.CSharp/TypeSystem/TypeSystemConvertVisitor.cs index 6da26cfc81..29de611ec5 100644 --- a/ICSharpCode.NRefactory.CSharp/TypeSystem/TypeSystemConvertVisitor.cs +++ b/ICSharpCode.NRefactory.CSharp/TypeSystem/TypeSystemConvertVisitor.cs @@ -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 { 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) diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/MethodTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/MethodTests.cs index eb997bcac5..0e26185351 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/MethodTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/MethodTests.cs @@ -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(code); + Assert.AreEqual("TestClass.M", mrr.Member.FullName); + } + [Test] public void ParameterIdentityInNormalMethod() { From 0f82920267d7fefbb5085a3af6fdb2ee84362c36 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 28 Jul 2012 12:01:20 +0200 Subject: [PATCH 3/9] GenerateProperty: do not propose to generate a setter if the field is readonly. --- .../CodeActions/GeneratePropertyAction.cs | 4 +-- .../CodeActions/ContextActionTestBase.cs | 6 +++- .../CodeActions/GeneratePropertyTests.cs | 28 ++++++++++++++++++- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/GeneratePropertyAction.cs b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/GeneratePropertyAction.cs index 3f40e01725..291b507f75 100644 --- a/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/GeneratePropertyAction.cs +++ b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/GeneratePropertyAction.cs @@ -1,4 +1,4 @@ -// +// // GenerateProperty.cs // // Author: @@ -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; diff --git a/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ContextActionTestBase.cs b/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ContextActionTestBase.cs index a094c3c002..409542ff94 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ContextActionTestBase.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ContextActionTestBase.cs @@ -84,7 +84,11 @@ namespace ICSharpCode.NRefactory.CSharp.CodeActions protected static void TestWrongContext (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) diff --git a/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/GeneratePropertyTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/GeneratePropertyTests.cs index 98de6781c2..509fac1bd9 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/GeneratePropertyTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/GeneratePropertyTests.cs @@ -1,4 +1,4 @@ -// +// // GeneratePropertyTests.cs // // Author: @@ -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 + + "}" + ); + } } } \ No newline at end of file From 3f782ce21cb6ed0524519899444d07165db5fa5c Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 28 Jul 2012 12:40:54 +0200 Subject: [PATCH 4/9] Add ITypeDefinition.GetInterfaceImplementation(). --- .../ICSharpCode.NRefactory.csproj | 1 + .../TypeSystem/IAttribute.cs | 1 - ICSharpCode.NRefactory/TypeSystem/IType.cs | 1 - .../TypeSystem/ITypeDefinition.cs | 20 +++ .../DefaultResolvedTypeDefinition.cs | 41 +++++- .../Utils/MultiDictionary.cs | 130 ++++++++++++++++++ 6 files changed, 191 insertions(+), 3 deletions(-) create mode 100644 ICSharpCode.NRefactory/Utils/MultiDictionary.cs diff --git a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj index f595fc990f..e33e444dae 100644 --- a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj +++ b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj @@ -219,6 +219,7 @@ + diff --git a/ICSharpCode.NRefactory/TypeSystem/IAttribute.cs b/ICSharpCode.NRefactory/TypeSystem/IAttribute.cs index ef9adf7f48..26425e2f43 100644 --- a/ICSharpCode.NRefactory/TypeSystem/IAttribute.cs +++ b/ICSharpCode.NRefactory/TypeSystem/IAttribute.cs @@ -18,7 +18,6 @@ using System; using System.Collections.Generic; -using System.Diagnostics.Contracts; using ICSharpCode.NRefactory.Semantics; diff --git a/ICSharpCode.NRefactory/TypeSystem/IType.cs b/ICSharpCode.NRefactory/TypeSystem/IType.cs index a6a4892f4c..2d010e22b9 100644 --- a/ICSharpCode.NRefactory/TypeSystem/IType.cs +++ b/ICSharpCode.NRefactory/TypeSystem/IType.cs @@ -18,7 +18,6 @@ using System; using System.Collections.Generic; -using System.Diagnostics.Contracts; namespace ICSharpCode.NRefactory.TypeSystem { diff --git a/ICSharpCode.NRefactory/TypeSystem/ITypeDefinition.cs b/ICSharpCode.NRefactory/TypeSystem/ITypeDefinition.cs index 1438505d8b..7cd98c8d23 100644 --- a/ICSharpCode.NRefactory/TypeSystem/ITypeDefinition.cs +++ b/ICSharpCode.NRefactory/TypeSystem/ITypeDefinition.cs @@ -130,5 +130,25 @@ namespace ICSharpCode.NRefactory.TypeSystem /// /// This property is used to speed up the search for extension methods. bool HasExtensionMethods { get; } + + /// + /// Determines how this type is implementing the specified interface member. + /// + /// + /// The method on this type that implements the interface member; + /// or null if the type does not implement the interface. + /// + IMember GetInterfaceImplementation(IMember interfaceMember); + + /// + /// Determines how this type is implementing the specified interface members. + /// + /// + /// 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. + /// + IList GetInterfaceImplementation(IList interfaceMembers); } } diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs index 4ea28dbe69..902d1c9094 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs @@ -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 } #endregion + #region GetInterfaceImplementation + public IMember GetInterfaceImplementation(IMember interfaceMember) + { + return GetInterfaceImplementation(new[] { interfaceMember })[0]; + } + + public IList GetInterfaceImplementation(IList 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(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; diff --git a/ICSharpCode.NRefactory/Utils/MultiDictionary.cs b/ICSharpCode.NRefactory/Utils/MultiDictionary.cs new file mode 100644 index 0000000000..25361a7a08 --- /dev/null +++ b/ICSharpCode.NRefactory/Utils/MultiDictionary.cs @@ -0,0 +1,130 @@ +// 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 +{ + /// + /// A dictionary that allows multiple pairs with the same key. + /// + public class MultiDictionary : ILookup + { + readonly Dictionary> dict; + + public MultiDictionary() + { + dict = new Dictionary>(); + } + + public MultiDictionary(IEqualityComparer comparer) + { + dict = new Dictionary>(comparer); + } + + public void Add(TKey key, TValue value) + { + List valueList; + if (!dict.TryGetValue(key, out valueList)) { + valueList = new List(); + dict.Add(key, valueList); + } + valueList.Add(value); + } + + public bool Remove(TKey key, TValue value) + { + List 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(); + } + + public IList this[TKey key] { + get { + List list; + if (dict.TryGetValue(key, out list)) + return list; + else + return EmptyList.Instance; + } + } + + public int Count { + get { return dict.Count; } + } + + IEnumerable ILookup.this[TKey key] { + get { return this[key]; } + } + + bool ILookup.Contains(TKey key) + { + return dict.ContainsKey(key); + } + + public IEnumerator> 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 + { + readonly TKey key; + readonly List values; + + public Grouping(TKey key, List values) + { + this.key = key; + this.values = values; + } + + public TKey Key { + get { return key; } + } + + public IEnumerator GetEnumerator() + { + return values.GetEnumerator(); + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return values.GetEnumerator(); + } + } + } +} From 8728c08c6859e4891832e96c770e0d59bf8587d7 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 28 Jul 2012 13:33:09 +0200 Subject: [PATCH 5/9] Add project configurations for .NET 4.5. --- ...pCode.NRefactory.CSharp.AstVerifier.csproj | 116 +++++---- .../ICSharpCode.NRefactory.CSharp.csproj | 21 ++ .../OutputVisitor/CSharpOutputVisitor.cs | 1 + ...arpCode.NRefactory.ConsistencyCheck.csproj | 18 ++ .../ICSharpCode.NRefactory.Demo.csproj | 30 +++ .../ICSharpCode.NRefactory.GtkDemo.csproj | 224 ++++++++++-------- .../ICSharpCode.NRefactory.Tests.csproj | 42 ++++ .../ICSharpCode.NRefactory.Xml.csproj | 22 ++ .../ICSharpCode.NRefactory.csproj | 22 ++ .../Utils/MultiDictionary.cs | 4 + NRefactory.sln | 78 +++++- 11 files changed, 427 insertions(+), 151 deletions(-) diff --git a/ICSharpCode.NRefactory.CSharp.AstVerifier/ICSharpCode.NRefactory.CSharp.AstVerifier.csproj b/ICSharpCode.NRefactory.CSharp.AstVerifier/ICSharpCode.NRefactory.CSharp.AstVerifier.csproj index bd6e1e8230..b75da9acdb 100644 --- a/ICSharpCode.NRefactory.CSharp.AstVerifier/ICSharpCode.NRefactory.CSharp.AstVerifier.csproj +++ b/ICSharpCode.NRefactory.CSharp.AstVerifier/ICSharpCode.NRefactory.CSharp.AstVerifier.csproj @@ -1,49 +1,69 @@ - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {961DADFA-7CE6-429F-BC22-47630D6DB826} - Exe - ICSharpCode.NRefactory.CSharp.AstVerifier - AstVerifier - - - true - full - false - bin\Debug - DEBUG; - prompt - 4 - true - - - none - false - bin\Release - prompt - 4 - true - - - - - - - - - - - - {53DCA265-3C3C-42F9-B647-F72BA678122B} - ICSharpCode.NRefactory.CSharp - - - {3B2A5653-EC97-4001-BB9B-D90F1AF2C371} - ICSharpCode.NRefactory - - + + + + Debug + AnyCPU + 10.0.0 + 2.0 + {961DADFA-7CE6-429F-BC22-47630D6DB826} + Exe + ICSharpCode.NRefactory.CSharp.AstVerifier + AstVerifier + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + true + + + none + false + bin\Release + prompt + 4 + true + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + true + v4.5 + + + none + false + bin\Release + prompt + 4 + true + v4.5 + + + + + + + + + + + + {53DCA265-3C3C-42F9-B647-F72BA678122B} + ICSharpCode.NRefactory.CSharp + + + {3B2A5653-EC97-4001-BB9B-D90F1AF2C371} + ICSharpCode.NRefactory + + \ No newline at end of file diff --git a/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj b/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj index c07d4a6454..8b6215e4f0 100644 --- a/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj +++ b/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj @@ -47,6 +47,27 @@ full True + + ..\ICSharpCode.NRefactory\bin\Debug\ + False + False + DEBUG;TRACE;FULL_AST;NET45 + v4.5 + + + full + True + + + ..\ICSharpCode.NRefactory\bin\Release\ + True + False + TRACE;FULL_AST;NET45 + v4.5 + + + PdbOnly + diff --git a/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs b/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs index 23932e802c..7c7900b451 100644 --- a/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs +++ b/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs @@ -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); diff --git a/ICSharpCode.NRefactory.ConsistencyCheck/ICSharpCode.NRefactory.ConsistencyCheck.csproj b/ICSharpCode.NRefactory.ConsistencyCheck/ICSharpCode.NRefactory.ConsistencyCheck.csproj index 0abf5100f1..3ac8752d0f 100644 --- a/ICSharpCode.NRefactory.ConsistencyCheck/ICSharpCode.NRefactory.ConsistencyCheck.csproj +++ b/ICSharpCode.NRefactory.ConsistencyCheck/ICSharpCode.NRefactory.ConsistencyCheck.csproj @@ -38,6 +38,24 @@ AnyCPU + + bin\Debug\ + true + Full + False + True + DEBUG;TRACE + v4.5 + + + bin\Release\ + False + None + True + False + TRACE + v4.5 + diff --git a/ICSharpCode.NRefactory.Demo/ICSharpCode.NRefactory.Demo.csproj b/ICSharpCode.NRefactory.Demo/ICSharpCode.NRefactory.Demo.csproj index c302a56ae0..87e5417f75 100644 --- a/ICSharpCode.NRefactory.Demo/ICSharpCode.NRefactory.Demo.csproj +++ b/ICSharpCode.NRefactory.Demo/ICSharpCode.NRefactory.Demo.csproj @@ -45,6 +45,36 @@ 4 + + bin\Debug\ + True + Full + False + True + DEBUG;TRACE + v4.5 + + + 4 + + + 4 + + + bin\Release\ + False + None + True + False + TRACE + v4.5 + + + 4 + + + 4 + diff --git a/ICSharpCode.NRefactory.GtkDemo/ICSharpCode.NRefactory.GtkDemo.csproj b/ICSharpCode.NRefactory.GtkDemo/ICSharpCode.NRefactory.GtkDemo.csproj index a772c27252..6e576fa169 100644 --- a/ICSharpCode.NRefactory.GtkDemo/ICSharpCode.NRefactory.GtkDemo.csproj +++ b/ICSharpCode.NRefactory.GtkDemo/ICSharpCode.NRefactory.GtkDemo.csproj @@ -1,103 +1,123 @@ - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {A7EEF7F8-238F-459D-95A9-96467539641D} - WinExe - ICSharpCode.NRefactory.GtkDemo - ICSharpCode.NRefactory.GtkDemo - - - true - full - false - bin\Debug - DEBUG; - prompt - 4 - false - - - none - false - bin\Release - prompt - 4 - false - - - - - gtk-sharp-2.0 - - - gtk-sharp-2.0 - - - glib-sharp-2.0 - - - glade-sharp-2.0 - - - gtk-sharp-2.0 - - - gtk-sharp-2.0 - - - - - - - gui.stetic - - - comment.png - - - class.png - - - expression.png - - - token.png - - - statement.png - - - namespace.png - - - - - - - - - - - - - {3B2A5653-EC97-4001-BB9B-D90F1AF2C371} - ICSharpCode.NRefactory - - - {53DCA265-3C3C-42F9-B647-F72BA678122B} - ICSharpCode.NRefactory.CSharp - - - - - PreserveNewest - - - - - + + + + Debug + AnyCPU + 10.0.0 + 2.0 + {A7EEF7F8-238F-459D-95A9-96467539641D} + WinExe + ICSharpCode.NRefactory.GtkDemo + ICSharpCode.NRefactory.GtkDemo + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + false + + + none + false + bin\Release + prompt + 4 + false + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + false + v4.5 + + + none + false + bin\Release + prompt + 4 + false + v4.5 + + + + + gtk-sharp-2.0 + + + gtk-sharp-2.0 + + + glib-sharp-2.0 + + + glade-sharp-2.0 + + + gtk-sharp-2.0 + + + gtk-sharp-2.0 + + + + + + + gui.stetic + + + comment.png + + + class.png + + + expression.png + + + token.png + + + statement.png + + + namespace.png + + + + + + + + + + + + + {3B2A5653-EC97-4001-BB9B-D90F1AF2C371} + ICSharpCode.NRefactory + + + {53DCA265-3C3C-42F9-B647-F72BA678122B} + ICSharpCode.NRefactory.CSharp + + + + + PreserveNewest + + + + + \ No newline at end of file diff --git a/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj b/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj index 130d7ba4c5..e84ed8b024 100644 --- a/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj +++ b/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj @@ -65,6 +65,48 @@ x86 + + bin\Debug\ + true + Full + False + True + DEBUG;TRACE;NET45 + v4.5 + + + ..\ICSharpCode.NRefactory\bin\Debug\ + False + Auto + 4194304 + 4096 + AnyCPU + + + ..\ICSharpCode.NRefactory\bin\Debug\ + x86 + + + bin\Release\ + False + None + True + False + TRACE;NET45 + v4.5 + + + ..\ICSharpCode.NRefactory\bin\Release\ + False + Auto + 4194304 + 4096 + AnyCPU + + + ..\ICSharpCode.NRefactory\bin\Release\ + x86 + diff --git a/ICSharpCode.NRefactory.Xml/ICSharpCode.NRefactory.Xml.csproj b/ICSharpCode.NRefactory.Xml/ICSharpCode.NRefactory.Xml.csproj index e98d2e0a8d..603112ad9c 100644 --- a/ICSharpCode.NRefactory.Xml/ICSharpCode.NRefactory.Xml.csproj +++ b/ICSharpCode.NRefactory.Xml/ICSharpCode.NRefactory.Xml.csproj @@ -47,6 +47,28 @@ PdbOnly false + + ..\ICSharpCode.NRefactory\bin\Debug\ + False + True + DEBUG;TRACE;NET45 + v4.5 + + + full + true + + + ..\ICSharpCode.NRefactory\bin\Release\ + True + False + TRACE;NET45 + v4.5 + + + PdbOnly + false + diff --git a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj index e33e444dae..6df2122ae5 100644 --- a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj +++ b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj @@ -50,6 +50,28 @@ none + + bin\Debug\ + False + DEBUG;TRACE;NET45 + True + Project + v4.5 + + + full + True + + + bin\Release\ + True + TRACE;NET45 + False + v4.5 + + + none + diff --git a/ICSharpCode.NRefactory/Utils/MultiDictionary.cs b/ICSharpCode.NRefactory/Utils/MultiDictionary.cs index 25361a7a08..496b66ba9e 100644 --- a/ICSharpCode.NRefactory/Utils/MultiDictionary.cs +++ b/ICSharpCode.NRefactory/Utils/MultiDictionary.cs @@ -67,7 +67,11 @@ namespace ICSharpCode.NRefactory.Utils dict.Clear(); } + #if NET45 + public IReadOnlyList this[TKey key] { + #else public IList this[TKey key] { + #endif get { List list; if (dict.TryGetValue(key, out list)) diff --git a/NRefactory.sln b/NRefactory.sln index 94451e3646..cc76ba1a42 100644 --- a/NRefactory.sln +++ b/NRefactory.sln @@ -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 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 {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 From 6bd0bfc5a832728d831b3d6503e4ca19f58f735c Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 28 Jul 2012 21:22:16 +0200 Subject: [PATCH 6/9] Add failing unit test for CompilationUnit.ConditionalSymbols. --- ICSharpCode.NRefactory.CSharp/Resolver/Log.cs | 5 ----- .../PreprocessorDirectiveTests.cs | 19 +++++++++++++++++++ ICSharpCode.NRefactory/Utils/LazyInit.cs | 3 --- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/Log.cs b/ICSharpCode.NRefactory.CSharp/Resolver/Log.cs index a167cd6999..9e85f451f0 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/Log.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/Log.cs @@ -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 { diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/PreprocessorDirectiveTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/PreprocessorDirectiveTests.cs index 28b522fc6c..bc91fe3de6 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/PreprocessorDirectiveTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/PreprocessorDirectiveTests.cs @@ -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); + } } } diff --git a/ICSharpCode.NRefactory/Utils/LazyInit.cs b/ICSharpCode.NRefactory/Utils/LazyInit.cs index 94c08bbea4..467a8daa35 100644 --- a/ICSharpCode.NRefactory/Utils/LazyInit.cs +++ b/ICSharpCode.NRefactory/Utils/LazyInit.cs @@ -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 { From d6b4420940dca8da89a4029689ab165a2e9796d2 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sun, 29 Jul 2012 10:28:36 +0200 Subject: [PATCH 7/9] Introduced NamedArgumentResolveResult. --- .../Resolver/CSharpAstResolver.cs | 2 +- .../Resolver/CSharpInvocationResolveResult.cs | 11 +- .../Resolver/CSharpResolver.cs | 2 +- .../Resolver/OverloadResolution.cs | 55 +++++-- .../Resolver/ResolveVisitor.cs | 135 +++++++++++------- .../CSharp/Resolver/InvocationTests.cs | 70 +++++++++ .../ICSharpCode.NRefactory.csproj | 1 + .../Semantics/NamedArgumentResolveResult.cs | 81 +++++++++++ 8 files changed, 285 insertions(+), 72 deletions(-) create mode 100644 ICSharpCode.NRefactory/Semantics/NamedArgumentResolveResult.cs diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/CSharpAstResolver.cs b/ICSharpCode.NRefactory.CSharp/Resolver/CSharpAstResolver.cs index 234e17f261..858abf7da2 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/CSharpAstResolver.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/CSharpAstResolver.cs @@ -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); } } } diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/CSharpInvocationResolveResult.cs b/ICSharpCode.NRefactory.CSharp/Resolver/CSharpInvocationResolveResult.cs index 401365a5c9..e1e34a2606 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/CSharpInvocationResolveResult.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/CSharpInvocationResolveResult.cs @@ -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) diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/CSharpResolver.cs b/ICSharpCode.NRefactory.CSharp/Resolver/CSharpResolver.cs index 20d34852fb..bd429df0d4 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/CSharpResolver.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/CSharpResolver.cs @@ -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()); diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/OverloadResolution.cs b/ICSharpCode.NRefactory.CSharp/Resolver/OverloadResolution.cs index d7f8da21a9..ba407c76fa 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/OverloadResolution.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/OverloadResolution.cs @@ -781,15 +781,35 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver return null; } + /// + /// 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 if an implicit conversion is being applied + /// to them when calling the method. + /// public IList GetArgumentsWithConversions() { if (bestCandidate == null) return arguments; else - return GetArgumentsWithConversions(null); + return GetArgumentsWithConversions(null, null); + } + + /// + /// 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 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 . + /// + public IList GetArgumentsWithConversionsAndNames() + { + if (bestCandidate == null) + return arguments; + else + return GetArgumentsWithConversions(null, GetBestCandidateWithSubstitutedTypeArguments()); } - IList GetArgumentsWithConversions(ResolveResult targetResolveResult) + IList GetArgumentsWithConversions(ResolveResult targetResolveResult, IParameterizedMember bestCandidateForNamedArguments) { var conversions = this.ArgumentConversions; ResolveResult[] args = new ResolveResult[arguments.Length]; @@ -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 return new CSharpInvocationResolveResult( this.IsExtensionMethodInvocation ? new TypeResolveResult(member.DeclaringType) : targetResolveResult, member, - GetArgumentsWithConversions(targetResolveResult), + GetArgumentsWithConversions(targetResolveResult, member), this.BestCandidateErrors, this.IsExtensionMethodInvocation, this.BestCandidateIsExpandedForm, diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs b/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs index 8f428e1494..ee1aa5b64f 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs @@ -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 } } + void MarkUnknownNamedArguments(IEnumerable arguments) + { + foreach (var nae in arguments.OfType()) { + StoreCurrentState(nae); + StoreResult(nae, new NamedArgumentResolveResult(nae.Name, resolveResultCache[nae.Expression])); + } + } + void ProcessConversionsInInvocation(Expression target, IEnumerable 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 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 @@ -1398,7 +1414,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver ResolveResult IAstVisitor.VisitIndexerExpression(IndexerExpression indexerExpression) { - if (resolverEnabled) { + if (resolverEnabled || NeedsResolvingDueToNamedArguments(indexerExpression)) { Expression target = indexerExpression.Target; ResolveResult targetResult = Resolve(target); string[] argumentNames; @@ -1406,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); @@ -1437,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 @@ -1477,48 +1498,44 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver ResolveResult IAstVisitor.VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression) { - if (resolverEnabled || !objectCreateExpression.Initializer.IsNull) { - var typeResolveResult = Resolve(objectCreateExpression.Type); - if (typeResolveResult.IsError) { - ScanChildren (objectCreateExpression); - return typeResolveResult; - } - IType type = typeResolveResult.Type; - - List initializerStatements = null; - var initializer = objectCreateExpression.Initializer; - if (!initializer.IsNull) { - initializerStatements = new List(); - 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; - } + var typeResolveResult = Resolve(objectCreateExpression.Type); + if (typeResolveResult.IsError) { + ScanChildren (objectCreateExpression); + return typeResolveResult; + } + IType type = typeResolveResult.Type; + + List initializerStatements = null; + var initializer = objectCreateExpression.Initializer; + if (!initializer.IsNull) { + initializerStatements = new List(); + 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) { + 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; } } @@ -1701,6 +1718,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver return result; } + /// + /// Gets and resolves the arguments; unpacking any NamedArgumentExpressions. + /// + /// + /// 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(). + /// ResolveResult[] GetArguments(IEnumerable argumentExpressions, out string[] argumentNames) { argumentNames = null; @@ -1722,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; @@ -1840,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 { @@ -3779,10 +3814,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver #region Constructor Initializer ResolveResult IAstVisitor.VisitConstructorInitializer(ConstructorInitializer constructorInitializer) { - if (!resolverEnabled) { - ScanChildren(constructorInitializer); - return null; - } ResolveResult target; if (constructorInitializer.ConstructorInitializerType == ConstructorInitializerType.Base) { target = resolver.ResolveBaseReference(); diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/InvocationTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/InvocationTests.cs index 6dd3b80762..6f1946dd3a 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/InvocationTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/InvocationTests.cs @@ -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(program); + Assert.IsInstanceOf(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(program); + Assert.IsInstanceOf(rr.Arguments.Single()); + var narr = (NamedArgumentResolveResult)rr.Arguments.Single(); + Assert.IsInstanceOf(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(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(program); + Assert.IsInstanceOf(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(program); + Assert.IsInstanceOf(narr.Argument); + Assert.AreEqual("x", narr.ParameterName); + Assert.IsNull(narr.Parameter); + } } } diff --git a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj index 6df2122ae5..7213b78cdb 100644 --- a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj +++ b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj @@ -120,6 +120,7 @@ + diff --git a/ICSharpCode.NRefactory/Semantics/NamedArgumentResolveResult.cs b/ICSharpCode.NRefactory/Semantics/NamedArgumentResolveResult.cs new file mode 100644 index 0000000000..7a69afebf8 --- /dev/null +++ b/ICSharpCode.NRefactory/Semantics/NamedArgumentResolveResult.cs @@ -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 +{ + /// + /// Represents a named argument. + /// + public class NamedArgumentResolveResult : ResolveResult + { + /// + /// Gets the member to which the parameter belongs. + /// This field can be null. + /// + public readonly IParameterizedMember Member; + + /// + /// Gets the parameter. + /// This field can be null. + /// + public readonly IParameter Parameter; + + /// + /// Gets the parameter name. + /// + public readonly string ParameterName; + + /// + /// Gets the argument passed to the parameter. + /// + 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 GetChildResults() + { + return new [] { Argument }; + } + } +} From fb4436499ea17bf6e83009b0574edbd57612fcf2 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sun, 29 Jul 2012 10:35:18 +0200 Subject: [PATCH 8/9] Remove outdated code contracts. --- .../TypeSystem/IAttribute.cs | 45 ------------------- .../TypeSystem/IFreezable.cs | 20 --------- .../TypeSystem/IInterningProvider.cs | 22 --------- .../TypeSystem/ISupportsInterning.cs | 26 ----------- .../TypeSystem/ITypeReference.cs | 18 -------- .../TypeSystem/IVariable.cs | 36 --------------- 6 files changed, 167 deletions(-) diff --git a/ICSharpCode.NRefactory/TypeSystem/IAttribute.cs b/ICSharpCode.NRefactory/TypeSystem/IAttribute.cs index 26425e2f43..184de64784 100644 --- a/ICSharpCode.NRefactory/TypeSystem/IAttribute.cs +++ b/ICSharpCode.NRefactory/TypeSystem/IAttribute.cs @@ -26,9 +26,6 @@ namespace ICSharpCode.NRefactory.TypeSystem /// /// Represents an unresolved attribute. /// - #if WITH_CONTRACTS - [ContractClass(typeof(IUnresolvedAttributeContract))] - #endif [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1711:IdentifiersShouldNotHaveIncorrectSuffix")] public interface IUnresolvedAttribute { @@ -37,8 +34,6 @@ namespace ICSharpCode.NRefactory.TypeSystem /// DomRegion Region { get; } - //ITypeReference AttributeType { get; } - /// /// Resolves the attribute. /// @@ -48,9 +43,6 @@ namespace ICSharpCode.NRefactory.TypeSystem /// /// Represents an attribute. /// - #if WITH_CONTRACTS - [ContractClass(typeof(IAttributeContract))] - #endif [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1711:IdentifiersShouldNotHaveIncorrectSuffix")] public interface IAttribute { @@ -80,41 +72,4 @@ namespace ICSharpCode.NRefactory.TypeSystem /// IList> 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() != null); - return null; - } - } - - IList IAttribute.GetPositionalArguments(ITypeResolveContext context) - { - Contract.Requires(context != null); - Contract.Ensures(Contract.Result>() != null); - return null; - } - - IList> IAttribute.GetNamedArguments(ITypeResolveContext context) - { - Contract.Requires(context != null); - Contract.Ensures(Contract.Result>>() != null); - return null; - } - - IMethod IAttribute.ResolveConstructor(ITypeResolveContext context) - { - Contract.Requires(context != null); - return null; - } - } - #endif } diff --git a/ICSharpCode.NRefactory/TypeSystem/IFreezable.cs b/ICSharpCode.NRefactory/TypeSystem/IFreezable.cs index e0b63a28ad..050d09e099 100644 --- a/ICSharpCode.NRefactory/TypeSystem/IFreezable.cs +++ b/ICSharpCode.NRefactory/TypeSystem/IFreezable.cs @@ -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 { /// @@ -36,20 +32,4 @@ namespace ICSharpCode.NRefactory.TypeSystem /// 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 } diff --git a/ICSharpCode.NRefactory/TypeSystem/IInterningProvider.cs b/ICSharpCode.NRefactory/TypeSystem/IInterningProvider.cs index dc20e18ef8..89edd7f9f4 100644 --- a/ICSharpCode.NRefactory/TypeSystem/IInterningProvider.cs +++ b/ICSharpCode.NRefactory/TypeSystem/IInterningProvider.cs @@ -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 /// 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. /// - #if WITH_CONTRACTS - [ContractClass(typeof(IInterningProviderContract))] - #endif public interface IInterningProvider { /// @@ -55,22 +51,4 @@ namespace ICSharpCode.NRefactory.TypeSystem IList InternList(IList list) where T : class; } - - #if WITH_CONTRACTS - [ContractClassFor(typeof(IInterningProvider))] - abstract class IInterningProviderContract : IInterningProvider - { - T IInterningProvider.Intern(T obj) - { - Contract.Ensures((Contract.Result() == null) == (obj == null)); - return obj; - } - - IList IInterningProvider.InternList(IList list) - { - Contract.Ensures((Contract.Result>() == null) == (list == null)); - return list; - } - } - #endif } diff --git a/ICSharpCode.NRefactory/TypeSystem/ISupportsInterning.cs b/ICSharpCode.NRefactory/TypeSystem/ISupportsInterning.cs index 43573ade47..0832e33e90 100644 --- a/ICSharpCode.NRefactory/TypeSystem/ISupportsInterning.cs +++ b/ICSharpCode.NRefactory/TypeSystem/ISupportsInterning.cs @@ -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 /// Interface for TypeSystem objects that support interning. /// See for more information. /// - #if WITH_CONTRACTS - [ContractClass(typeof(ISupportsInterningContract))] - #endif public interface ISupportsInterning { /// @@ -46,25 +41,4 @@ namespace ICSharpCode.NRefactory.TypeSystem /// 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 } diff --git a/ICSharpCode.NRefactory/TypeSystem/ITypeReference.cs b/ICSharpCode.NRefactory/TypeSystem/ITypeReference.cs index efad8e983c..fc22826c37 100644 --- a/ICSharpCode.NRefactory/TypeSystem/ITypeReference.cs +++ b/ICSharpCode.NRefactory/TypeSystem/ITypeReference.cs @@ -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 /// Represents a reference to a type. /// Must be resolved before it can be used as type. /// - #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 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() != null); - return null; - } - } - #endif } \ No newline at end of file diff --git a/ICSharpCode.NRefactory/TypeSystem/IVariable.cs b/ICSharpCode.NRefactory/TypeSystem/IVariable.cs index e185247707..9e4d45835e 100644 --- a/ICSharpCode.NRefactory/TypeSystem/IVariable.cs +++ b/ICSharpCode.NRefactory/TypeSystem/IVariable.cs @@ -17,16 +17,12 @@ // DEALINGS IN THE SOFTWARE. using System; -using System.Diagnostics.Contracts; namespace ICSharpCode.NRefactory.TypeSystem { /// /// Represents a variable (name/type pair). /// - #if WITH_CONTRACTS - [ContractClass(typeof(IVariableContract))] - #endif public interface IVariable { /// @@ -55,36 +51,4 @@ namespace ICSharpCode.NRefactory.TypeSystem /// object ConstantValue { get; } } - - #if WITH_CONTRACTS - [ContractClassFor(typeof(IVariable))] - abstract class IVariableContract : IVariable - { - string IVariable.Name { - get { - Contract.Ensures(Contract.Result() != null); - return null; - } - } - - ITypeReference IVariable.Type { - get { - Contract.Ensures(Contract.Result() != null); - return null; - } - } - - bool IVariable.IsConst { - get { - IVariable @this = this; - Contract.Ensures(Contract.Result() == (@this.ConstantValue != null)); - return false; - } - } - - object IVariable.ConstantValue { - get { return null; } - } - } - #endif } From d4372bf9549c7890c76491cb94dde7a2097a4b8c Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sun, 29 Jul 2012 10:52:34 +0200 Subject: [PATCH 9/9] Add DefaultAttribute. --- .../ICSharpCode.NRefactory.csproj | 5 +- .../TypeSystem/CecilLoader.cs | 40 +------- .../Implementation/DefaultAttribute.cs | 97 +++++++++++++++++++ 3 files changed, 104 insertions(+), 38 deletions(-) create mode 100644 ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultAttribute.cs diff --git a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj index 7213b78cdb..50ec131c12 100644 --- a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj +++ b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj @@ -56,7 +56,7 @@ DEBUG;TRACE;NET45 True Project - v4.5 + v4.5 full @@ -67,7 +67,7 @@ True TRACE;NET45 False - v4.5 + v4.5 none @@ -161,6 +161,7 @@ + diff --git a/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs b/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs index 2f445196db..0f6c6d6741 100644 --- a/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs +++ b/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs @@ -1433,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); } } @@ -1480,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 PositionalArguments { get; internal set; } - - public IList> NamedArguments { get; internal set; } - } #endregion #endregion diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultAttribute.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultAttribute.cs new file mode 100644 index 0000000000..79df0167a6 --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultAttribute.cs @@ -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 +{ + /// + /// IAttribute implementation for already-resolved attributes. + /// + public class DefaultAttribute : IAttribute + { + readonly IType attributeType; + readonly IList positionalArguments; + readonly IList> namedArguments; + readonly DomRegion region; + volatile IMethod constructor; + + public DefaultAttribute(IType attributeType, IList positionalArguments = null, + IList> namedArguments = null, + DomRegion region = default(DomRegion)) + { + if (attributeType == null) + throw new ArgumentNullException("attributeType"); + this.attributeType = attributeType; + this.positionalArguments = positionalArguments ?? EmptyList.Instance; + this.namedArguments = namedArguments ?? EmptyList>.Instance; + this.region = region; + } + + public DefaultAttribute(IMethod constructor, IList positionalArguments = null, + IList> namedArguments = null, + DomRegion region = default(DomRegion)) + { + if (constructor == null) + throw new ArgumentNullException("constructor"); + this.constructor = constructor; + this.attributeType = constructor.DeclaringType; + this.positionalArguments = positionalArguments ?? EmptyList.Instance; + this.namedArguments = namedArguments ?? EmptyList>.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 PositionalArguments { + get { return positionalArguments; } + } + + public IList> NamedArguments { + get { return namedArguments; } + } + } +}