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() {