Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Line Numbers #3014

Merged
merged 22 commits into from
May 11, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
567ac41
Lexer adjustment for line numbers (nearly works)
MDoerner May 7, 2017
a8a87b5
Lexer version that works with all tests passing.
MDoerner May 8, 2017
5a161d3
Stop removing line numbers from the code
MDoerner May 8, 2017
b3c45be
Merge branch 'next' into LineNumberExperiments
MDoerner May 8, 2017
0f3e6ba
Removed tests that make no sense anymore.
MDoerner May 8, 2017
8ac4afa
Grammar changes towards having line numbers
MDoerner May 8, 2017
9e55bc3
Simplification of the grammar.
MDoerner May 9, 2017
e293930
Parser and lexer based on new grammar.
MDoerner May 9, 2017
66cd02b
Adapted the declaration resolver and fixed one test (grammar is broken)
MDoerner May 9, 2017
0141f71
fixed grammar. (Rewriters are broken.)
MDoerner May 9, 2017
dd4dce7
Fixed the rewriters.
MDoerner May 9, 2017
3b65fce
Small adjustment of the grammar and the declaration resolver.
MDoerner May 9, 2017
6e6af16
Fixed stupid bug introduced earlier.
MDoerner May 10, 2017
7a33b3b
Test to cover #2636 (fails)
MDoerner May 10, 2017
15de7ec
Fix to get the tests to pass.
MDoerner May 10, 2017
03a1dc2
Merge branch 'next' into MoreLineNumberExperiments
MDoerner May 10, 2017
0a457f2
Small grammar tweak.
MDoerner May 10, 2017
1359b21
Adapted last PR to make the tests pass.
MDoerner May 10, 2017
70f0f80
Fixed RemoveEmptyIfBlockQuickfix in case there are line labels.
MDoerner May 11, 2017
0fe4c63
Minor grammar tweak to cover a failing corner case
MDoerner May 11, 2017
eb21d61
Minor grammar simplification
MDoerner May 11, 2017
4f74f7a
Merge branch 'next' into MoreLineNumberExperiments
retailcoder May 11, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions Rubberduck.Inspections/Concrete/EmptyIfBlockInspection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,19 @@ private bool ContainsExecutableStatements(VBAParser.BlockContext block)
{
if (child is VBAParser.BlockStmtContext)
{
Debug.Assert(child.ChildCount == 1);
var blockStmt = (VBAParser.BlockStmtContext)child;
var mainBlockStmt = blockStmt.mainBlockStmt();

if(mainBlockStmt == null)
{
continue; //We have a lone line lable, which is not executable.
}

Debug.Assert(mainBlockStmt.ChildCount == 1);

// exclude variables and consts because they are not executable statements
if (child.GetChild(0) is VBAParser.VariableStmtContext ||
child.GetChild(0) is VBAParser.ConstStmtContext)
if (mainBlockStmt.GetChild(0) is VBAParser.VariableStmtContext ||
mainBlockStmt.GetChild(0) is VBAParser.ConstStmtContext)
{
continue;
}
Expand Down
20 changes: 17 additions & 3 deletions Rubberduck.Inspections/QuickFixes/RemoveEmptyIfBlockQuickFix.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ private void UpdateContext(VBAParser.IfStmtContext context, IModuleRewriter rewr

if (BlockHasDeclaration(context.block()))
{
rewriter.InsertBefore(context.Start.TokenIndex, context.block().GetText());
rewriter.InsertBefore(context.Start.TokenIndex, AdjustedBlockText(context.block()));
}

if (elseIfBlock != null)
Expand Down Expand Up @@ -86,7 +86,7 @@ private void UpdateContext(VBAParser.ElseIfBlockContext context, IModuleRewriter
{
if (BlockHasDeclaration(context.block()))
{
rewriter.InsertBefore(((VBAParser.IfStmtContext)context.Parent).Start.TokenIndex, context.block().GetText());
rewriter.InsertBefore(((VBAParser.IfStmtContext)context.Parent).Start.TokenIndex, AdjustedBlockText(context.block()));
}

rewriter.Remove(context);
Expand Down Expand Up @@ -159,8 +159,22 @@ private void UpdateCondition(ParserRuleContext condition, IModuleRewriter rewrit
}
}

private string AdjustedBlockText(VBAParser.BlockContext blockContext)
{
var blockText = blockContext.GetText();
if (FirstBlockStmntHasLabel(blockContext))
{
blockText = Environment.NewLine + blockText;
}

return blockText;
}

private bool BlockHasDeclaration(VBAParser.BlockContext block)
=> block.children?.Any(s => s is VBAParser.BlockStmtContext) ?? false;
=> block.blockStmt()?.Any() ?? false;

private bool FirstBlockStmntHasLabel(VBAParser.BlockContext block)
=> block.blockStmt()?.FirstOrDefault()?.statementLabelDefinition() != null;

public string Description(IInspectionResult result)
{
Expand Down
1 change: 1 addition & 0 deletions Rubberduck.Parsing/Grammar/VBALexer.g4
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

lexer grammar VBALexer;


ABS : A B S;
ANY : A N Y;
ARRAY : A R R A Y;
Expand Down
7,472 changes: 3,752 additions & 3,720 deletions Rubberduck.Parsing/Grammar/VBAParser.cs

Large diffs are not rendered by default.

21 changes: 15 additions & 6 deletions Rubberduck.Parsing/Grammar/VBAParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,13 @@ moduleBodyElement :

block : (blockStmt endOfStatement)*;

blockStmt :
statementLabelDefinition
| fileStmt
blockStmt :
statementLabelDefinition whiteSpace? mainBlockStmt?
| mainBlockStmt
;

mainBlockStmt :
fileStmt
| attributeStmt
| constStmt
| doLoopStmt
Expand Down Expand Up @@ -558,9 +562,14 @@ complexType :

fieldLength : MULT whiteSpace? (numberLiteral | identifierValue);

statementLabelDefinition : identifierStatementLabel | lineNumberLabel;
identifierStatementLabel : unrestrictedIdentifier whiteSpace? COLON;
lineNumberLabel : numberLiteral whiteSpace? COLON?;
//Statement labels can only appear at the start of a line.
statementLabelDefinition : {_input.La(-1) == NEWLINE}? (combinedLabels | identifierStatementLabel | standaloneLineNumberLabel);
identifierStatementLabel : unrestrictedIdentifier whiteSpace? COLON;
standaloneLineNumberLabel :
lineNumberLabel whiteSpace? COLON
| lineNumberLabel;
combinedLabels : lineNumberLabel whiteSpace identifierStatementLabel;
lineNumberLabel : numberLiteral;

numberLiteral : HEXLITERAL | OCTLITERAL | FLOATLITERAL | INTEGERLITERAL;

Expand Down
39 changes: 39 additions & 0 deletions Rubberduck.Parsing/Grammar/VBAParserBaseListener.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1489,6 +1489,19 @@ public virtual void EnterAttributeName([NotNull] VBAParser.AttributeNameContext
/// <param name="context">The parse tree.</param>
public virtual void ExitAttributeName([NotNull] VBAParser.AttributeNameContext context) { }

/// <summary>
/// Enter a parse tree produced by <see cref="VBAParser.mainBlockStmt"/>.
/// <para>The default implementation does nothing.</para>
/// </summary>
/// <param name="context">The parse tree.</param>
public virtual void EnterMainBlockStmt([NotNull] VBAParser.MainBlockStmtContext context) { }
/// <summary>
/// Exit a parse tree produced by <see cref="VBAParser.mainBlockStmt"/>.
/// <para>The default implementation does nothing.</para>
/// </summary>
/// <param name="context">The parse tree.</param>
public virtual void ExitMainBlockStmt([NotNull] VBAParser.MainBlockStmtContext context) { }

/// <summary>
/// Enter a parse tree produced by <see cref="VBAParser.implementsStmt"/>.
/// <para>The default implementation does nothing.</para>
Expand Down Expand Up @@ -2022,6 +2035,19 @@ public virtual void EnterIdentifier([NotNull] VBAParser.IdentifierContext contex
/// <param name="context">The parse tree.</param>
public virtual void ExitIdentifier([NotNull] VBAParser.IdentifierContext context) { }

/// <summary>
/// Enter a parse tree produced by <see cref="VBAParser.combinedLabels"/>.
/// <para>The default implementation does nothing.</para>
/// </summary>
/// <param name="context">The parse tree.</param>
public virtual void EnterCombinedLabels([NotNull] VBAParser.CombinedLabelsContext context) { }
/// <summary>
/// Exit a parse tree produced by <see cref="VBAParser.combinedLabels"/>.
/// <para>The default implementation does nothing.</para>
/// </summary>
/// <param name="context">The parse tree.</param>
public virtual void ExitCombinedLabels([NotNull] VBAParser.CombinedLabelsContext context) { }

/// <summary>
/// Enter a parse tree produced by <see cref="VBAParser.attributeStmt"/>.
/// <para>The default implementation does nothing.</para>
Expand Down Expand Up @@ -2763,6 +2789,19 @@ public virtual void EnterComparisonOperator([NotNull] VBAParser.ComparisonOperat
/// <param name="context">The parse tree.</param>
public virtual void ExitComparisonOperator([NotNull] VBAParser.ComparisonOperatorContext context) { }

/// <summary>
/// Enter a parse tree produced by <see cref="VBAParser.standaloneLineNumberLabel"/>.
/// <para>The default implementation does nothing.</para>
/// </summary>
/// <param name="context">The parse tree.</param>
public virtual void EnterStandaloneLineNumberLabel([NotNull] VBAParser.StandaloneLineNumberLabelContext context) { }
/// <summary>
/// Exit a parse tree produced by <see cref="VBAParser.standaloneLineNumberLabel"/>.
/// <para>The default implementation does nothing.</para>
/// </summary>
/// <param name="context">The parse tree.</param>
public virtual void ExitStandaloneLineNumberLabel([NotNull] VBAParser.StandaloneLineNumberLabelContext context) { }

/// <summary>
/// Enter a parse tree produced by <see cref="VBAParser.startRecordNumber"/>.
/// <para>The default implementation does nothing.</para>
Expand Down
33 changes: 33 additions & 0 deletions Rubberduck.Parsing/Grammar/VBAParserBaseVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1264,6 +1264,17 @@ public partial class VBAParserBaseVisitor<Result> : AbstractParseTreeVisitor<Res
/// <return>The visitor result.</return>
public virtual Result VisitAttributeName([NotNull] VBAParser.AttributeNameContext context) { return VisitChildren(context); }

/// <summary>
/// Visit a parse tree produced by <see cref="VBAParser.mainBlockStmt"/>.
/// <para>
/// The default implementation returns the result of calling <see cref="AbstractParseTreeVisitor{Result}.VisitChildren(IRuleNode)"/>
/// on <paramref name="context"/>.
/// </para>
/// </summary>
/// <param name="context">The parse tree.</param>
/// <return>The visitor result.</return>
public virtual Result VisitMainBlockStmt([NotNull] VBAParser.MainBlockStmtContext context) { return VisitChildren(context); }

/// <summary>
/// Visit a parse tree produced by <see cref="VBAParser.implementsStmt"/>.
/// <para>
Expand Down Expand Up @@ -1715,6 +1726,17 @@ public partial class VBAParserBaseVisitor<Result> : AbstractParseTreeVisitor<Res
/// <return>The visitor result.</return>
public virtual Result VisitIdentifier([NotNull] VBAParser.IdentifierContext context) { return VisitChildren(context); }

/// <summary>
/// Visit a parse tree produced by <see cref="VBAParser.combinedLabels"/>.
/// <para>
/// The default implementation returns the result of calling <see cref="AbstractParseTreeVisitor{Result}.VisitChildren(IRuleNode)"/>
/// on <paramref name="context"/>.
/// </para>
/// </summary>
/// <param name="context">The parse tree.</param>
/// <return>The visitor result.</return>
public virtual Result VisitCombinedLabels([NotNull] VBAParser.CombinedLabelsContext context) { return VisitChildren(context); }

/// <summary>
/// Visit a parse tree produced by <see cref="VBAParser.attributeStmt"/>.
/// <para>
Expand Down Expand Up @@ -2342,6 +2364,17 @@ public partial class VBAParserBaseVisitor<Result> : AbstractParseTreeVisitor<Res
/// <return>The visitor result.</return>
public virtual Result VisitComparisonOperator([NotNull] VBAParser.ComparisonOperatorContext context) { return VisitChildren(context); }

/// <summary>
/// Visit a parse tree produced by <see cref="VBAParser.standaloneLineNumberLabel"/>.
/// <para>
/// The default implementation returns the result of calling <see cref="AbstractParseTreeVisitor{Result}.VisitChildren(IRuleNode)"/>
/// on <paramref name="context"/>.
/// </para>
/// </summary>
/// <param name="context">The parse tree.</param>
/// <return>The visitor result.</return>
public virtual Result VisitStandaloneLineNumberLabel([NotNull] VBAParser.StandaloneLineNumberLabelContext context) { return VisitChildren(context); }

/// <summary>
/// Visit a parse tree produced by <see cref="VBAParser.startRecordNumber"/>.
/// <para>
Expand Down
33 changes: 33 additions & 0 deletions Rubberduck.Parsing/Grammar/VBAParserListener.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1305,6 +1305,17 @@ public interface IVBAParserListener : IParseTreeListener {
/// <param name="context">The parse tree.</param>
void ExitAttributeName([NotNull] VBAParser.AttributeNameContext context);

/// <summary>
/// Enter a parse tree produced by <see cref="VBAParser.mainBlockStmt"/>.
/// </summary>
/// <param name="context">The parse tree.</param>
void EnterMainBlockStmt([NotNull] VBAParser.MainBlockStmtContext context);
/// <summary>
/// Exit a parse tree produced by <see cref="VBAParser.mainBlockStmt"/>.
/// </summary>
/// <param name="context">The parse tree.</param>
void ExitMainBlockStmt([NotNull] VBAParser.MainBlockStmtContext context);

/// <summary>
/// Enter a parse tree produced by <see cref="VBAParser.implementsStmt"/>.
/// </summary>
Expand Down Expand Up @@ -1762,6 +1773,17 @@ public interface IVBAParserListener : IParseTreeListener {
/// <param name="context">The parse tree.</param>
void ExitIdentifier([NotNull] VBAParser.IdentifierContext context);

/// <summary>
/// Enter a parse tree produced by <see cref="VBAParser.combinedLabels"/>.
/// </summary>
/// <param name="context">The parse tree.</param>
void EnterCombinedLabels([NotNull] VBAParser.CombinedLabelsContext context);
/// <summary>
/// Exit a parse tree produced by <see cref="VBAParser.combinedLabels"/>.
/// </summary>
/// <param name="context">The parse tree.</param>
void ExitCombinedLabels([NotNull] VBAParser.CombinedLabelsContext context);

/// <summary>
/// Enter a parse tree produced by <see cref="VBAParser.attributeStmt"/>.
/// </summary>
Expand Down Expand Up @@ -2405,6 +2427,17 @@ public interface IVBAParserListener : IParseTreeListener {
/// <param name="context">The parse tree.</param>
void ExitComparisonOperator([NotNull] VBAParser.ComparisonOperatorContext context);

/// <summary>
/// Enter a parse tree produced by <see cref="VBAParser.standaloneLineNumberLabel"/>.
/// </summary>
/// <param name="context">The parse tree.</param>
void EnterStandaloneLineNumberLabel([NotNull] VBAParser.StandaloneLineNumberLabelContext context);
/// <summary>
/// Exit a parse tree produced by <see cref="VBAParser.standaloneLineNumberLabel"/>.
/// </summary>
/// <param name="context">The parse tree.</param>
void ExitStandaloneLineNumberLabel([NotNull] VBAParser.StandaloneLineNumberLabelContext context);

/// <summary>
/// Enter a parse tree produced by <see cref="VBAParser.startRecordNumber"/>.
/// </summary>
Expand Down
21 changes: 21 additions & 0 deletions Rubberduck.Parsing/Grammar/VBAParserVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -836,6 +836,13 @@ public interface IVBAParserVisitor<Result> : IParseTreeVisitor<Result> {
/// <return>The visitor result.</return>
Result VisitAttributeName([NotNull] VBAParser.AttributeNameContext context);

/// <summary>
/// Visit a parse tree produced by <see cref="VBAParser.mainBlockStmt"/>.
/// </summary>
/// <param name="context">The parse tree.</param>
/// <return>The visitor result.</return>
Result VisitMainBlockStmt([NotNull] VBAParser.MainBlockStmtContext context);

/// <summary>
/// Visit a parse tree produced by <see cref="VBAParser.implementsStmt"/>.
/// </summary>
Expand Down Expand Up @@ -1126,6 +1133,13 @@ public interface IVBAParserVisitor<Result> : IParseTreeVisitor<Result> {
/// <return>The visitor result.</return>
Result VisitIdentifier([NotNull] VBAParser.IdentifierContext context);

/// <summary>
/// Visit a parse tree produced by <see cref="VBAParser.combinedLabels"/>.
/// </summary>
/// <param name="context">The parse tree.</param>
/// <return>The visitor result.</return>
Result VisitCombinedLabels([NotNull] VBAParser.CombinedLabelsContext context);

/// <summary>
/// Visit a parse tree produced by <see cref="VBAParser.attributeStmt"/>.
/// </summary>
Expand Down Expand Up @@ -1533,6 +1547,13 @@ public interface IVBAParserVisitor<Result> : IParseTreeVisitor<Result> {
/// <return>The visitor result.</return>
Result VisitComparisonOperator([NotNull] VBAParser.ComparisonOperatorContext context);

/// <summary>
/// Visit a parse tree produced by <see cref="VBAParser.standaloneLineNumberLabel"/>.
/// </summary>
/// <param name="context">The parse tree.</param>
/// <return>The visitor result.</return>
Result VisitStandaloneLineNumberLabel([NotNull] VBAParser.StandaloneLineNumberLabelContext context);

/// <summary>
/// Visit a parse tree produced by <see cref="VBAParser.startRecordNumber"/>.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,15 @@ private static RewriterInfo GetLocalConstantRemovalInfo(VBAParser.ConstSubStmtCo
VBAParser.ConstStmtContext constants,
int count, int itemIndex, IReadOnlyList<VBAParser.ConstSubStmtContext> items)
{
var blockStmt = (VBAParser.BlockStmtContext)constants.Parent;
var startIndex = blockStmt.Start.TokenIndex;
var parent = (VBAParser.BlockContext)blockStmt.Parent;
var statements = parent.blockStmt();
var mainBlockStmt = (VBAParser.MainBlockStmtContext)constants.Parent;
var startIndex = mainBlockStmt.Start.TokenIndex;
var blockStmt = (VBAParser.BlockStmtContext)mainBlockStmt.Parent;
var block = (VBAParser.BlockContext)blockStmt.Parent;
var statements = block.blockStmt();

if (count == 1)
{
var stopIndex = FindStopTokenIndex(statements, blockStmt, parent);
var stopIndex = FindStopTokenIndex(statements, mainBlockStmt, block);
return new RewriterInfo(startIndex, stopIndex);
}
return GetRewriterInfoForTargetRemovedFromListStmt(target.Start, itemIndex, items);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,24 @@ protected static int FindStopTokenIndex<TParent>(IReadOnlyList<ParserRuleContext
return item.Stop.TokenIndex;
}

protected static int FindStopTokenIndex(IReadOnlyList<VBAParser.BlockStmtContext> blockStmts, VBAParser.MainBlockStmtContext mainBlockStmt, VBAParser.BlockContext block)
{
for (var i = 0; i < blockStmts.Count; i++)
{
if (blockStmts[i].mainBlockStmt() != mainBlockStmt)
{
continue;
}
if (blockStmts[i].statementLabelDefinition() != null)
{
return mainBlockStmt.Stop.TokenIndex; //Removing the following endOfStatement if there is a label on the line would break the code.
}
return FindStopTokenIndex(block, i);
}

return mainBlockStmt.Stop.TokenIndex;
}

private static int FindStopTokenIndex(VBAParser.BlockContext context, int index)
{
return context.endOfStatement(index).Stop.TokenIndex;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,15 @@ private static RewriterInfo GetLocalVariableRemovalInfo(VBAParser.VariableSubStm
VBAParser.VariableListStmtContext variables,
int count, int itemIndex, IReadOnlyList<VBAParser.VariableSubStmtContext> items)
{
var blockStmt = (VBAParser.BlockStmtContext)variables.Parent.Parent;
var startIndex = blockStmt.Start.TokenIndex;
var parent = (VBAParser.BlockContext)blockStmt.Parent;
var statements = parent.blockStmt();
var mainBlockStmt = (VBAParser.MainBlockStmtContext)variables.Parent.Parent;
var startIndex = mainBlockStmt.Start.TokenIndex;
var blockStmt = (VBAParser.BlockStmtContext)mainBlockStmt.Parent;
var block = (VBAParser.BlockContext)blockStmt.Parent;
var statements = block.blockStmt();

if (count == 1)
{
var stopIndex = FindStopTokenIndex(statements, blockStmt, parent);
var stopIndex = FindStopTokenIndex(statements, blockStmt, block);
return new RewriterInfo(startIndex, stopIndex);
}
return GetRewriterInfoForTargetRemovedFromListStmt(target.Start, itemIndex, items);
Expand Down
Loading