Skip to content

Commit

Permalink
Macro references now have exact start and end position
Browse files Browse the repository at this point in the history
  • Loading branch information
gquerret committed Oct 31, 2021
1 parent d64d04a commit ee89006
Show file tree
Hide file tree
Showing 12 changed files with 112 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
* analyze-* statements, ...
*/
public interface IPreprocessorEventListener {
void macroRef(int line, int column, String macroName);
void macroRef(int line, int column, int endLine, int endColumn, String macroName);
void macroRefEnd();
void include(int line, int column, int currentFile, String incFile);
void include(int line, int column, int endLine, int endColumn, int currentFile, String incFile);
void includeArgument(String argName, String value, boolean undefined);
void includeEnd();
void define(int line, int column, String name, String value, MacroDefinitionType type);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ public class IncludeRef extends MacroRef {
private int fileIndex;
private boolean usesNamedArgs;

public IncludeRef(MacroRef parent, int line, int column) {
super(parent, line, column);
public IncludeRef(MacroRef parent, int line, int column, int endLine, int endColumn) {
super(parent, line, column, endLine, endColumn);
}

public IncludeRef(MacroRef parent, int line, int column, int fileIndex) {
super(parent, line, column);
public IncludeRef(MacroRef parent, int line, int column, int endLine, int endColumn, int fileIndex) {
super(parent, line, column, endLine, endColumn);
this.fileIndex = fileIndex;
}

Expand Down
25 changes: 18 additions & 7 deletions proparse/src/main/java/org/prorefactor/macrolevel/MacroRef.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,18 @@ public abstract class MacroRef implements MacroEvent {
private final MacroRef parent;
private final int refColumn;
private final int refLine;
private final int refEndLine;
private final int refEndColumn;

/** A list of macro references and defines that are in this macro's source */
public final List<MacroEvent> macroEventList = new ArrayList<>();

public MacroRef(MacroRef parent, int line, int column) {
MacroRef(MacroRef parent, int line, int column, int endLine, int endColumn) {
this.parent = parent;
this.refLine = line;
this.refColumn = column;
this.refEndLine = endLine;
this.refEndColumn = endColumn;
}

@Override
Expand All @@ -52,15 +56,22 @@ public int getColumn() {
return refColumn;
}

public int getEndLine() {
return refEndLine;
}

public int getEndColumn() {
return refEndColumn;
}

/**
* Find <i>external macro references</i>. An external macro is an include file, a &amp;GLOBAL or a &amp;SCOPED from another
* file, and include args.
* Find <i>external macro references</i>. An external macro is an include file, a &amp;GLOBAL or a &amp;SCOPED from
* another file, and include args.
*
* TODO: (Jan 26) This doesn't seem right to me anymore. An &amp;UNDEFINE only affects the local scope. If re-implemented
* after building a pseudoprocessor, consider dropping this. &amp;UNDEFINE of a &amp;GLOBAL or of a &amp;SCOPED from another file
* is considered a reference. &amp;UNDEFINE of an include argument is considered a reference.
* &amp;UNDEFINE of a &amp;GLOBAL or of a &amp;SCOPED from another file is considered a reference. &amp;UNDEFINE of an
* include argument is considered a reference.
*
* The subroutine is recursive, because a local define may incur an external reference!
* The subroutine is recursive, because a local define may incur an external reference.
*
* @return An array of objects: MacroRef and MacroDef (for UNDEFINE).
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
public class NamedMacroRef extends MacroRef {
private final MacroDef macroDef;

public NamedMacroRef(MacroDef macro, MacroRef parent, int line, int column) {
super(parent, line, column);
public NamedMacroRef(MacroDef macro, MacroRef parent, int line, int column, int endLine, int endColumn) {
super(parent, line, column, endLine, endColumn);
this.macroDef = macro;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public class PreprocessorEventListener implements IPreprocessorEventListener {
private CodeSection currSection;

public PreprocessorEventListener() {
root = new IncludeRef(null, 0, 0);
root = new IncludeRef(null, 0, 0, 0, 0);

currRef = root;
currInclude = root;
Expand Down Expand Up @@ -91,8 +91,8 @@ public void preproIf(int line, int column, boolean value) {
}

@Override
public void include(int line, int column, int currentFile, String incFile) {
IncludeRef newRef = new IncludeRef(currRef, line, column, currentFile);
public void include(int line, int column, int endLine, int endColumn, int currentFile, String incFile) {
IncludeRef newRef = new IncludeRef(currRef, line, column, endLine, endColumn, currentFile);
scopeStack.addFirst(new Scope(newRef));
currRef.macroEventList.add(newRef);
currInclude = newRef;
Expand Down Expand Up @@ -128,8 +128,8 @@ public void includeEnd() {
}

@Override
public void macroRef(int line, int column, String macroName) {
NamedMacroRef newRef = new NamedMacroRef(findMacroDef(macroName), currRef, line, column);
public void macroRef(int line, int column, int endLine, int endColumn, String macroName) {
NamedMacroRef newRef = new NamedMacroRef(findMacroDef(macroName), currRef, line, column, endLine, endColumn);
currRef.macroEventList.add(newRef);
currRef = newRef;
}
Expand Down
21 changes: 9 additions & 12 deletions proparse/src/main/java/org/prorefactor/proparse/Lexer.java
Original file line number Diff line number Diff line change
Expand Up @@ -1547,7 +1547,7 @@ private void ppMacroReference() {
ppCurrChar = '{';
currentInput = new InputSource(++sourceCounter, refText.substring(1), refPos.file, refPos.line, refPos.col);
currentInclude.addInputSource(currentInput);
prepro.getLstListener().macroRef(refPos.line, refPos.col, "_proparse_");
prepro.getLstListener().macroRef(refPos.line, refPos.col, currLine, currCol, "_proparse_");
} else {
// Proparse Directive
ppCurrChar = PROPARSE_DIRECTIVE;
Expand All @@ -1556,7 +1556,7 @@ private void ppMacroReference() {
// This will be counted as a source whether picked up here or picked
// up as a normal macro ref.
++sourceCounter;
prepro.getLstListener().macroRef(refPos.line, refPos.col, "_proparse_");
prepro.getLstListener().macroRef(refPos.line, refPos.col, currLine, currCol, "_proparse_");
prepro.getLstListener().macroRefEnd();
}
} else if ("{*}".equals(refText)) {
Expand Down Expand Up @@ -1663,16 +1663,13 @@ else if (cp.chars[cp.pos] == '&') { // include '&' named args
if (prepro.isLexOnly()) {
ppCurrChar = INCLUDE_DIRECTIVE;
includeDirectiveText = refText.trim();
} else
// newInclude() returns false if filename is blank or currently
// "consuming" due to &IF FALSE.
// newInclude() will throw() if file not found or cannot be opened.
if (ppNewInclude(includeFilename)) {
// Unlike currline and currcol,
// currfile is only updated with a push/pop of the input stack.
} else if (ppNewInclude(includeFilename)) {
// ppNewInclude() returns false if filename is blank or currently "consuming" due to &IF FALSE.
// ppNewInclude() will throw UncheckedIOException if file not found or cannot be opened.
// Unlike currline and currcol, currfile is only updated with a push/pop of the input stack.
currFile = currentInput.getFileIndex();
currSourceNum = currentInput.getSourceNum();
prepro.getLstListener().include(refPos.line, refPos.col, currFile, includeFilename);
prepro.getLstListener().include(refPos.line, refPos.col, currLine, currCol, currFile, includeFilename);
// Add the arguments to the new include object.
int argNum = 1;
for (IncludeArg incarg : incArgs) {
Expand All @@ -1696,12 +1693,12 @@ private void ppNewMacroRef(String macroName, FilePos refPos) {
// Using this trick: {{&undefined-argument}{&*}}
// it is possible to get line breaks into what we
// get here as the macroName. See test data bug15.p and bug15.i.
prepro.getLstListener().macroRef(refPos.line, refPos.col, macroName);
prepro.getLstListener().macroRef(refPos.line, refPos.col, currLine, currCol, macroName);
ppNewMacroRef2(getArgText(macroName), refPos);
}

private void ppNewMacroRef(int argNum, FilePos refPos) {
prepro.getLstListener().macroRef(refPos.line, refPos.col, Integer.toString(argNum));
prepro.getLstListener().macroRef(refPos.line, refPos.col, currLine, currCol, Integer.toString(argNum));
ppNewMacroRef2(getArgText(argNum), refPos);
}

Expand Down
52 changes: 49 additions & 3 deletions proparse/src/test/java/org/prorefactor/core/MacroGraphTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.prorefactor.core.util.UnitTestModule;
import org.prorefactor.macrolevel.IncludeRef;
import org.prorefactor.macrolevel.MacroEvent;
import org.prorefactor.macrolevel.MacroRef;
import org.prorefactor.macrolevel.NamedMacroRef;
import org.prorefactor.refactor.RefactorSession;
import org.prorefactor.treeparser.ParseUnit;
Expand Down Expand Up @@ -124,9 +125,46 @@ public void testMacroGraphPosition() {
assertFalse(unit.hasSyntaxError());

List<MacroEvent> list = unit.getMacroGraph().findExternalMacroReferences();
assertEquals(list.get(0).getPosition().getLine(), 3);
assertEquals(list.get(0).getPosition().getColumn(), 5);
assertEquals(list.get(0).getPosition().getFileNum(), 0);
assertTrue(list.get(0) instanceof IncludeRef);
assertEquals(((MacroRef) list.get(0)).getFileIndex(), 1);
assertEquals(((MacroRef) list.get(0)).getLine(), 3);
assertEquals(((MacroRef) list.get(0)).getColumn(), 5);
assertEquals(((MacroRef) list.get(0)).getEndLine(), 3);
assertEquals(((MacroRef) list.get(0)).getEndColumn(), 40);
assertTrue(list.get(1) instanceof IncludeRef);
assertEquals(((MacroRef) list.get(1)).getFileIndex(), 2);
assertEquals(((MacroRef) list.get(1)).getLine(), 20);
assertEquals(((MacroRef) list.get(1)).getColumn(), 1);
assertEquals(((MacroRef) list.get(1)).getEndLine(), 20);
assertEquals(((MacroRef) list.get(1)).getEndColumn(), 44);
assertTrue(list.get(2) instanceof IncludeRef);
assertEquals(((MacroRef) list.get(2)).getFileIndex(), 3);
assertEquals(((MacroRef) list.get(2)).getLine(), 22);
assertEquals(((MacroRef) list.get(2)).getColumn(), 1);
assertEquals(((MacroRef) list.get(2)).getEndLine(), 22);
assertEquals(((MacroRef) list.get(2)).getEndColumn(), 36);
assertTrue(list.get(3) instanceof IncludeRef);
assertEquals(((MacroRef) list.get(3)).getFileIndex(), 3);
assertEquals(((MacroRef) list.get(3)).getLine(), 28);
assertEquals(((MacroRef) list.get(3)).getColumn(), 1);
assertEquals(((MacroRef) list.get(3)).getEndLine(), 28);
assertEquals(((MacroRef) list.get(3)).getEndColumn(), 36);

MacroRef ref = (MacroRef) unit.getMacroGraph().macroEventList.get(5);
assertEquals(ref.getLine(), 24);
assertEquals(ref.getEndLine(), 24);
assertEquals(ref.getColumn(), 1);
assertEquals(ref.getEndColumn(), 49);
ref = (MacroRef) unit.getMacroGraph().macroEventList.get(6);
assertEquals(ref.getLine(), 25);
assertEquals(ref.getEndLine(), 25);
assertEquals(ref.getColumn(), 3);
assertEquals(ref.getEndColumn(), 53);
ref = (MacroRef) unit.getMacroGraph().macroEventList.get(7);
assertEquals(ref.getLine(), 26);
assertEquals(ref.getEndLine(), 27);
assertEquals(ref.getColumn(), 1);
assertEquals(ref.getEndColumn(), 1);
}

@Test
Expand All @@ -140,6 +178,10 @@ public void testIncludeParameter01() {
assertEquals(list.size(), 1);
assertTrue(list.get(0) instanceof IncludeRef);
IncludeRef ref = (IncludeRef) list.get(0);
assertEquals(ref.getLine(), 1);
assertEquals(ref.getEndLine(), 3);
assertEquals(ref.getColumn(), 1);
assertEquals(ref.getEndColumn(), 44);
assertNotNull(ref.getArgNumber(1));
assertEquals(ref.getArgNumber(1).getName(), "param1");
assertEquals(ref.getArgNumber(1).getValue(), "value1");
Expand All @@ -160,6 +202,10 @@ public void testIncludeParameter02() {
assertEquals(list.size(), 1);
assertTrue(list.get(0) instanceof IncludeRef);
IncludeRef ref = (IncludeRef) list.get(0);
assertEquals(ref.getLine(), 1);
assertEquals(ref.getEndLine(), 5);
assertEquals(ref.getColumn(), 1);
assertEquals(ref.getEndColumn(), 33);
assertNotNull(ref.getArgNumber(1));
assertEquals(ref.getArgNumber(1).getName(), "param1");
assertEquals(ref.getArgNumber(1).getValue(), "value1");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.prorefactor.core.util.UnitTestModule;
import org.prorefactor.macrolevel.IncludeRef;
import org.prorefactor.macrolevel.MacroDef;
import org.prorefactor.macrolevel.MacroRef;
import org.prorefactor.macrolevel.NamedMacroRef;
import org.prorefactor.proparse.antlr4.Proparse;
import org.prorefactor.refactor.RefactorSession;
Expand Down Expand Up @@ -303,19 +304,28 @@ public void test09() {
assertTrue(incRef.macroEventList.get(1) instanceof NamedMacroRef);
NamedMacroRef nmr = (NamedMacroRef) incRef.macroEventList.get(1);
assertEquals(nmr.getMacroDef(), incRef.macroEventList.get(0));
assertEquals(nmr.getLine(), 4);
assertEquals(nmr.getEndLine(), 4);
assertEquals(nmr.getColumn(), 10);
assertEquals(nmr.getEndColumn(), 17);
}

@Test
public void test10() {
ParseUnit unit = new ParseUnit(new File(SRC_DIR, "preprocessor16.p"), session);
unit.parse();
assertFalse(unit.hasSyntaxError());
IncludeRef incRef = unit.getMacroGraph();
assertEquals(incRef.macroEventList.size(), 3);
assertTrue(incRef.macroEventList.get(0) instanceof MacroDef);
assertTrue(incRef.macroEventList.get(1) instanceof NamedMacroRef);
NamedMacroRef nmr = (NamedMacroRef) incRef.macroEventList.get(1);
assertEquals(nmr.getMacroDef(), incRef.macroEventList.get(0));
IncludeRef mainFile = unit.getMacroGraph();
assertEquals(mainFile.macroEventList.size(), 3);
assertTrue(mainFile.macroEventList.get(0) instanceof MacroDef);
assertTrue(mainFile.macroEventList.get(1) instanceof NamedMacroRef);
NamedMacroRef nmr = (NamedMacroRef) mainFile.macroEventList.get(1);
assertEquals(nmr.getMacroDef(), mainFile.macroEventList.get(0));
IncludeRef incRef = (IncludeRef) mainFile.macroEventList.get(2);
assertEquals(incRef.getLine(), 6);
assertEquals(incRef.getEndLine(), 6);
assertEquals(incRef.getColumn(), 4);
assertEquals(incRef.getEndColumn(), 36);
List<JPNode> nodes = unit.getTopNode().query(ABLNodeType.DEFINE);
assertEquals(nodes.size(), 1);
// Preprocessor magic... Keywords can start in main file, and end in include file...
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public class TokenListTest {
private RefactorSession session;

@BeforeTest
public void setUp() {
public void setUp() {
Injector injector = Guice.createInjector(new UnitTestModule());
session = injector.getInstance(RefactorSession.class);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
{ preprocessor/preprocessor02-03.i }

{&_proparse_ prolint-nowarn(messagekeywordmatch)}
{&_proparse_ prolint-nowarn(messagekeywordmatch)}
{&_proparse_ prolint-nowarn(messagekeywordmatch)}
{&_proparse_ prolint-nowarn(messagekeywordmatch) }
{&_proparse_ prolint-nowarn(messagekeywordmatch)
}
{ preprocessor/preprocessor02-03.i }
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Variable FOO is expanded by preprocessor, and will result in OutOfRange problem with CPD
// Expansion should be reverted for CPD.
&scoped-define FOO LongLongName
MESSAGE "{&FOO}" VIEW-AS
&scoped-define FOO LongLongLongLongLongLongLongLongName
MESSAGE "{&FOO }" VIEW-AS
ALERT-BOX.
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{ preprocessor/preprocessor18.i &param1= "value1"
&param2 =
"value2" }.
"value2" }.

0 comments on commit ee89006

Please sign in to comment.