Skip to content

Commit f668115

Browse files
committed
Correct wrong assumption about possible member attribute positions
Apparently, they always have to be on the first line after the start of the member.
1 parent ff6ba2e commit f668115

File tree

4 files changed

+65
-11
lines changed

4 files changed

+65
-11
lines changed

Rubberduck.Parsing/ParserRuleContextExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ public static bool ContainsTokenIndex(this ParserRuleContext context, int tokenI
198198
public static TContext GetDescendent<TContext>(this ParserRuleContext context) where TContext : ParserRuleContext
199199
{
200200
var descendents = GetDescendents<TContext>(context);
201-
return descendents.FirstOrDefault();
201+
return descendents.OrderBy(descendent => descendent.Start.TokenIndex).FirstOrDefault();
202202
}
203203

204204
/// <summary>

Rubberduck.Parsing/VBA/AttributesUpdater.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,18 @@ public void AddAttribute(IRewriteSession rewriteSession, Declaration declaration
7474
}
7575
else
7676
{
77-
var codeToInsert = $"{Environment.NewLine}Attribute {attribute} ={AttributeValuesText(values)}";
78-
rewriter.InsertAfter(declaration.AttributesPassContext.Stop.TokenIndex, codeToInsert);
77+
ParserRuleContext attributesContext = declaration.AttributesPassContext;
78+
var firstEndOfLineInMember = attributesContext.GetDescendent<VBAParser.EndOfLineContext>();
79+
if (firstEndOfLineInMember == null)
80+
{
81+
var codeToInsert = $"{Environment.NewLine}Attribute {attribute} ={AttributeValuesText(values)}";
82+
rewriter.InsertAfter(declaration.AttributesPassContext.Stop.TokenIndex, codeToInsert);
83+
}
84+
else
85+
{
86+
var codeToInsert = $"Attribute {attribute} ={AttributeValuesText(values)}{Environment.NewLine}";
87+
rewriter.InsertAfter(firstEndOfLineInMember.Stop.TokenIndex, codeToInsert);
88+
}
7989
}
8090
}
8191

RubberduckTests/PostProcessing/AttributesUpdaterTests.cs

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public class AttributesUpdaterTests
1414
{
1515
[Test]
1616
[Category("AttributesUpdater")]
17-
public void AddAttributeAddsMemberAttributeBelowMember()
17+
public void AddAttributeAddsMemberAttributeBelowFirstLineOfMember()
1818
{
1919
const string inputCode =
2020
@"VERSION 1.0 CLASS
@@ -36,9 +36,9 @@ End Sub
3636
Attribute VB_Name = ""ClassKeys""
3737
Attribute VB_GlobalNameSpace = False
3838
Public Sub Foo(bar As String)
39+
Attribute Foo.VB_Description = ""The MyFunc Description""
3940
bar = vbNullString
4041
End Sub
41-
Attribute Foo.VB_Description = ""The MyFunc Description""
4242
";
4343
var attributeToAdd = "Foo.VB_Description";
4444
var attributeValues = new List<string> {"\"The MyFunc Description\""};
@@ -60,6 +60,50 @@ End Sub
6060
Assert.AreEqual(expectedCode, actualCode);
6161
}
6262

63+
[Test]
64+
[Category("AttributesUpdater")]
65+
public void AddAttributeAddsMemberAttributeBelowOneLineMember()
66+
{
67+
const string inputCode =
68+
@"VERSION 1.0 CLASS
69+
BEGIN
70+
MultiUse = -1 'True
71+
END
72+
Attribute VB_Name = ""ClassKeys""
73+
Attribute VB_GlobalNameSpace = False
74+
Public Sub Foo(bar As String) : bar = vbNullString : End Sub
75+
";
76+
77+
const string expectedCode =
78+
@"VERSION 1.0 CLASS
79+
BEGIN
80+
MultiUse = -1 'True
81+
END
82+
Attribute VB_Name = ""ClassKeys""
83+
Attribute VB_GlobalNameSpace = False
84+
Public Sub Foo(bar As String) : bar = vbNullString : End Sub
85+
Attribute Foo.VB_Description = ""The MyFunc Description""
86+
";
87+
var attributeToAdd = "Foo.VB_Description";
88+
var attributeValues = new List<string> { "\"The MyFunc Description\"" };
89+
90+
string actualCode;
91+
var (component, rewriteSession, state) = TestSetup(inputCode);
92+
using (state)
93+
{
94+
var fooDeclaration = state.DeclarationFinder
95+
.UserDeclarations(DeclarationType.Procedure)
96+
.First(decl => decl.IdentifierName == "Foo");
97+
var attributesUpdater = new AttributesUpdater(state);
98+
99+
attributesUpdater.AddAttribute(rewriteSession, fooDeclaration, attributeToAdd, attributeValues);
100+
rewriteSession.TryRewrite();
101+
102+
actualCode = component.CodeModule.Content();
103+
}
104+
Assert.AreEqual(expectedCode, actualCode);
105+
}
106+
63107
[Test]
64108
[Category("AttributesUpdater")]
65109
public void MultipleAddAttributeWorkForMembers()
@@ -84,10 +128,10 @@ End Sub
84128
Attribute VB_Name = ""ClassKeys""
85129
Attribute VB_GlobalNameSpace = False
86130
Public Sub Foo(bar As String)
87-
bar = vbNullString
88-
End Sub
89131
Attribute Foo.VB_Description = ""The MyFunc Description""
90132
Attribute Foo.VB_HelpID = 2
133+
bar = vbNullString
134+
End Sub
91135
";
92136
var firstAttributeToAdd = "Foo.VB_Description";
93137
var firstAttributeValues = new List<string> { "\"The MyFunc Description\"" };

RubberduckTests/QuickFixes/AddMissingAttributeQuickFixTests.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ Public Sub Foo()
4444
const string expectedCode =
4545
@"'@MemberAttribute VB_Description, ""Desc""
4646
Public Sub Foo()
47+
Attribute Foo.VB_Description = ""Desc""
4748
Const const1 As Integer = 9
48-
End Sub
49-
Attribute Foo.VB_Description = ""Desc""";
49+
End Sub";
5050

5151
var actualCode = ApplyQuickFixToFirstInspectionResult(inputCode, state => new MissingAttributeInspection(state), CodeKind.AttributesCode);
5252
Assert.AreEqual(expectedCode, actualCode);
@@ -86,9 +86,9 @@ Public Sub Foo()
8686
const string expectedCode =
8787
@"'@MemberAttribute VB_Ext_Key, ""Key"", ""Value""
8888
Public Sub Foo()
89+
Attribute Foo.VB_Ext_Key = ""Key"", ""Value""
8990
Const const1 As Integer = 9
90-
End Sub
91-
Attribute Foo.VB_Ext_Key = ""Key"", ""Value""";
91+
End Sub";
9292

9393
var actualCode = ApplyQuickFixToFirstInspectionResult(inputCode, state => new MissingAttributeInspection(state), CodeKind.AttributesCode);
9494
Assert.AreEqual(expectedCode, actualCode);

0 commit comments

Comments
 (0)