diff --git a/Jenkinsfile b/Jenkinsfile
index aa6f60d37..d5b6ccd8e 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -23,7 +23,7 @@ pipeline {
} else if (env.BRANCH_NAME.startsWith("release") || env.BRANCH_NAME.startsWith("hotfix")) {
sh "$MVN_HOME/bin/mvn clean javadoc:javadoc install -Dmaven.test.failure.ignore=true -Dgit.commit=\$(git rev-parse --short HEAD)"
} else {
- sh "$MVN_HOME/bin/mvn clean package -Dmaven.test.failure.ignore=true -Dgit.commit=\$(git rev-parse --short HEAD)"
+ sh "$MVN_HOME/bin/mvn clean verify -Dmaven.test.failure.ignore=true -Dgit.commit=\$(git rev-parse --short HEAD)"
}
}
}
diff --git a/coverage-report/pom.xml b/coverage-report/pom.xml
index 093e51b55..9b22f452b 100644
--- a/coverage-report/pom.xml
+++ b/coverage-report/pom.xml
@@ -5,7 +5,7 @@
eu.rssw
sonar-openedge
- 2.29.1
+ 2.30.0
eu.rssw.openedge.parsers
coverage-report
@@ -21,37 +21,37 @@
eu.rssw.openedge.rcode
rcode-reader
- 2.29.1
+ 2.30.0
eu.rssw.sonar.openedge
sonar-openedge-plugin
- 2.29.1
+ 2.30.0
eu.rssw.openedge.parsers
proparse
- 2.29.1
+ 2.30.0
eu.rssw.openedge.parsers
profiler-parser
- 2.29.1
+ 2.30.0
eu.rssw.openedge.parsers
database-parser
- 2.29.1
+ 2.30.0
eu.rssw.openedge.parsers
listing-parser
- 2.29.1
+ 2.30.0
eu.rssw.openedge.checks
openedge-checks
- 2.29.1
+ 2.30.0
diff --git a/database-parser/pom.xml b/database-parser/pom.xml
index 560ca36eb..393ed1c14 100644
--- a/database-parser/pom.xml
+++ b/database-parser/pom.xml
@@ -5,7 +5,7 @@
eu.rssw
sonar-openedge
- 2.29.1
+ 2.30.0
eu.rssw.openedge.parsers
database-parser
diff --git a/listing-parser/pom.xml b/listing-parser/pom.xml
index c9cc762a6..ad7058880 100644
--- a/listing-parser/pom.xml
+++ b/listing-parser/pom.xml
@@ -5,7 +5,7 @@
eu.rssw
sonar-openedge
- 2.29.1
+ 2.30.0
eu.rssw.openedge.parsers
listing-parser
diff --git a/openedge-checks/pom.xml b/openedge-checks/pom.xml
index d88343c2f..7c1d2297b 100644
--- a/openedge-checks/pom.xml
+++ b/openedge-checks/pom.xml
@@ -5,7 +5,7 @@
eu.rssw
sonar-openedge
- 2.29.1
+ 2.30.0
eu.rssw.openedge.checks
openedge-checks
@@ -23,12 +23,12 @@
eu.rssw.openedge.parsers
database-parser
- 2.29.1
+ 2.30.0
eu.rssw.openedge.parsers
proparse
- 2.29.1
+ 2.30.0
org.testng
diff --git a/openedge-checks/src/main/java/org/sonar/plugins/openedge/api/checks/OpenEdgeProparseCheck.java b/openedge-checks/src/main/java/org/sonar/plugins/openedge/api/checks/OpenEdgeProparseCheck.java
index 91606c07c..63c64dbb9 100644
--- a/openedge-checks/src/main/java/org/sonar/plugins/openedge/api/checks/OpenEdgeProparseCheck.java
+++ b/openedge-checks/src/main/java/org/sonar/plugins/openedge/api/checks/OpenEdgeProparseCheck.java
@@ -109,7 +109,7 @@ protected NewIssue createIssue(InputFile file, ProToken token, String msg, boole
NewIssueLocation location = issue.newLocation().on(targetFile);
if (lineNumber > 0) {
if (exactLocation) {
- location.at(targetFile.newRange(token.getLine(), token.getCharPositionInLine() - 1, token.getEndLine(),
+ location.at(targetFile.newRange(token.getLine(), token.getCharPositionInLine(), token.getEndLine(),
token.getEndCharPositionInLine()));
} else {
TextRange range = targetFile.selectLine(lineNumber);
@@ -168,7 +168,7 @@ protected void addLocation(NewIssue issue, InputFile file, JPNode node, String m
int lineNumber = naturalChild.getLine();
if (lineNumber > 0) {
if (exactLocation) {
- location.at(targetFile.newRange(naturalChild.getLine(), naturalChild.getColumn() - 1,
+ location.at(targetFile.newRange(naturalChild.getLine(), naturalChild.getColumn(),
naturalChild.getEndLine(), naturalChild.getEndColumn()));
} else {
TextRange range = targetFile.selectLine(lineNumber);
diff --git a/openedge-plugin/pom.xml b/openedge-plugin/pom.xml
index c01b5fc4b..6ecdcdd5d 100644
--- a/openedge-plugin/pom.xml
+++ b/openedge-plugin/pom.xml
@@ -5,7 +5,7 @@
eu.rssw
sonar-openedge
- 2.29.1
+ 2.30.0
eu.rssw.sonar.openedge
sonar-openedge-plugin
@@ -30,17 +30,17 @@
eu.rssw.openedge.checks
openedge-checks
- 2.29.1
+ 2.30.0
eu.rssw.openedge.parsers
listing-parser
- 2.29.1
+ 2.30.0
eu.rssw.openedge.parsers
profiler-parser
- 2.29.1
+ 2.30.0
org.sonarsource.sonarqube
diff --git a/openedge-plugin/src/main/java/org/sonar/plugins/openedge/OpenEdgePlugin.java b/openedge-plugin/src/main/java/org/sonar/plugins/openedge/OpenEdgePlugin.java
index 7133a27c7..985909b2e 100644
--- a/openedge-plugin/src/main/java/org/sonar/plugins/openedge/OpenEdgePlugin.java
+++ b/openedge-plugin/src/main/java/org/sonar/plugins/openedge/OpenEdgePlugin.java
@@ -58,11 +58,8 @@ public void define(Context context) {
context.addExtensions(OpenEdge.class, OpenEdgeDB.class, OpenEdgeSettings.class);
// Profile and rules
- if (context.getRuntime().getProduct() == SonarProduct.SONARQUBE)
- context.addExtension(OpenEdgeRulesDefinition.class);
-
- context.addExtensions(BasicChecksRegistration.class, OpenEdgeProfile.class, OpenEdgeDBProfile.class,
- OpenEdgeMetrics.class, OpenEdgeComponents.class);
+ context.addExtensions(OpenEdgeRulesDefinition.class, BasicChecksRegistration.class, OpenEdgeProfile.class,
+ OpenEdgeDBProfile.class, OpenEdgeMetrics.class, OpenEdgeComponents.class);
// Syntax highlight and simple CPD
if (context.getRuntime().getProduct() == SonarProduct.SONARQUBE) {
diff --git a/openedge-plugin/src/main/java/org/sonar/plugins/openedge/foundation/CPDCallback.java b/openedge-plugin/src/main/java/org/sonar/plugins/openedge/foundation/CPDCallback.java
index f24092894..54480e92f 100644
--- a/openedge-plugin/src/main/java/org/sonar/plugins/openedge/foundation/CPDCallback.java
+++ b/openedge-plugin/src/main/java/org/sonar/plugins/openedge/foundation/CPDCallback.java
@@ -131,7 +131,7 @@ private void visitCpdNode(JPNode node) {
}
try {
- TextRange range = file.newRange(node.getLine(), node.getColumn() - 1, node.getEndLine(), node.getEndColumn());
+ TextRange range = file.newRange(node.getLine(), node.getColumn(), node.getEndLine(), node.getEndColumn());
cpdTokens.addToken(range, str);
} catch (IllegalArgumentException | IllegalStateException uncaught) {
LOG.debug("Unable to create CPD token at position {}:{} to {}:{} - Cause {}", node.getLine(), node.getColumn(),
@@ -143,7 +143,7 @@ private void insertFakeNode(JPNode node) {
List children = node.getDirectChildren();
JPNode lastSibling = children.isEmpty() ? node : children.get(children.size() - 1);
try {
- TextRange range = file.newRange(node.getLine(), node.getColumn() - 1, lastSibling.getEndLine(), lastSibling.getEndColumn() - 1);
+ TextRange range = file.newRange(node.getLine(), node.getColumn(), lastSibling.getEndLine(), lastSibling.getEndColumn());
cpdTokens.addToken(range, UUID.randomUUID().toString());
} catch (IllegalArgumentException | IllegalStateException uncaught) {
LOG.debug("Unable to create CPD token at position {}:{} to {}:{} - Cause {}", node.getLine(), node.getColumn(),
diff --git a/openedge-plugin/src/main/java/org/sonar/plugins/openedge/sensor/OpenEdgeCPDSensor.java b/openedge-plugin/src/main/java/org/sonar/plugins/openedge/sensor/OpenEdgeCPDSensor.java
index ddd2b0e63..a1c9a0c8b 100644
--- a/openedge-plugin/src/main/java/org/sonar/plugins/openedge/sensor/OpenEdgeCPDSensor.java
+++ b/openedge-plugin/src/main/java/org/sonar/plugins/openedge/sensor/OpenEdgeCPDSensor.java
@@ -136,7 +136,7 @@ private static void processToken(InputFile file, NewCpdTokens cpdTokens, ProToke
}
try {
- TextRange range = file.newRange(tok.getLine(), tok.getCharPositionInLine() - 1, tok.getEndLine(),
+ TextRange range = file.newRange(tok.getLine(), tok.getCharPositionInLine(), tok.getEndLine(),
tok.getEndCharPositionInLine());
cpdTokens.addToken(range, str);
} catch (IllegalArgumentException | IllegalStateException uncaught) {
diff --git a/openedge-plugin/src/main/java/org/sonar/plugins/openedge/sensor/OpenEdgeCodeColorizer.java b/openedge-plugin/src/main/java/org/sonar/plugins/openedge/sensor/OpenEdgeCodeColorizer.java
index 91f9bd559..ed3e73b63 100644
--- a/openedge-plugin/src/main/java/org/sonar/plugins/openedge/sensor/OpenEdgeCodeColorizer.java
+++ b/openedge-plugin/src/main/java/org/sonar/plugins/openedge/sensor/OpenEdgeCodeColorizer.java
@@ -117,7 +117,7 @@ private void highlightFile(SensorContext context, IProparseEnvironment session,
if (textType != null) {
try {
- TextPointer start = file.newPointer(tok.getLine(), tok.getCharPositionInLine() - 1);
+ TextPointer start = file.newPointer(tok.getLine(), tok.getCharPositionInLine());
int maxChar = file.selectLine(tok.getEndLine()).end().lineOffset();
TextPointer end = file.newPointer(tok.getEndLine(), maxChar < tok.getEndCharPositionInLine()
? (maxChar > 0 ? maxChar - 1 : 0) : tok.getEndCharPositionInLine());
diff --git a/openedge-plugin/src/main/java/org/sonar/plugins/openedge/sensor/OpenEdgeProparseSensor.java b/openedge-plugin/src/main/java/org/sonar/plugins/openedge/sensor/OpenEdgeProparseSensor.java
index d19f142f4..03e93b580 100644
--- a/openedge-plugin/src/main/java/org/sonar/plugins/openedge/sensor/OpenEdgeProparseSensor.java
+++ b/openedge-plugin/src/main/java/org/sonar/plugins/openedge/sensor/OpenEdgeProparseSensor.java
@@ -349,8 +349,8 @@ private void parseMainFile(SensorContext context, InputFile file, IProparseEnvir
TextPointer end = null;
if (InputFileUtils.getRelativePath(file, context.fileSystem()).equals(tok.getFileName())) {
try {
- strt = file.newPointer(tok.getLine(), tok.getCharPositionInLine() - 1);
- end = file.newPointer(tok.getLine(), tok.getCharPositionInLine());
+ strt = file.newPointer(tok.getLine(), tok.getCharPositionInLine());
+ end = file.newPointer(tok.getLine(), tok.getEndCharPositionInLine());
} catch (IllegalArgumentException uncaught) {
// Nothing
}
diff --git a/openedge-plugin/src/test/java/org/sonar/plugins/openedge/OpenEdgePluginTest.java b/openedge-plugin/src/test/java/org/sonar/plugins/openedge/OpenEdgePluginTest.java
index 6a1c755aa..3af0ce6c0 100644
--- a/openedge-plugin/src/test/java/org/sonar/plugins/openedge/OpenEdgePluginTest.java
+++ b/openedge-plugin/src/test/java/org/sonar/plugins/openedge/OpenEdgePluginTest.java
@@ -49,7 +49,7 @@ public class OpenEdgePluginTest {
public void testExtensionsSonarLint() {
Plugin.Context context = new Plugin.Context(SONARLINT_RUNTIME);
new OpenEdgePlugin().define(context);
- assertEquals(context.getExtensions().size(), 26);
+ assertEquals(context.getExtensions().size(), 27);
}
@Test
diff --git a/pom.xml b/pom.xml
index 7503474ae..be05e6f3b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
eu.rssw
sonar-openedge
- 2.29.1
+ 2.30.0
pom
OpenEdge plugin for SonarQube
diff --git a/profiler-parser/pom.xml b/profiler-parser/pom.xml
index de701ba90..5bd18e357 100644
--- a/profiler-parser/pom.xml
+++ b/profiler-parser/pom.xml
@@ -5,7 +5,7 @@
eu.rssw
sonar-openedge
- 2.29.1
+ 2.30.0
eu.rssw.openedge.parsers
profiler-parser
diff --git a/proparse/pom.xml b/proparse/pom.xml
index af2ea8c92..b18b95d37 100644
--- a/proparse/pom.xml
+++ b/proparse/pom.xml
@@ -5,7 +5,7 @@
eu.rssw
sonar-openedge
- 2.29.1
+ 2.30.0
eu.rssw.openedge.parsers
proparse
@@ -22,7 +22,7 @@
eu.rssw.openedge.rcode
rcode-reader
- 2.29.1
+ 2.30.0
org.antlr
diff --git a/proparse/src/main/antlr4/org/prorefactor/proparse/antlr4/Proparse.g4 b/proparse/src/main/antlr4/org/prorefactor/proparse/antlr4/Proparse.g4
index dc72d43cc..644eedca8 100644
--- a/proparse/src/main/antlr4/org/prorefactor/proparse/antlr4/Proparse.g4
+++ b/proparse/src/main/antlr4/org/prorefactor/proparse/antlr4/Proparse.g4
@@ -755,6 +755,10 @@ widgetname:
identifier
;
+queryIdentifier:
+ identifier
+ ;
+
identifier:
// identifier gets us an ID node for an unqualified (local) reference.
// Only an ID or unreservedkeyword can be used as an unqualified reference.
@@ -1173,7 +1177,7 @@ clearStatement:
;
closeQueryStatement:
- CLOSE QUERY identifier statementEnd
+ CLOSE QUERY queryIdentifier statementEnd
;
closeStoredProcedureStatement:
@@ -1851,12 +1855,12 @@ definePropertyAccessorSetBlock:
defineQueryStatement:
DEFINE defineShare? ( PRIVATE | PROTECTED | STATIC )*
- QUERY n=identifier
+ QUERY id=identifier
FOR record recordFields?
( COMMA record recordFields? )*
( cacheExpr | SCROLLING | RCODEINFORMATION )*
statementEnd
- { support.defVar($n.text); }
+ { support.defVar($id.text); }
;
defineRectangleStatement:
@@ -2514,7 +2518,7 @@ externalFunctionStatement:
;
getStatement:
- GET findWhich identifier ( lockHow | NOWAIT )* statementEnd
+ GET findWhich queryIdentifier ( lockHow | NOWAIT )* statementEnd
;
getKeyValueStatement:
@@ -2960,7 +2964,7 @@ onAction:
;
openQueryStatement:
- OPEN QUERY identifier ( FOR | PRESELECT ) multiRecordSearch
+ OPEN QUERY queryIdentifier ( FOR | PRESELECT ) multiRecordSearch
openQueryOption*
statementEnd
;
@@ -3268,7 +3272,7 @@ releaseObjectStatement:
;
repositionStatement:
- REPOSITION identifier repositionOption NOERROR? statementEnd
+ REPOSITION queryIdentifier repositionOption NOERROR? statementEnd
;
repositionOption:
diff --git a/proparse/src/main/java/org/prorefactor/core/Pair.java b/proparse/src/main/java/org/prorefactor/core/Pair.java
deleted file mode 100644
index 4ad410439..000000000
--- a/proparse/src/main/java/org/prorefactor/core/Pair.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * ABL Language Server implementation
- *
- * This source code is not part of an open-source package.
- * Copyright (c) 2021-2024 Riverside Software
- * contact@riverside-software.fr
- */
-package org.prorefactor.core;
-
-public class Pair {
- private final X o1;
- private final Y o2;
-
- public Pair(X o1, Y o2) {
- this.o1 = o1;
- this.o2 = o2;
- }
-
- public static Pair of(A x, B y) {
- return new Pair<>(x, y);
- }
-
- public X getO1() {
- return o1;
- }
-
- public Y getO2() {
- return o2;
- }
-}
diff --git a/proparse/src/main/java/org/prorefactor/core/ProToken.java b/proparse/src/main/java/org/prorefactor/core/ProToken.java
index d56d7a2ae..5ddab3ad3 100644
--- a/proparse/src/main/java/org/prorefactor/core/ProToken.java
+++ b/proparse/src/main/java/org/prorefactor/core/ProToken.java
@@ -77,12 +77,6 @@ public int getLine() {
return line;
}
- /**
- * The index of the first character of this token relative to the beginning of the line at which it occurs.
- *
- * IMPORTANT: While the ANTLR4 Token interface specifies that charPositionInLine should start at 0, the ProToken
- * implementation starts at 1. This implementation detail might change in the future (if that's not too late).
- */
@Override
public int getCharPositionInLine() {
return charPositionInLine;
@@ -150,9 +144,7 @@ public int getEndLine() {
}
/**
- * The index of the last character of this token relative to the beginning of the line at which it occurs. This means
- * that the first character of next token will be at this position + 1. Also means that getCharPositionInLine() ==
- * getEndCharPositionInLine() for single-character tokens.
+ * Line offset **after** the last character of the token
*/
public int getEndCharPositionInLine() {
return endCharPositionInLine;
diff --git a/proparse/src/main/java/org/prorefactor/core/nodetypes/ExpressionNode.java b/proparse/src/main/java/org/prorefactor/core/nodetypes/ExpressionNode.java
index 80164861f..5aad79824 100644
--- a/proparse/src/main/java/org/prorefactor/core/nodetypes/ExpressionNode.java
+++ b/proparse/src/main/java/org/prorefactor/core/nodetypes/ExpressionNode.java
@@ -19,6 +19,7 @@
import org.prorefactor.core.ABLNodeType;
import org.prorefactor.core.JPNode;
+import org.prorefactor.core.Pair;
import org.prorefactor.core.ProToken;
import org.prorefactor.proparse.support.IProparseEnvironment;
@@ -733,6 +734,7 @@ static DataType getStandardAttributeDataType(String id) {
static DataType getStandardMethodDataType(String id) {
switch (id) {
case "ADD-NEW-FIELD":
+ case "ADD-SUPER-PROCEDURE":
return DataType.LOGICAL;
// TODO Full list
default:
@@ -740,7 +742,8 @@ static DataType getStandardMethodDataType(String id) {
}
}
- static DataType getObjectMethodDataType(Function provider, JPNode node, ITypeInfo info, String methodName) {
+ static Pair getObjectMethod(Function provider, JPNode node, ITypeInfo info,
+ String methodName) {
// Create array of dataTypes
List paramItems = node.getDirectChildren(ABLNodeType.PARAMETER_ITEM);
DataType[] params = new DataType[paramItems.size()];
@@ -755,12 +758,7 @@ static DataType getObjectMethodDataType(Function provider, JP
params[zz++] = dt;
}
- if (info != null) {
- IMethodElement methd = info.getMethod(provider, methodName, params);
- return methd == null ? DataType.NOT_COMPUTED : methd.getReturnType();
- } else {
- return DataType.NOT_COMPUTED;
- }
+ return info == null ? null : info.getMethod(provider, methodName, params);
}
static DataType getObjectAttributeDataType(IProparseEnvironment session, ITypeInfo info, String propName,
diff --git a/proparse/src/main/java/org/prorefactor/core/nodetypes/LocalMethodCallNode.java b/proparse/src/main/java/org/prorefactor/core/nodetypes/LocalMethodCallNode.java
index 33d7b7c85..f8404756f 100644
--- a/proparse/src/main/java/org/prorefactor/core/nodetypes/LocalMethodCallNode.java
+++ b/proparse/src/main/java/org/prorefactor/core/nodetypes/LocalMethodCallNode.java
@@ -15,19 +15,23 @@
package org.prorefactor.core.nodetypes;
import org.prorefactor.core.JPNode;
+import org.prorefactor.core.Pair;
import org.prorefactor.core.ProToken;
import com.google.common.base.Strings;
import eu.rssw.pct.elements.BuiltinClasses;
import eu.rssw.pct.elements.DataType;
+import eu.rssw.pct.elements.IMethodElement;
import eu.rssw.pct.elements.ITypeInfo;
/**
* Expression node: methodName(parameters)
(only in classes)
*/
public class LocalMethodCallNode extends ExpressionNode {
- private String methodName = "";
+ private final String methodName;
+ private boolean computed = false;
+ private Pair method = null;
public LocalMethodCallNode(ProToken t, JPNode parent, int num, boolean hasChildren, String methodName) {
super(t, parent, num, hasChildren);
@@ -38,17 +42,36 @@ public String getMethodName() {
return methodName;
}
- @Override
- public DataType getDataType() {
+ private void compute() {
ProgramRootNode root = getTopLevelParent();
- if (root == null)
- return DataType.NOT_COMPUTED;
+ if (root != null) {
+ ITypeInfo typeInfo = root.getTypeInfo();
+ if (root.isClass() && (typeInfo == null))
+ typeInfo = BuiltinClasses.PROGRESS_LANG_OBJECT;
+ method = typeInfo == null ? null : getObjectMethod(root.getTypeInfoProvider(), this, typeInfo, methodName);
+ }
+ }
+
+ public synchronized ITypeInfo getTypeInfo() {
+ if (!computed) {
+ compute();
+ computed = true;
+ }
+ return method == null ? null : method.getO1();
+ }
- ITypeInfo info = root.getTypeInfo();
- if (root.isClass() && (info == null))
- info = BuiltinClasses.PROGRESS_LANG_OBJECT;
+ public synchronized IMethodElement getMethodElement() {
+ if (!computed) {
+ compute();
+ computed = true;
+ }
+ return method == null ? null : method.getO2();
+ }
- return getObjectMethodDataType(root.getTypeInfoProvider(), this, info, methodName);
+ @Override
+ public DataType getDataType() {
+ IMethodElement tmp = getMethodElement();
+ return tmp == null ? DataType.NOT_COMPUTED : tmp.getReturnType();
}
}
diff --git a/proparse/src/main/java/org/prorefactor/core/nodetypes/MethodCallNode.java b/proparse/src/main/java/org/prorefactor/core/nodetypes/MethodCallNode.java
index 0bc1f7630..1ab7cce0d 100644
--- a/proparse/src/main/java/org/prorefactor/core/nodetypes/MethodCallNode.java
+++ b/proparse/src/main/java/org/prorefactor/core/nodetypes/MethodCallNode.java
@@ -16,12 +16,14 @@
import org.prorefactor.core.ABLNodeType;
import org.prorefactor.core.JPNode;
+import org.prorefactor.core.Pair;
import org.prorefactor.core.ProToken;
import org.prorefactor.treeparser.symbols.Event;
import com.google.common.base.Strings;
import eu.rssw.pct.elements.DataType;
+import eu.rssw.pct.elements.IMethodElement;
import eu.rssw.pct.elements.ITypeInfo;
import eu.rssw.pct.elements.PrimitiveDataType;
@@ -29,7 +31,10 @@
* Expression node: <expr>:methodName(parameters)
*/
public class MethodCallNode extends ExpressionNode {
- private String methodName = "";
+ private final String methodName;
+ private boolean computed = false;
+ private Pair method = null;
+ private DataType returnDataType = DataType.NOT_COMPUTED;
public MethodCallNode(ProToken t, JPNode parent, int num, boolean hasChildren, String methodName) {
super(t, parent, num, hasChildren);
@@ -40,51 +45,103 @@ public String getMethodName() {
return methodName;
}
- @Override
- public DataType getDataType() {
- ProgramRootNode root = getTopLevelParent();
- if (root == null)
- return DataType.NOT_COMPUTED;
-
- if (getFirstChild() instanceof SystemHandleNode) {
- SystemHandleNode shn = (SystemHandleNode) getFirstChild();
- return shn.getMethodDataType(methodName.toUpperCase());
- } else if (getFirstChild() instanceof FieldRefNode) {
- if (((FieldRefNode) getFirstChild()).isStaticReference()) {
- ITypeInfo info = ((FieldRefNode) getFirstChild()).getStaticReference();
- return getObjectMethodDataType(root.getTypeInfoProvider(), findDirectChild(ABLNodeType.METHOD_PARAM_LIST), info,
- methodName);
- } else if ((getFirstChild().getSymbol() instanceof Event)
- && ("publish".equalsIgnoreCase(methodName) || "subscribe".equalsIgnoreCase(methodName))) {
- // Events only have Publish / Subscribe
- return DataType.VOID;
- }
+ private void handleSystemHandleNode(SystemHandleNode node, ProgramRootNode root) {
+ if (node.getFirstChild().getNodeType() == ABLNodeType.THISOBJECT) {
+ ITypeInfo typeInfo = root.getEnvironment().getTypeInfo(root.getClassName());
+ method = typeInfo == null ? null : getObjectMethod(root.getTypeInfoProvider(),
+ this.findDirectChild(ABLNodeType.METHOD_PARAM_LIST), typeInfo, methodName);
+ returnDataType = method == null ? DataType.NOT_COMPUTED : method.getO2().getReturnType();
+ } else if (node.getFirstChild().getNodeType() == ABLNodeType.SUPER) {
+ ITypeInfo info = root.getEnvironment().getTypeInfo(root.getClassName());
+ info = info == null ? null : root.getEnvironment().getTypeInfo(info.getParentTypeName());
+ method = info == null ? null : getObjectMethod(root.getTypeInfoProvider(),
+ this.findDirectChild(ABLNodeType.METHOD_PARAM_LIST), info, methodName);
+ returnDataType = method == null ? DataType.NOT_COMPUTED : method.getO2().getReturnType();
+ } else {
+ returnDataType = node.getMethodDataType(methodName.toUpperCase());
}
+ }
- // Left-Handle expression has to be a class
- IExpression expr = getFirstChild().asIExpression();
- if (expr != null) {
- DataType dataType = expr.getDataType();
- if (dataType.getPrimitive() == PrimitiveDataType.CLASS) {
- ITypeInfo info = root.getEnvironment().getTypeInfo(dataType.getClassName());
- return getObjectMethodDataType(getTopLevelParent().getTypeInfoProvider(),
- findDirectChild(ABLNodeType.METHOD_PARAM_LIST), info, methodName);
- } else if (dataType.getPrimitive() == PrimitiveDataType.HANDLE) {
- return getStandardMethodDataType(methodName.toUpperCase());
+ private void handleFieldRefNode(FieldRefNode node, ProgramRootNode root) {
+ if (node.isStaticReference()) {
+ method = getObjectMethod(root.getTypeInfoProvider(), findDirectChild(ABLNodeType.METHOD_PARAM_LIST), node.getStaticReference(),
+ methodName);
+ returnDataType = method == null ? DataType.NOT_COMPUTED : method.getO2().getReturnType();
+ } else if ((node.getSymbol() instanceof Event)
+ && ("publish".equalsIgnoreCase(methodName) || "subscribe".equalsIgnoreCase(methodName))) {
+ // Events only have Publish / Subscribe
+ returnDataType = DataType.VOID;
+ } else if (node.isIExpression()) {
+ handleExpression(node.asIExpression(), root);
+ }
+ }
+
+ private void handleExpression(IExpression expr, ProgramRootNode root) {
+ DataType dataType = expr.getDataType();
+ if (dataType.getPrimitive() == PrimitiveDataType.CLASS) {
+ ITypeInfo typeInfo = root.getEnvironment().getTypeInfo(dataType.getClassName());
+ method = typeInfo == null ? null : getObjectMethod(getTopLevelParent().getTypeInfoProvider(),
+ findDirectChild(ABLNodeType.METHOD_PARAM_LIST), typeInfo, methodName);
+ returnDataType = method == null ? DataType.NOT_COMPUTED : method.getO2().getReturnType();
+ } else if (dataType.getPrimitive() == PrimitiveDataType.HANDLE) {
+ returnDataType = getStandardMethodDataType(methodName.toUpperCase());
+ }
+ }
+
+ private void handleNonExpression(JPNode firstChild, ProgramRootNode root) {
+ // Within constructor: super(...) or this-object(...)
+ JPNode nextChild = firstChild.getNextSibling();
+ if (((firstChild.getNodeType() == ABLNodeType.SUPER) || (firstChild.getNodeType() == ABLNodeType.THISOBJECT))
+ && (nextChild.getNodeType() == ABLNodeType.LEFTPAREN)) {
+ if (root.getTypeInfo() == null) {
+ returnDataType = new DataType(root.getRootScope().getClassName());
+ } else {
+ returnDataType = new DataType(root.getTypeInfo().getTypeName());
}
+ }
+ }
+
+ private void compute() {
+ // Default
+ ProgramRootNode root = getTopLevelParent();
+ if (root == null)
+ return;
+
+ JPNode firstChild = getFirstChild();
+ if (firstChild instanceof SystemHandleNode) {
+ handleSystemHandleNode((SystemHandleNode) firstChild, root);
+ } else if (firstChild instanceof FieldRefNode) {
+ handleFieldRefNode((FieldRefNode) firstChild, root);
+ } else if (firstChild.isIExpression()) {
+ handleExpression(firstChild.asIExpression(), root);
} else {
- // Within constructor: super(...) or this-object(...)
- JPNode firstChild = getFirstChild();
- JPNode nextChild = firstChild.getNextSibling();
- if (((firstChild.getNodeType() == ABLNodeType.SUPER) || (firstChild.getNodeType() == ABLNodeType.THISOBJECT))
- && (nextChild.getNodeType() == ABLNodeType.LEFTPAREN)) {
- if (root.getTypeInfo() == null)
- return new DataType(root.getRootScope().getClassName());
- else
- return new DataType(root.getTypeInfo().getTypeName());
- }
+ handleNonExpression(firstChild, root);
+ }
+ }
+
+ public synchronized ITypeInfo getTypeInfo() {
+ if (!computed) {
+ compute();
+ computed = true;
+ }
+ return method == null ? null : method.getO1();
+ }
+
+ @Override
+ public synchronized DataType getDataType() {
+ if (!computed) {
+ compute();
+ computed = true;
+ }
+ return returnDataType;
+ }
+
+ public synchronized IMethodElement getMethodElement() {
+ if (!computed) {
+ compute();
+ computed = true;
}
- return DataType.NOT_COMPUTED;
+ return method == null ? null : method.getO2();
}
}
diff --git a/proparse/src/main/java/org/prorefactor/core/nodetypes/SystemHandleNode.java b/proparse/src/main/java/org/prorefactor/core/nodetypes/SystemHandleNode.java
index f8c3f3790..e42baf84c 100644
--- a/proparse/src/main/java/org/prorefactor/core/nodetypes/SystemHandleNode.java
+++ b/proparse/src/main/java/org/prorefactor/core/nodetypes/SystemHandleNode.java
@@ -16,9 +16,11 @@
import org.prorefactor.core.ABLNodeType;
import org.prorefactor.core.JPNode;
+import org.prorefactor.core.Pair;
import org.prorefactor.core.ProToken;
import eu.rssw.pct.elements.DataType;
+import eu.rssw.pct.elements.IMethodElement;
import eu.rssw.pct.elements.ITypeInfo;
/**
@@ -299,8 +301,11 @@ private DataType getSuperMethodDataType(String id) {
if ((info == null) || (info.getParentTypeName() == null))
return DataType.NOT_COMPUTED;
info = root.getEnvironment().getTypeInfo(info.getParentTypeName());
- return getObjectMethodDataType(root.getTypeInfoProvider(),
+ if (info == null)
+ return DataType.NOT_COMPUTED;
+ Pair elem = getObjectMethod(root.getTypeInfoProvider(),
this.getParent().findDirectChild(ABLNodeType.METHOD_PARAM_LIST), info, id);
+ return elem == null ? DataType.NOT_COMPUTED : elem.getO2().getReturnType();
}
private DataType getThisObjectAttributeDataType(String id) {
@@ -320,8 +325,9 @@ private DataType getThisObjectMethodDataType(String id) {
ITypeInfo info = root.getTypeInfo();
if (info == null)
return DataType.NOT_COMPUTED;
- return getObjectMethodDataType(root.getTypeInfoProvider(),
+ Pair elem = getObjectMethod(root.getTypeInfoProvider(),
this.getParent().findDirectChild(ABLNodeType.METHOD_PARAM_LIST), info, id);
+ return elem == null ? DataType.NOT_COMPUTED : elem.getO2().getReturnType();
}
private DataType getWebContextMethodDataType(String id) {
diff --git a/proparse/src/main/java/org/prorefactor/proparse/InputSource.java b/proparse/src/main/java/org/prorefactor/proparse/InputSource.java
index 85b5344d5..dfd9da23f 100644
--- a/proparse/src/main/java/org/prorefactor/proparse/InputSource.java
+++ b/proparse/src/main/java/org/prorefactor/proparse/InputSource.java
@@ -52,7 +52,7 @@ public class InputSource {
private final int fileIndex;
private final boolean macroExpansion;
- private int nextCol = 1;
+ private int nextCol = 0;
private int nextLine = 1;
private int currPos;
private String currAnalyzeSuspend = null;
@@ -122,7 +122,7 @@ public int get() {
if (!macroExpansion) {
if (currChar == '\n') {
nextLine++;
- nextCol = 1;
+ nextCol = 0;
} else {
nextCol++;
}
diff --git a/proparse/src/main/java/org/prorefactor/proparse/JPNodeVisitor.java b/proparse/src/main/java/org/prorefactor/proparse/JPNodeVisitor.java
index 6311f9148..c050c4520 100644
--- a/proparse/src/main/java/org/prorefactor/proparse/JPNodeVisitor.java
+++ b/proparse/src/main/java/org/prorefactor/proparse/JPNodeVisitor.java
@@ -524,6 +524,11 @@ public Builder visitBlockLabel(BlockLabelContext ctx) {
return visitChildren(ctx).changeType(ABLNodeType.BLOCK_LABEL);
}
+ @Override
+ public Builder visitQueryIdentifier(QueryIdentifierContext ctx) {
+ return visitChildren(ctx).setRuleNode(ctx);
+ }
+
@Override
public Builder visitIdentifierUKW(IdentifierUKWContext ctx) {
return visitChildren(ctx).changeType(ABLNodeType.ID);
diff --git a/proparse/src/main/java/org/prorefactor/proparse/Lexer.java b/proparse/src/main/java/org/prorefactor/proparse/Lexer.java
index 10297df8c..ceaa23eef 100644
--- a/proparse/src/main/java/org/prorefactor/proparse/Lexer.java
+++ b/proparse/src/main/java/org/prorefactor/proparse/Lexer.java
@@ -1236,7 +1236,7 @@ private ProToken makeToken(ABLNodeType type, String text) {
.setCharPositionInLine(tokenStartPos.col) //
.setEndFileIndex(prevChar.file) //
.setEndLine(prevChar.line) //
- .setEndCharPositionInLine(prevChar.col) //
+ .setEndCharPositionInLine(prevChar.col + 1) //
.setMacroExpansion(prevMacroExpansion) //
.setMacroSourceNum(tokenStartPos.sourceNum) //
.setAnalyzeSuspend(getCurrentAnalyzeSuspend()) //
@@ -1553,7 +1553,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, currLine, currCol, "_proparse_");
+ prepro.getLstListener().macroRef(refPos.line, refPos.col, currLine, currCol + 1, "_proparse_");
} else {
// Proparse Directive
ppCurrChar = PROPARSE_DIRECTIVE;
@@ -1562,7 +1562,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, currLine, currCol, "_proparse_");
+ prepro.getLstListener().macroRef(refPos.line, refPos.col, currLine, currCol + 1, "_proparse_");
prepro.getLstListener().macroRefEnd();
}
} else if ("{*}".equals(refText)) {
@@ -1675,7 +1675,7 @@ else if (cp.chars[cp.pos] == '&') { // include '&' named args
// 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, currLine, currCol, currFile, includeFilename);
+ prepro.getLstListener().include(refPos.line, refPos.col, currLine, currCol + 1, currFile, includeFilename);
// Add the arguments to the new include object.
int argNum = 1;
for (IncludeArg incarg : incArgs) {
@@ -1699,12 +1699,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, currLine, currCol, macroName);
+ prepro.getLstListener().macroRef(refPos.line, refPos.col, currLine, currCol + 1, macroName);
ppNewMacroRef2(getArgText(macroName), refPos);
}
private void ppNewMacroRef(int argNum, FilePos refPos) {
- prepro.getLstListener().macroRef(refPos.line, refPos.col, currLine, currCol, Integer.toString(argNum));
+ prepro.getLstListener().macroRef(refPos.line, refPos.col, currLine, currCol + 1, Integer.toString(argNum));
ppNewMacroRef2(getArgText(argNum), refPos);
}
@@ -1759,22 +1759,18 @@ private int ppPopInput() {
* If not a doublequote, we collect characters until we find a whitespace
*/
private String ppIncludeRefArg(MacroCharPos cp, boolean numberedArg) {
- StringBuilder retVal = new StringBuilder();
- boolean gobbleWS = false;
- char c = cp.chars[cp.pos];
-
- if (!numberedArg) {
- if (c == '"') {
- gobbleWS = true;
- } else {
- retVal.append(c);
- }
- cp.pos++;
+ // Handle empty string in double quotes followed by space in a different way depending on numberedArg value
+ if ((cp.pos <= cp.chars.length - 4) && (cp.chars[cp.pos] == '"') && (cp.chars[cp.pos + 1] == '"')
+ && Character.isWhitespace(cp.chars[cp.pos + 2])) {
+ cp.pos += 2;
+ return numberedArg ? "\"" : "";
}
+ StringBuilder retVal = new StringBuilder();
+ boolean gobbleWS = false;
// Iterate up to, but not including, closing curly
while (cp.pos < cp.chars.length - 1) {
- c = cp.chars[cp.pos];
+ char c = cp.chars[cp.pos];
switch (c) {
case '"':
if (cp.chars[cp.pos + 1] == '"') {
diff --git a/proparse/src/main/java/org/prorefactor/treeparser/ParseUnit.java b/proparse/src/main/java/org/prorefactor/treeparser/ParseUnit.java
index 2222fd46a..8c0dec255 100644
--- a/proparse/src/main/java/org/prorefactor/treeparser/ParseUnit.java
+++ b/proparse/src/main/java/org/prorefactor/treeparser/ParseUnit.java
@@ -45,6 +45,7 @@
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import org.prorefactor.core.ABLNodeType;
import org.prorefactor.core.IConstants;
+import org.prorefactor.core.JPNode;
import org.prorefactor.core.JPNodeMetrics;
import org.prorefactor.core.nodetypes.ProgramRootNode;
import org.prorefactor.core.nodetypes.RecordNameNode;
@@ -272,6 +273,40 @@ public String getIncludeFileName(int index) {
return MacroLevel.sourceArray(macroGraph);
}
+ /**
+ * Return total number of ParseTree objects (ANTLR4 output) in this unit
+ */
+ public long getParseTreeSize() {
+ return sizeOfParseTree(tree);
+ }
+
+ private static long sizeOfParseTree(ParseTree tree) {
+ if (tree == null)
+ return 0L;
+ long sz = 1;
+ for (int zz = 0; zz < tree.getChildCount(); zz++) {
+ sz += sizeOfParseTree(tree.getChild(zz));
+ }
+ return sz;
+ }
+
+ /**
+ * Return total number of JPNode in this unit
+ */
+ public long getJPNodeSize() {
+ return sizeOfJPNode(topNode);
+ }
+
+ private static long sizeOfJPNode(JPNode tree) {
+ if (tree == null)
+ return 0L;
+ long sz = 1;
+ for (JPNode n : tree.getDirectChildren()) {
+ sz += sizeOfJPNode(n);
+ }
+ return sz;
+ }
+
/**
* Returns a TokenSource object for the main file. Include files are not expanded, and preprocessor is not used
*
diff --git a/proparse/src/main/java/org/prorefactor/treeparser/SymbolFactory.java b/proparse/src/main/java/org/prorefactor/treeparser/SymbolFactory.java
index 9db5801a2..93d5bff36 100644
--- a/proparse/src/main/java/org/prorefactor/treeparser/SymbolFactory.java
+++ b/proparse/src/main/java/org/prorefactor/treeparser/SymbolFactory.java
@@ -65,8 +65,7 @@ public static Symbol create(ABLNodeType symbolType, String name, TreeParserSymbo
case SUBMENU:
return new Submenu(name, scope);
default:
- assert false : "Unexpected values for SymbolFactory" + " " + symbolType + " " + name;
- return null;
+ throw new IllegalArgumentException("Unexpected " + symbolType + " node type for SymbolFactory#create()");
}
}
diff --git a/proparse/src/main/java/org/prorefactor/treeparser/TreeParserComputeReferences.java b/proparse/src/main/java/org/prorefactor/treeparser/TreeParserComputeReferences.java
index f52265fda..6937009f8 100644
--- a/proparse/src/main/java/org/prorefactor/treeparser/TreeParserComputeReferences.java
+++ b/proparse/src/main/java/org/prorefactor/treeparser/TreeParserComputeReferences.java
@@ -29,12 +29,16 @@
import org.prorefactor.proparse.antlr4.Proparse.FieldContext;
import org.prorefactor.proparse.antlr4.Proparse.ParameterArgDatasetHandleContext;
import org.prorefactor.proparse.antlr4.Proparse.ParameterArgTableHandleContext;
+import org.prorefactor.proparse.antlr4.Proparse.QueryIdentifierContext;
import org.prorefactor.proparse.antlr4.Proparse.RecordContext;
import org.prorefactor.proparse.antlr4.Proparse.WidNameContext;
import org.prorefactor.treeparser.symbols.FieldBuffer;
+import org.prorefactor.treeparser.symbols.Query;
import org.prorefactor.treeparser.symbols.TableBuffer;
import org.prorefactor.treeparser.symbols.Variable;
+import eu.rssw.pct.elements.DataType;
+
public class TreeParserComputeReferences extends AbstractBlockProparseListener {
@Inject
@@ -60,7 +64,6 @@ public void exitParameterArgDatasetHandle(ParameterArgDatasetHandleContext ctx)
@Override
public void enterExprTermAttribute(ExprTermAttributeContext ctx) {
ContextQualifier cq = contextQualifiers.get(ctx.attributeName().nonPunctuating());
-
if (ctx.expressionTerm() instanceof ExprTermOtherContext) {
ExprTermOtherContext ctx2 = (ExprTermOtherContext) ctx.expressionTerm();
if (ctx2.expressionTerm2() instanceof Exprt2FieldContext) {
@@ -72,6 +75,15 @@ public void enterExprTermAttribute(ExprTermAttributeContext ctx) {
}
}
+ @Override
+ public void enterQueryIdentifier(QueryIdentifierContext ctx) {
+ Query qry = currentScope.lookupQuery(ctx.identifier().getText());
+ JPNode node = support.getNode(ctx);
+ if ((node != null) && (qry != null)) {
+ node.setSymbol(qry);
+ }
+ }
+
@Override
public void enterWidName(WidNameContext ctx) {
if ((ctx.BUFFER() != null) || (ctx.TEMPTABLE() != null)) {
@@ -130,19 +142,25 @@ private void noteReference(JPNode node, ContextQualifier cq) {
// Called from expressionTerm rule (expressionTerm2 option) and widattr rule (widattrExprt2 option)
// Tries to add references to variables/properties of current class, or references to static classes
+ // And references to current variables / properties through another object reference
private void widattr(Exprt2FieldContext ctx2, ContextQualifier cq, String right) {
String clsRef = ctx2.field().getText();
String clsName = rootScope.getClassName();
- if ((clsRef != null) && (clsName != null) && (clsRef.indexOf('.') == -1) && (clsName.indexOf('.') != -1))
- clsName = clsName.substring(clsName.lastIndexOf('.') + 1);
- if ((clsRef != null) && (clsName != null) && clsRef.equalsIgnoreCase(clsName)) {
- FieldLookupResult result = currentBlock.lookupField(right, true);
- if (result == null)
- return;
+ boolean isFullStaticRef = (clsRef != null) && clsRef.equalsIgnoreCase(clsName);
+ boolean isShortStaticRef = (clsRef != null) && (clsRef.indexOf('.') == -1) && (clsName != null)
+ && clsRef.equalsIgnoreCase(clsName.substring(clsName.lastIndexOf('.') + 1));
+ boolean isStaticRef = isFullStaticRef || isShortStaticRef;
- // Variable
- if (result.getSymbol() instanceof Variable) {
+ JPNode fieldNode = support.getNode(ctx2.field());
+ boolean isExpr = (fieldNode != null) && fieldNode.isIExpression();
+ DataType dt = isExpr ? fieldNode.asIExpression().getDataType() : null;
+ boolean isRefToCurrentClass = (dt != null) && (dt.getClassName() != null)
+ && (dt.getClassName().equalsIgnoreCase(rootScope.getClassName()));
+
+ if (isStaticRef || isRefToCurrentClass) {
+ FieldLookupResult result = currentBlock.lookupField(right, true);
+ if ((result != null) && (result.getSymbol() instanceof Variable)) {
result.getSymbol().noteReference(support.getNode(ctx2.getParent().getParent()), cq);
}
}
diff --git a/proparse/src/test/java/org/prorefactor/core/ClassesTest.java b/proparse/src/test/java/org/prorefactor/core/ClassesTest.java
index 035c442bc..9890b5271 100644
--- a/proparse/src/test/java/org/prorefactor/core/ClassesTest.java
+++ b/proparse/src/test/java/org/prorefactor/core/ClassesTest.java
@@ -151,15 +151,23 @@ public void testThisObject() {
Variable prop1 = unit.getRootScope().getVariable("prop1");
Variable prop2 = unit.getRootScope().getVariable("prop2");
Variable var1 = unit.getRootScope().getVariable("var1");
+ Variable var2 = unit.getRootScope().getVariable("var2");
+ Variable var3 = unit.getRootScope().getVariable("var3");
assertNotNull(prop1);
assertNotNull(prop2);
assertNotNull(var1);
+ assertNotNull(var2);
+ assertNotNull(var3);
assertEquals(prop1.getNumReads(), 1);
assertEquals(prop1.getNumWrites(), 1);
assertEquals(prop2.getNumReads(), 1);
assertEquals(prop2.getNumWrites(), 1);
assertEquals(var1.getNumReads(), 0);
assertEquals(var1.getNumWrites(), 1);
+ assertEquals(var2.getNumReads(), 0);
+ assertEquals(var2.getNumWrites(), 2);
+ assertEquals(var3.getNumReads(), 1);
+ assertEquals(var3.getNumWrites(), 1);
}
}
diff --git a/proparse/src/test/java/org/prorefactor/core/JPNodeTest.java b/proparse/src/test/java/org/prorefactor/core/JPNodeTest.java
index 28e6d6ed5..2b7a06dec 100644
--- a/proparse/src/test/java/org/prorefactor/core/JPNodeTest.java
+++ b/proparse/src/test/java/org/prorefactor/core/JPNodeTest.java
@@ -53,8 +53,8 @@
* Tests for JPNodeVisitor
*/
public class JPNodeTest extends AbstractProparseTest {
- private final static String SRC_DIR = "src/test/resources/jpnode";
- private final static String TEMP_DIR = "target/nodes-lister/jpnode";
+ private static final String SRC_DIR = "src/test/resources/jpnode";
+ private static final String TEMP_DIR = "target/nodes-lister/jpnode";
private RefactorSession session;
private File tempDir = new File(TEMP_DIR);
@@ -177,14 +177,14 @@ public void testDotComment01() {
assertTrue(node.getText().startsWith(".message"));
assertEquals(node.getLine(), 1);
assertEquals(node.getEndLine(), 3);
- assertEquals(node.getColumn(), 1);
+ assertEquals(node.getColumn(), 0);
assertEquals(node.getEndColumn(), 27);
assertNotNull(node.getFirstChild());
assertEquals(node.getFirstChild().getNodeType(), ABLNodeType.PERIOD);
assertEquals(node.getFirstChild().getLine(), 3);
assertEquals(node.getFirstChild().getEndLine(), 3);
- assertEquals(node.getFirstChild().getColumn(), 29);
+ assertEquals(node.getFirstChild().getColumn(), 28);
assertEquals(node.getFirstChild().getEndColumn(), 29);
}
@@ -198,14 +198,14 @@ public void testDotComment02() {
assertEquals(node.getLine(), 1);
assertEquals(node.getEndLine(), 1);
- assertEquals(node.getColumn(), 1);
+ assertEquals(node.getColumn(), 0);
assertEquals(node.getEndColumn(), 8);
assertNotNull(node.getFirstChild());
assertEquals(node.getFirstChild().getNodeType(), ABLNodeType.PERIOD);
assertEquals(node.getFirstChild().getLine(), 1);
assertEquals(node.getFirstChild().getEndLine(), 1);
- assertEquals(node.getFirstChild().getColumn(), 9);
+ assertEquals(node.getFirstChild().getColumn(), 8);
assertEquals(node.getFirstChild().getEndColumn(), 9);
}
@@ -267,7 +267,7 @@ public void testFileName01() {
assertEquals(node.getFirstChild().getText(), "c:/foo/bar/something.p");
assertEquals(node.getFirstChild().getLine(), 1);
assertEquals(node.getFirstChild().getEndLine(), 1);
- assertEquals(node.getFirstChild().getColumn(), 9);
+ assertEquals(node.getFirstChild().getColumn(), 8);
assertEquals(node.getFirstChild().getEndColumn(), 30);
assertNotNull(node.getFirstChild().getNextSibling());
diff --git a/proparse/src/test/java/org/prorefactor/core/MacroGraphTest.java b/proparse/src/test/java/org/prorefactor/core/MacroGraphTest.java
index 3e7b974e1..9fc556967 100644
--- a/proparse/src/test/java/org/prorefactor/core/MacroGraphTest.java
+++ b/proparse/src/test/java/org/prorefactor/core/MacroGraphTest.java
@@ -28,6 +28,8 @@
import org.prorefactor.core.util.SportsSchema;
import org.prorefactor.core.util.UnitTestProparseSettings;
import org.prorefactor.macrolevel.IncludeRef;
+import org.prorefactor.macrolevel.MacroDef;
+import org.prorefactor.macrolevel.MacroDefinitionType;
import org.prorefactor.macrolevel.MacroEvent;
import org.prorefactor.macrolevel.MacroRef;
import org.prorefactor.macrolevel.NamedMacroRef;
@@ -38,7 +40,7 @@
import org.testng.annotations.Test;
public class MacroGraphTest extends AbstractProparseTest {
- private final static String SRC_DIR = "src/test/resources/data/preprocessor";
+ private static final String SRC_DIR = "src/test/resources/data/preprocessor";
private RefactorSession session;
@@ -135,42 +137,42 @@ public void testMacroGraphPosition() {
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)).getColumn(), 4);
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)).getColumn(), 0);
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)).getColumn(), 0);
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)).getColumn(), 0);
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.getColumn(), 0);
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.getColumn(), 2);
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.getColumn(), 0);
assertEquals(ref.getEndColumn(), 1);
}
@@ -187,7 +189,7 @@ public void testIncludeParameter01() {
IncludeRef ref = (IncludeRef) list.get(0);
assertEquals(ref.getLine(), 1);
assertEquals(ref.getEndLine(), 3);
- assertEquals(ref.getColumn(), 1);
+ assertEquals(ref.getColumn(), 0);
assertEquals(ref.getEndColumn(), 44);
assertNotNull(ref.getArgNumber(1));
assertEquals(ref.getArgNumber(1).getName(), "param1");
@@ -211,7 +213,7 @@ public void testIncludeParameter02() {
IncludeRef ref = (IncludeRef) list.get(0);
assertEquals(ref.getLine(), 1);
assertEquals(ref.getEndLine(), 5);
- assertEquals(ref.getColumn(), 1);
+ assertEquals(ref.getColumn(), 0);
assertEquals(ref.getEndColumn(), 33);
assertNotNull(ref.getArgNumber(1));
assertEquals(ref.getArgNumber(1).getName(), "param1");
@@ -225,4 +227,86 @@ public void testIncludeParameter02() {
assertNull(ref.getArgNumber(4));
}
+ @Test
+ public void testIncludeParameter03() {
+ ParseUnit unit = getParseUnit(new File(SRC_DIR, "preprocessor20.p"), session);
+ unit.parse();
+ assertFalse(unit.hasSyntaxError());
+
+ List list = unit.getMacroGraph().findExternalMacroReferences();
+ assertNotNull(list);
+ assertEquals(list.size(), 3);
+
+ /* First include file */
+ IncludeRef ref1 = (IncludeRef) list.get(0);
+ assertEquals(ref1.getLine(), 6);
+ assertEquals(ref1.getEndLine(), 6);
+ assertEquals(ref1.getColumn(), 17);
+ assertEquals(ref1.getEndColumn(), 58);
+ assertEquals(ref1.numArgs(), 1);
+ MacroDef ref1Arg1 = ref1.getArgNumber(1);
+ assertEquals(ref1Arg1.getType(), MacroDefinitionType.NUMBEREDARG);
+ assertEquals(ref1Arg1.getValue(), "BAR");
+
+ /* Second include file */
+ IncludeRef ref2 = (IncludeRef) list.get(1);
+ assertEquals(ref2.getLine(), 2);
+ assertEquals(ref2.getEndLine(), 8);
+ assertEquals(ref2.getColumn(), 0);
+ assertEquals(ref2.getEndColumn(), 7);
+ assertEquals(ref2.numArgs(), 5);
+ MacroDef ref2Arg1 = ref2.lookupNamedArg("param1");
+ assertEquals(ref2Arg1.getValue(), "");
+ MacroDef ref2Arg2 = ref2.lookupNamedArg("param2");
+ assertEquals(ref2Arg2.getValue(), "");
+ MacroDef ref2Arg3 = ref2.lookupNamedArg("param3");
+ assertEquals(ref2Arg3.getValue(), " ");
+ MacroDef ref2Arg4 = ref2.lookupNamedArg("param4");
+ assertEquals(ref2Arg4.getValue(), "XXX BAR BAR XXX ");
+ MacroDef ref2Arg5 = ref2.lookupNamedArg("param5");
+ assertEquals(ref2Arg5.getValue(), " test ");
+
+ /* Third include file */
+ IncludeRef ref3 = (IncludeRef) list.get(2);
+ assertEquals(ref3.getLine(), 9);
+ assertEquals(ref3.getEndLine(), 9);
+ assertEquals(ref3.getColumn(), 0);
+ assertEquals(ref3.getEndColumn(), 82);
+ assertEquals(ref3.numArgs(), 6);
+ MacroDef ref3Arg1 = ref3.getArgNumber(1);
+ assertEquals(ref3Arg1.getValue(), "\"");
+ MacroDef ref3Arg2 = ref3.getArgNumber(2);
+ assertEquals(ref3Arg2.getValue(), "value1");
+ MacroDef ref3Arg3 = ref3.getArgNumber(3);
+ assertEquals(ref3Arg3.getValue(), "value2");
+ MacroDef ref3Arg4 = ref3.getArgNumber(4);
+ assertEquals(ref3Arg4.getValue(), "\"value3\":U");
+ MacroDef ref3Arg5 = ref3.getArgNumber(5);
+ assertEquals(ref3Arg5.getValue(), "\"value4\"");
+ MacroDef ref3Arg6 = ref3.getArgNumber(6);
+ assertEquals(ref3Arg6.getValue(), " ");
+ }
+
+ @Test
+ public void testIncludeParameter04() {
+ ParseUnit unit = getParseUnit(new File(SRC_DIR, "preprocessor25.p"), session);
+ unit.parse();
+ assertFalse(unit.hasSyntaxError());
+
+ List list = unit.getMacroGraph().findExternalMacroReferences();
+ assertNotNull(list);
+ assertEquals(list.size(), 1);
+
+ /* First include file */
+ IncludeRef ref1 = (IncludeRef) list.get(0);
+ assertEquals(ref1.getLine(), 1);
+ assertEquals(ref1.getEndLine(), 1);
+ assertEquals(ref1.getColumn(), 0);
+ assertEquals(ref1.getEndColumn(), 56);
+ assertEquals(ref1.numArgs(), 1);
+ MacroDef ref1Arg1 = ref1.getArgNumber(1);
+ assertEquals(ref1Arg1.getType(), MacroDefinitionType.NAMEDARG);
+ assertEquals(ref1Arg1.getName(), "DefaultValue");
+ assertEquals(ref1Arg1.getValue(), "\"-\"");
+ }
}
diff --git a/proparse/src/test/java/org/prorefactor/core/MetricsTest.java b/proparse/src/test/java/org/prorefactor/core/MetricsTest.java
index d2639e3e5..b7d80be78 100644
--- a/proparse/src/test/java/org/prorefactor/core/MetricsTest.java
+++ b/proparse/src/test/java/org/prorefactor/core/MetricsTest.java
@@ -44,6 +44,8 @@ public void test01() {
assertEquals(unit.getMetrics().getLoc(), 2);
assertEquals(unit.getMetrics().getComments(), 6);
+ assertEquals(unit.getParseTreeSize(), 50);
+ assertEquals(unit.getJPNodeSize(), 22);
}
@Test
diff --git a/proparse/src/test/java/org/prorefactor/core/ParserTest.java b/proparse/src/test/java/org/prorefactor/core/ParserTest.java
index 528ba7f06..051439c0c 100644
--- a/proparse/src/test/java/org/prorefactor/core/ParserTest.java
+++ b/proparse/src/test/java/org/prorefactor/core/ParserTest.java
@@ -925,7 +925,7 @@ public void testElvis01() {
JPNode node1 = unit.getTopNode().query(ABLNodeType.ELVIS).get(0);
assertEquals(node1.getLine(), 3);
assertEquals(node1.getEndLine(), 3);
- assertEquals(node1.getColumn(), 11);
+ assertEquals(node1.getColumn(), 10);
assertEquals(node1.getEndColumn(), 12);
assertEquals(node1.getText(), "?:");
}
@@ -940,21 +940,21 @@ public void testElvis02() {
JPNode node2 = unit.getTopNode().query(ABLNodeType.LEXCOLON).get(0);
JPNode node3 = unit.getTopNode().query(ABLNodeType.DISPLAY).get(0);
assertEquals(node1.getLine(), 1);
- assertEquals(node1.getColumn(), 42);
+ assertEquals(node1.getColumn(), 41);
assertEquals(node1.getEndColumn(), 42);
assertEquals(node1.getText(), "?");
assertEquals(node2.getLine(), 1);
- assertEquals(node2.getColumn(), 43);
+ assertEquals(node2.getColumn(), 42);
assertEquals(node2.getEndColumn(), 43);
assertEquals(node2.getText(), ":");
assertEquals(node3.getLine(), 2);
- assertEquals(node3.getColumn(), 3);
+ assertEquals(node3.getColumn(), 2);
assertEquals(node3.getEndColumn(), 9);
assertNotNull(node3.getHiddenBefore());
assertNull(node3.getHiddenBefore().getHiddenBefore());
assertEquals(node3.getHiddenBefore().getLine(), 1);
assertEquals(node3.getHiddenBefore().getEndLine(), 2);
- assertEquals(node3.getHiddenBefore().getCharPositionInLine(), 44);
+ assertEquals(node3.getHiddenBefore().getCharPositionInLine(), 43);
assertEquals(node3.getHiddenBefore().getEndCharPositionInLine(), 2);
}
diff --git a/proparse/src/test/java/org/prorefactor/core/PreprocessorDirectiveTest.java b/proparse/src/test/java/org/prorefactor/core/PreprocessorDirectiveTest.java
index 471a1969f..e5dff76c8 100644
--- a/proparse/src/test/java/org/prorefactor/core/PreprocessorDirectiveTest.java
+++ b/proparse/src/test/java/org/prorefactor/core/PreprocessorDirectiveTest.java
@@ -37,7 +37,7 @@
import org.testng.annotations.Test;
public class PreprocessorDirectiveTest extends AbstractProparseTest {
- private final static String SRC_DIR = "src/test/resources/data/preprocessor";
+ private static final String SRC_DIR = "src/test/resources/data/preprocessor";
private RefactorSession session;
@@ -303,7 +303,7 @@ public void test09() {
assertEquals(nmr.getMacroDef(), incRef.macroEventList.get(0));
assertEquals(nmr.getLine(), 4);
assertEquals(nmr.getEndLine(), 4);
- assertEquals(nmr.getColumn(), 10);
+ assertEquals(nmr.getColumn(), 9);
assertEquals(nmr.getEndColumn(), 17);
}
@@ -321,7 +321,7 @@ public void test10() {
IncludeRef incRef = (IncludeRef) mainFile.macroEventList.get(2);
assertEquals(incRef.getLine(), 6);
assertEquals(incRef.getEndLine(), 6);
- assertEquals(incRef.getColumn(), 4);
+ assertEquals(incRef.getColumn(), 3);
assertEquals(incRef.getEndColumn(), 36);
List nodes = unit.getTopNode().query(ABLNodeType.DEFINE);
assertEquals(nodes.size(), 1);
@@ -330,7 +330,7 @@ public void test10() {
assertEquals(nodes.get(0).getEndFileIndex(), 1);
assertEquals(nodes.get(0).getLine(), 6);
assertEquals(nodes.get(0).getEndLine(), 1);
- assertEquals(nodes.get(0).getColumn(), 1);
+ assertEquals(nodes.get(0).getColumn(), 0);
assertEquals(nodes.get(0).getEndColumn(), 3);
}
@@ -345,11 +345,11 @@ public void test11() {
JPNode leftParen = substNode.getNextNode();
JPNode str = leftParen.getNextNode().getFirstChild().getFirstChild();
assertEquals(leftParen.getLine(), 2);
- assertEquals(leftParen.getColumn(), 19);
+ assertEquals(leftParen.getColumn(), 18);
assertEquals(leftParen.getEndLine(), 2);
assertEquals(leftParen.getEndColumn(), 19);
assertEquals(str.getLine(), 2);
- assertEquals(str.getColumn(), 20);
+ assertEquals(str.getColumn(), 19);
assertEquals(str.getEndLine(), 2);
assertEquals(str.getEndColumn(), 24);
@@ -357,11 +357,11 @@ public void test11() {
JPNode leftParen2 = substNode2.getNextNode();
JPNode str2 = leftParen2.getNextNode().getFirstChild().getFirstChild();
assertEquals(leftParen2.getLine(), 3);
- assertEquals(leftParen2.getColumn(), 19);
+ assertEquals(leftParen2.getColumn(), 18);
assertEquals(leftParen2.getEndLine(), 3);
assertEquals(leftParen2.getEndColumn(), 19);
assertEquals(str2.getLine(), 3);
- assertEquals(str2.getColumn(), 20);
+ assertEquals(str2.getColumn(), 19);
assertEquals(str2.getEndLine(), 3);
// FIXME Wrong value, should be 25
assertEquals(str2.getEndColumn(), 20);
@@ -372,7 +372,7 @@ public void test11() {
JPNode str3 = dispNode.getNextNode().getNextNode().getFirstChild();
assertEquals(str3.getLine(), 4);
assertEquals(str3.getEndLine(), 4);
- assertEquals(str3.getColumn(), 9);
+ assertEquals(str3.getColumn(), 8);
// FIXME Wrong value, should be 14
assertEquals(str3.getEndColumn(), 9);
}
diff --git a/proparse/src/test/java/org/prorefactor/core/TreeParser03Test.java b/proparse/src/test/java/org/prorefactor/core/TreeParser03Test.java
index 80857f172..4a40bde13 100644
--- a/proparse/src/test/java/org/prorefactor/core/TreeParser03Test.java
+++ b/proparse/src/test/java/org/prorefactor/core/TreeParser03Test.java
@@ -38,6 +38,7 @@
import org.prorefactor.treeparser.TreeParserSymbolScope;
import org.prorefactor.treeparser.symbols.Event;
import org.prorefactor.treeparser.symbols.Modifier;
+import org.prorefactor.treeparser.symbols.Query;
import org.prorefactor.treeparser.symbols.Routine;
import org.prorefactor.treeparser.symbols.Symbol;
import org.prorefactor.treeparser.symbols.TableBuffer;
@@ -1466,22 +1467,22 @@ public void testTTAsParameter() {
assertNotNull(f2prm6.getDefinitionNode());
assertEquals(f2prm1.getDefinitionNode().getNodeType(), ABLNodeType.ID);
assertEquals(f2prm1.getDefinitionNode().getLine(), 13);
- assertEquals(f2prm1.getDefinitionNode().getColumn(), 5);
+ assertEquals(f2prm1.getDefinitionNode().getColumn(), 4);
assertEquals(f2prm2.getDefinitionNode().getNodeType(), ABLNodeType.ID);
assertEquals(f2prm2.getDefinitionNode().getLine(), 14);
- assertEquals(f2prm2.getDefinitionNode().getColumn(), 5);
+ assertEquals(f2prm2.getDefinitionNode().getColumn(), 4);
assertEquals(f2prm3.getDefinitionNode().getNodeType(), ABLNodeType.RECORD_NAME);
assertEquals(f2prm3.getDefinitionNode().getLine(), 15);
- assertEquals(f2prm3.getDefinitionNode().getColumn(), 11);
+ assertEquals(f2prm3.getDefinitionNode().getColumn(), 10);
assertEquals(f2prm4.getDefinitionNode().getNodeType(), ABLNodeType.ID);
assertEquals(f2prm4.getDefinitionNode().getLine(), 16);
- assertEquals(f2prm4.getDefinitionNode().getColumn(), 18);
+ assertEquals(f2prm4.getDefinitionNode().getColumn(), 17);
assertEquals(f2prm5.getDefinitionNode().getNodeType(), ABLNodeType.ID);
assertEquals(f2prm5.getDefinitionNode().getLine(), 17);
- assertEquals(f2prm5.getDefinitionNode().getColumn(), 13);
+ assertEquals(f2prm5.getDefinitionNode().getColumn(), 12);
assertEquals(f2prm6.getDefinitionNode().getNodeType(), ABLNodeType.ID);
assertEquals(f2prm6.getDefinitionNode().getLine(), 18);
- assertEquals(f2prm6.getDefinitionNode().getColumn(), 20);
+ assertEquals(f2prm6.getDefinitionNode().getColumn(), 19);
}
@@ -1537,4 +1538,21 @@ public void test41() {
assertEquals(nodes.get(2).asIExpression().getDataType(), DataType.DECIMAL);
}
+ @Test
+ public void test42() {
+ ParseUnit unit = getParseUnit(new File("src/test/resources/treeparser03/test42.p"), session);
+ assertNull(unit.getTopNode());
+ unit.treeParser01();
+ assertFalse(unit.hasSyntaxError());
+ assertNotNull(unit.getTopNode());
+ assertNotNull(unit.getRootScope());
+
+ assertNull(unit.getRootScope().lookupQuery("qry00"));
+ Query qry = unit.getRootScope().lookupQuery("qry");
+ assertNotNull(qry);
+ List list = unit.getTopNode().query(ABLNodeType.ID);
+ assertEquals(list.size(), 4);
+ assertFalse(list.stream().anyMatch(it -> it.getSymbol() == null));
+ assertFalse(list.stream().anyMatch(it -> it.getSymbol().getNodeType() != ABLNodeType.QUERY));
+ }
}
diff --git a/proparse/src/test/java/org/prorefactor/proparse/ABLLexerTest.java b/proparse/src/test/java/org/prorefactor/proparse/ABLLexerTest.java
index 5320b8343..1ae96d969 100644
--- a/proparse/src/test/java/org/prorefactor/proparse/ABLLexerTest.java
+++ b/proparse/src/test/java/org/prorefactor/proparse/ABLLexerTest.java
@@ -458,7 +458,7 @@ public void testQuotedStringPosition01() {
ProToken tok = (ProToken) lexer.nextToken();
assertEquals(tok.getNodeType(), ABLNodeType.DO);
assertEquals(tok.getLine(), 1);
- assertEquals(tok.getCharPositionInLine(), 1);
+ assertEquals(tok.getCharPositionInLine(), 0);
assertEquals(tok.getEndLine(), 1);
assertEquals(tok.getEndCharPositionInLine(), 2);
@@ -473,7 +473,7 @@ public void testQuotedStringPosition01() {
tok = (ProToken) lexer.nextToken();
assertEquals(tok.getNodeType(), ABLNodeType.QSTRING);
assertEquals(tok.getLine(), 1);
- assertEquals(tok.getCharPositionInLine(), 15);
+ assertEquals(tok.getCharPositionInLine(), 14);
assertEquals(tok.getEndLine(), 1);
// The important test here, end column has to be 16 even when followed by ':'
assertEquals(tok.getEndCharPositionInLine(), 16);
@@ -482,7 +482,7 @@ public void testQuotedStringPosition01() {
tok = (ProToken) lexer.nextToken();
assertEquals(tok.getNodeType(), ABLNodeType.LEXCOLON);
assertEquals(tok.getLine(), 1);
- assertEquals(tok.getCharPositionInLine(), 17);
+ assertEquals(tok.getCharPositionInLine(), 16);
assertEquals(tok.getEndLine(), 1);
assertEquals(tok.getEndCharPositionInLine(), 17);
}
@@ -494,7 +494,7 @@ public void testQuotedStringPosition02() {
ProToken tok = (ProToken) lexer.nextToken();
assertEquals(tok.getNodeType(), ABLNodeType.DO);
assertEquals(tok.getLine(), 1);
- assertEquals(tok.getCharPositionInLine(), 1);
+ assertEquals(tok.getCharPositionInLine(), 0);
assertEquals(tok.getEndLine(), 1);
assertEquals(tok.getEndCharPositionInLine(), 2);
@@ -510,7 +510,7 @@ public void testQuotedStringPosition02() {
tok = (ProToken) lexer.nextToken();
assertEquals(tok.getNodeType(), ABLNodeType.QSTRING);
assertEquals(tok.getLine(), 1);
- assertEquals(tok.getCharPositionInLine(), 15);
+ assertEquals(tok.getCharPositionInLine(), 14);
assertEquals(tok.getEndLine(), 1);
assertEquals(tok.getEndCharPositionInLine(), 16);
@@ -520,7 +520,7 @@ public void testQuotedStringPosition02() {
tok = (ProToken) lexer.nextToken();
assertEquals(tok.getNodeType(), ABLNodeType.LEXCOLON);
assertEquals(tok.getLine(), 1);
- assertEquals(tok.getCharPositionInLine(), 18);
+ assertEquals(tok.getCharPositionInLine(), 17);
assertEquals(tok.getEndLine(), 1);
assertEquals(tok.getEndCharPositionInLine(), 18);
}
@@ -532,13 +532,13 @@ public void testQuotedStringPosition03() {
ProToken tok = (ProToken) lexer.nextToken();
assertEquals(tok.getNodeType(), ABLNodeType.QSTRING);
assertEquals(tok.getLine(), 1);
- assertEquals(tok.getCharPositionInLine(), 1);
+ assertEquals(tok.getCharPositionInLine(), 0);
assertEquals(tok.getEndLine(), 1);
assertEquals(tok.getEndCharPositionInLine(), 10);
tok = (ProToken) lexer.nextToken();
assertEquals(tok.getNodeType(), ABLNodeType.PERIOD);
assertEquals(tok.getLine(), 1);
- assertEquals(tok.getCharPositionInLine(), 11);
+ assertEquals(tok.getCharPositionInLine(), 10);
assertEquals(tok.getEndLine(), 1);
assertEquals(tok.getEndCharPositionInLine(), 11);
}
@@ -550,13 +550,13 @@ public void testQuotedStringPosition04() {
ProToken tok = (ProToken) lexer.nextToken();
assertEquals(tok.getNodeType(), ABLNodeType.QSTRING);
assertEquals(tok.getLine(), 1);
- assertEquals(tok.getCharPositionInLine(), 1);
+ assertEquals(tok.getCharPositionInLine(), 0);
assertEquals(tok.getEndLine(), 1);
assertEquals(tok.getEndCharPositionInLine(), 6);
tok = (ProToken) lexer.nextToken();
assertEquals(tok.getNodeType(), ABLNodeType.PERIOD);
assertEquals(tok.getLine(), 1);
- assertEquals(tok.getCharPositionInLine(), 7);
+ assertEquals(tok.getCharPositionInLine(), 6);
assertEquals(tok.getEndLine(), 1);
assertEquals(tok.getEndCharPositionInLine(), 7);
}
@@ -568,13 +568,13 @@ public void testQuotedStringPosition05() {
ProToken tok = (ProToken) lexer.nextToken();
assertEquals(tok.getNodeType(), ABLNodeType.QSTRING);
assertEquals(tok.getLine(), 1);
- assertEquals(tok.getCharPositionInLine(), 1);
+ assertEquals(tok.getCharPositionInLine(), 0);
assertEquals(tok.getEndLine(), 1);
assertEquals(tok.getEndCharPositionInLine(), 8);
tok = (ProToken) lexer.nextToken();
assertEquals(tok.getNodeType(), ABLNodeType.PERIOD);
assertEquals(tok.getLine(), 1);
- assertEquals(tok.getCharPositionInLine(), 9);
+ assertEquals(tok.getCharPositionInLine(), 8);
assertEquals(tok.getEndLine(), 1);
assertEquals(tok.getEndCharPositionInLine(), 9);
}
@@ -686,7 +686,7 @@ public void testWritableTokens() {
assertNotNull(tok);
assertTrue(tok instanceof WritableProToken);
assertEquals(tok.getLine(), 1);
- assertEquals(tok.getCharPositionInLine(), 3);
+ assertEquals(tok.getCharPositionInLine(), 2);
WritableProToken tok2 = (WritableProToken) tok;
tok2.setLine(5);
tok2.setCharPositionInLine(4);
diff --git a/proparse/src/test/java/org/prorefactor/proparse/ExpressionEngineTest.java b/proparse/src/test/java/org/prorefactor/proparse/ExpressionEngineTest.java
index 9c536aaf5..028160222 100644
--- a/proparse/src/test/java/org/prorefactor/proparse/ExpressionEngineTest.java
+++ b/proparse/src/test/java/org/prorefactor/proparse/ExpressionEngineTest.java
@@ -18,6 +18,7 @@
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotEquals;
import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import java.io.FileReader;
@@ -47,7 +48,6 @@
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
-import eu.rssw.pct.RCodeInfo.InvalidRCodeException;
import eu.rssw.pct.elements.DataType;
import eu.rssw.pct.elements.ParameterMode;
import eu.rssw.pct.elements.PrimitiveDataType;
@@ -61,43 +61,9 @@ public class ExpressionEngineTest extends AbstractProparseTest {
private RefactorSession session;
@BeforeMethod
- public void setUp() throws IOException, InvalidRCodeException {
+ public void setUp() throws IOException {
session = new RefactorSession(new UnitTestProparseSettings(), new SportsSchema());
- // For testObjectAttribute02
- TypeInfo typeInfo01 = new TypeInfo("rssw.test.Class02", false, false, "Progress.Lang.Object", "");
- typeInfo01.addProperty(new PropertyElement("p1", false, DataType.CHARACTER));
- typeInfo01.addVariable(new VariableElement("v1", DataType.LONGCHAR));
- session.injectTypeInfo(typeInfo01);
-
- // For testObjectMethod03
- TypeInfo typeInfo02 = new TypeInfo("rssw.test.Class03", false, false, "Progress.Lang.Object", "");
- typeInfo02.addMethod(new MethodElement("m1", false, DataType.VOID));
- typeInfo02.addMethod(new MethodElement("m2", false, DataType.INT64));
- session.injectTypeInfo(typeInfo02);
-
- // For testStaticMethod
- TypeInfo typeInfo03 = new TypeInfo("rssw.test.Class04", false, false, "Progress.Lang.Object", "");
- typeInfo03.addMethod(new MethodElement("m1", true, DataType.CHARACTER));
- typeInfo03.addMethod(new MethodElement("m2", true, DataType.INTEGER));
- typeInfo03.addMethod(new MethodElement("m2", true, DataType.INT64, //
- new Parameter(1, "prm1", 0, ParameterMode.INPUT, DataType.INTEGER)));
- session.injectTypeInfo(typeInfo03);
-
- // Overloaded methods
- TypeInfo typeInfo04 = new TypeInfo("rssw.test.Class05", false, false, "Progress.Lang.Object", "");
- typeInfo04.addMethod(new MethodElement("over01", true, DataType.CHARACTER));
- typeInfo04.addMethod(new MethodElement("over01", true, DataType.VOID, new Parameter(1, "prm1", 0, ParameterMode.INPUT, DataType.INTEGER)));
- typeInfo04.addMethod(new MethodElement("over01", true, DataType.INTEGER, new Parameter(1, "prm1", 0, ParameterMode.INPUT, DataType.CHARACTER)));
- typeInfo04.addMethod(new MethodElement("over01", true, DataType.INT64, //
- new Parameter(1, "prm1", 0, ParameterMode.INPUT, DataType.CHARACTER), //
- new Parameter(2, "prm2", 0, ParameterMode.INPUT, DataType.CHARACTER)));
- session.injectTypeInfo(typeInfo04);
-
- // For catalog
- TypeInfo typeInfo05 = new TypeInfo("rssw.MyTestClassCatalog", false, false, "System.Windows.Forms.Control", "");
- session.injectTypeInfo(typeInfo05);
-
// Inject content of catalog.json
try (Reader reader = new FileReader("src/test/resources/catalog.json")) {
session.injectClassesFromCatalog(reader);
@@ -368,6 +334,14 @@ public void testObjectAttribute01() {
assertEquals(exp.getDataType().getClassName(), "Progress.Lang.Object");
}
+ @BeforeMethod(dependsOnMethods = "setUp")
+ public void beforeObjectAttribute02() {
+ TypeInfo typeInfo = new TypeInfo("rssw.test.Class02", false, false, "Progress.Lang.Object", "");
+ typeInfo.addProperty(new PropertyElement("p1", false, DataType.CHARACTER));
+ typeInfo.addVariable(new VariableElement("v1", DataType.LONGCHAR));
+ session.injectTypeInfo(typeInfo);
+ }
+
@Test
public void testObjectAttribute02() {
ParseUnit unit = getParseUnit(
@@ -437,6 +411,16 @@ public void testEnumValues02() {
assertEquals(exp2.getDataType().getClassName(), "Progress.Reflect.AccessMode");
}
+ @BeforeMethod(dependsOnMethods = "setUp")
+ public void beforeStaticMethod() {
+ TypeInfo typeInfo = new TypeInfo("rssw.test.Class04", false, false, "Progress.Lang.Object", "");
+ typeInfo.addMethod(new MethodElement("m1", true, DataType.CHARACTER));
+ typeInfo.addMethod(new MethodElement("m2", true, DataType.INTEGER));
+ typeInfo.addMethod(new MethodElement("m2", true, DataType.INT64, //
+ new Parameter(1, "prm1", 0, ParameterMode.INPUT, DataType.INTEGER)));
+ session.injectTypeInfo(typeInfo);
+ }
+
@Test
public void testStaticMethod01() {
String sourceCode = "message rssw.test.Class04:m1(). "
@@ -492,10 +476,17 @@ public void testObjectMethod() {
assertEquals(exp2.getDataType(), DataType.NOT_COMPUTED);
}
+ @BeforeMethod(dependsOnMethods = "setUp")
+ public void beforeObjectMethod02() {
+ TypeInfo typeInfo = new TypeInfo("rssw.pct.Class02", false, false, "Progress.Lang.Object", "");
+ typeInfo.addMethod(new MethodElement("m1", false, DataType.VOID));
+ session.injectTypeInfo(typeInfo);
+ }
+
@Test
public void testObjectMethod02() {
- ParseUnit unit = getParseUnit("class rssw.pct: method void m1(): toString(). foobar(). end method. end class.",
- session);
+ ParseUnit unit = getParseUnit(
+ "class rssw.pct.Class02: method void m1(): toString(). foobar(). end method. end class.", session);
unit.treeParser01();
List nodes = unit.getTopNode().queryExpressions();
@@ -503,34 +494,113 @@ public void testObjectMethod02() {
assertTrue(nodes.get(0) instanceof LocalMethodCallNode);
LocalMethodCallNode exp = (LocalMethodCallNode) nodes.get(0);
+ assertNotNull(exp.getTypeInfo());
+ assertNotNull(exp.getMethodElement());
+ assertEquals(exp.getTypeInfo().getTypeName(), "Progress.Lang.Object");
assertEquals(exp.getMethodName(), "toString");
assertEquals(exp.getDataType(), DataType.CHARACTER);
assertTrue(nodes.get(1) instanceof LocalMethodCallNode);
LocalMethodCallNode exp2 = (LocalMethodCallNode) nodes.get(1);
+ assertNull(exp2.getMethodElement());
+ assertNull(exp2.getTypeInfo());
assertEquals(exp2.getMethodName(), "foobar");
assertEquals(exp2.getDataType(), DataType.NOT_COMPUTED);
}
+ @BeforeMethod(dependsOnMethods = "setUp")
+ public void beforeObjectMethod03() {
+ TypeInfo typeInfo = new TypeInfo("rssw.test.Class03", false, false, "Progress.Lang.Object", "");
+ typeInfo.addMethod(new MethodElement("m1", false, DataType.VOID));
+ typeInfo.addMethod(new MethodElement("m2", false, DataType.INT64));
+ session.injectTypeInfo(typeInfo);
+ }
+
@Test
public void testObjectMethod03() {
ParseUnit unit = getParseUnit(
- "class rssw.test.Class03: method void m1(): this-object:m2(). super:toString(). end method. method int64 m2(): return 0. end method. end class.",
+ "class rssw.test.Class03: method void m1(): this-object:m2(). super:toString(). super:unknown(). end method. method int64 m2(): return 0. end method. end class.",
session);
unit.treeParser01();
List nodes = unit.getTopNode().queryExpressions();
- assertEquals(nodes.size(), 3);
+ assertEquals(nodes.size(), 4);
assertTrue(nodes.get(0) instanceof MethodCallNode);
MethodCallNode exp = (MethodCallNode) nodes.get(0);
+ assertNotNull(exp.getMethodElement());
+ assertEquals(exp.getTypeInfo().getTypeName(), "rssw.test.Class03");
assertEquals(exp.getMethodName(), "m2");
assertEquals(exp.getDataType(), DataType.INT64);
assertTrue(nodes.get(1) instanceof MethodCallNode);
MethodCallNode exp2 = (MethodCallNode) nodes.get(1);
+ assertEquals(exp2.getTypeInfo().getTypeName(), "Progress.Lang.Object");
+ assertNotNull(exp2.getMethodElement());
assertEquals(exp2.getMethodName(), "toString");
assertEquals(exp2.getDataType(), DataType.CHARACTER);
+
+ assertTrue(nodes.get(2) instanceof MethodCallNode);
+ MethodCallNode exp3 = (MethodCallNode) nodes.get(2);
+ assertNull(exp3.getMethodElement());
+ assertNull(exp3.getTypeInfo());
+ assertEquals(exp3.getMethodName(), "unknown");
+ assertEquals(exp3.getDataType(), DataType.NOT_COMPUTED);
+ }
+
+ @BeforeMethod(dependsOnMethods = "setUp")
+ public void beforeObjectMethod04() {
+ TypeInfo typeInfo = new TypeInfo("rssw.test.Class06", false, false, "Progress.Lang.Object", "");
+ typeInfo.addMethod(new MethodElement("m1", false, DataType.VOID));
+ typeInfo.addMethod(new MethodElement("m2", false, DataType.HANDLE));
+ session.injectTypeInfo(typeInfo);
+ }
+
+ @Test
+ public void testObjectMethod04() {
+ ParseUnit unit = getParseUnit("class rssw.test.Class06: " //
+ + "method void m1():" //
+ + " m2():add-super-procedure(xx). " //
+ + "end method. " //
+ + "method handle m2():" //
+ + " return session. " //
+ + "end method. " //
+ + "end class.", session);
+ unit.treeParser01();
+
+ List nodes = unit.getTopNode().queryExpressions();
+ assertEquals(nodes.size(), 2);
+
+ assertTrue(nodes.get(0) instanceof MethodCallNode);
+ MethodCallNode exp = (MethodCallNode) nodes.get(0);
+ assertEquals(exp.getMethodName(), "add-super-procedure");
+ assertEquals(exp.getDataType(), DataType.LOGICAL);
+ }
+
+ @Test
+ public void testObjectMethod05() {
+ ParseUnit unit = getParseUnit("class rssw.test.Class07: " //
+ + "constructor Class07():" //
+ + " this-object(1). " //
+ + "end constructor. " //
+ + "constructor Class07(xx as int):" //
+ + " super(1). " //
+ + "end constructor. " //
+ + "end class.", session);
+ unit.treeParser01();
+
+ List nodes = unit.getTopNode().queryExpressions();
+ assertEquals(nodes.size(), 2);
+
+ assertTrue(nodes.get(0) instanceof MethodCallNode);
+ MethodCallNode exp = (MethodCallNode) nodes.get(0);
+ assertNull(exp.getMethodElement()); // Currently not available
+ assertEquals(exp.getDataType().getClassName(), "rssw.test.Class07");
+
+ assertTrue(nodes.get(1) instanceof MethodCallNode);
+ MethodCallNode exp2 = (MethodCallNode) nodes.get(0);
+ assertNull(exp2.getMethodElement()); // Currently not available
+ assertEquals(exp2.getDataType().getClassName(), "rssw.test.Class07");
}
@Test
@@ -720,6 +790,20 @@ public void testArrayGetExpressions02() {
assertTrue(((ArrayReferenceNode) exp).getOffsetExpression() instanceof ConstantNode);
}
+ @BeforeMethod(dependsOnMethods = "setUp")
+ public void beforeOverloadedMethodCall() {
+ TypeInfo typeInfo = new TypeInfo("rssw.test.Class05", false, false, "Progress.Lang.Object", "");
+ typeInfo.addMethod(new MethodElement("over01", true, DataType.CHARACTER));
+ typeInfo.addMethod(new MethodElement("over01", true, DataType.VOID,
+ new Parameter(1, "prm1", 0, ParameterMode.INPUT, DataType.INTEGER)));
+ typeInfo.addMethod(new MethodElement("over01", true, DataType.INTEGER,
+ new Parameter(1, "prm1", 0, ParameterMode.INPUT, DataType.CHARACTER)));
+ typeInfo.addMethod(new MethodElement("over01", true, DataType.INT64, //
+ new Parameter(1, "prm1", 0, ParameterMode.INPUT, DataType.CHARACTER), //
+ new Parameter(2, "prm2", 0, ParameterMode.INPUT, DataType.CHARACTER)));
+ session.injectTypeInfo(typeInfo);
+ }
+
@Test
public void testOverloadedMethodCall01() {
String sourceCode = "def var var1 as rssw.test.Class05. "
@@ -835,6 +919,12 @@ public void testEvent01() {
assertEquals(exp2.getDataType().getPrimitive(), PrimitiveDataType.VOID);
}
+ @BeforeMethod(dependsOnMethods = "setUp")
+ public void beforeCatalog01() {
+ TypeInfo typeInfo = new TypeInfo("rssw.MyTestClassCatalog", false, false, "System.Windows.Forms.Control", "");
+ session.injectTypeInfo(typeInfo);
+ }
+
@Test
public void testCatalog01() {
String sourceCode = "class rssw.MyTestClassCatalog inherits System.Windows.Forms.Control: "
@@ -854,4 +944,30 @@ public void testCatalog01() {
IExpression exp2 = nodes.get(1);
assertEquals(exp2.getDataType().getPrimitive(), PrimitiveDataType.INTEGER);
}
+
+ @BeforeMethod(dependsOnMethods = "setUp")
+ public void beforeSignature01() {
+ TypeInfo typeInfo = new TypeInfo("rssw.test.FooClass01", false, false, "Progress.Lang.Object", "");
+ typeInfo.addMethod(new MethodElement("Foo", false, DataType.CHARACTER, //
+ new Parameter(1, "prm1", 0, ParameterMode.INPUT_OUTPUT, DataType.CHARACTER)));
+ session.injectTypeInfo(typeInfo);
+ }
+
+ @Test
+ public void testSignature01() {
+ String sourceCode = "class rssw.test.FooClass01:"
+ + " constructor FooClass01( ):"
+ + " this-object:Foo('')."
+ + " end constructor."
+ + " method public character Foo(input-output pcTest as character):"
+ + " end method. "
+ + "end class.";
+ ParseUnit unit01 = getParseUnit(sourceCode, session);
+ unit01.treeParser01();
+
+ List nodes = unit01.getTopNode().queryExpressions();
+ assertEquals(nodes.size(), 1);
+ IExpression exp1 = nodes.get(0);
+ assertEquals(exp1.getDataType().getPrimitive(), PrimitiveDataType.CHARACTER);
+ }
}
diff --git a/proparse/src/test/java/org/prorefactor/proparse/PostLexerTest.java b/proparse/src/test/java/org/prorefactor/proparse/PostLexerTest.java
index fc8751c58..480d5a3b6 100644
--- a/proparse/src/test/java/org/prorefactor/proparse/PostLexerTest.java
+++ b/proparse/src/test/java/org/prorefactor/proparse/PostLexerTest.java
@@ -44,7 +44,7 @@
import com.google.common.base.Charsets;
public class PostLexerTest extends AbstractProparseTest {
- private final static String SRC_DIR = "src/test/resources/data/lexer";
+ private static final String SRC_DIR = "src/test/resources/data/lexer";
private RefactorSession session;
@@ -307,7 +307,7 @@ public void testXCode1() {
ProToken tok = (ProToken) nextVisibleToken(src);
assertEquals(tok.getNodeType(), ABLNodeType.MESSAGE);
assertEquals(tok.getLine(), 2);
- assertEquals(tok.getCharPositionInLine(), 1);
+ assertEquals(tok.getCharPositionInLine(), 0);
assertEquals(tok.getEndLine(), 2);
assertEquals(tok.getEndCharPositionInLine(), 7);
@@ -329,7 +329,7 @@ public void testXCode2() {
ProToken tok = (ProToken) nextVisibleToken(src);
assertEquals(tok.getNodeType(), ABLNodeType.MESSAGE);
assertEquals(tok.getLine(), 2);
- assertEquals(tok.getCharPositionInLine(), 1);
+ assertEquals(tok.getCharPositionInLine(), 0);
assertEquals(tok.getEndLine(), 2);
assertEquals(tok.getEndCharPositionInLine(), 7);
@@ -365,7 +365,7 @@ public void testXCode4() {
tok = (ProToken) src.nextToken();
assertEquals(tok.getNodeType(), ABLNodeType.QSTRING);
assertEquals(tok.getLine(), 1);
- assertEquals(tok.getCharPositionInLine(), 27);
+ assertEquals(tok.getCharPositionInLine(), 26);
assertEquals(tok.getEndLine(), 1);
assertEquals(tok.getEndCharPositionInLine(), 33);
@@ -377,7 +377,7 @@ public void testXCode4() {
tok = (ProToken) src.nextToken();
assertEquals(tok.getNodeType(), ABLNodeType.QSTRING);
assertEquals(tok.getLine(), 1);
- assertEquals(tok.getCharPositionInLine(), 72);
+ assertEquals(tok.getCharPositionInLine(), 71);
assertEquals(tok.getEndLine(), 1);
assertEquals(tok.getEndCharPositionInLine(), 84);
}
diff --git a/proparse/src/test/java/org/prorefactor/proparse/TokenListTest.java b/proparse/src/test/java/org/prorefactor/proparse/TokenListTest.java
index d8e8db837..fd20f61c6 100644
--- a/proparse/src/test/java/org/prorefactor/proparse/TokenListTest.java
+++ b/proparse/src/test/java/org/prorefactor/proparse/TokenListTest.java
@@ -57,7 +57,7 @@ public void testTokenList02() {
assertEquals(tok.getNodeType(), ABLNodeType.ID);
assertEquals(tok.getText(), "Progress.Security.PAMStatus");
assertEquals(tok.getLine(), 1);
- assertEquals(tok.getCharPositionInLine(), 1);
+ assertEquals(tok.getCharPositionInLine(), 0);
assertEquals(tok.getEndLine(), 1);
assertEquals(tok.getEndCharPositionInLine(), 27);
assertEquals(tok.getChannel(), 0);
@@ -71,7 +71,7 @@ public void testTokenList02() {
assertEquals(tok.getNodeType(), ABLNodeType.ID);
assertEquals(tok.getText(), "Progress.Security.PAMStatus");
assertEquals(tok.getLine(), 2);
- assertEquals(tok.getCharPositionInLine(), 1);
+ assertEquals(tok.getCharPositionInLine(), 0);
assertEquals(tok.getEndLine(), 2);
assertEquals(tok.getEndCharPositionInLine(), 27);
assertEquals(tok.getChannel(), 0);
@@ -86,7 +86,7 @@ public void testTokenList02() {
assertEquals(tok.getNodeType(), ABLNodeType.ID);
assertEquals(tok.getText(), "Progress.Security.PAMStatus");
assertEquals(tok.getLine(), 3);
- assertEquals(tok.getCharPositionInLine(), 1);
+ assertEquals(tok.getCharPositionInLine(), 0);
assertEquals(tok.getEndLine(), 3);
assertEquals(tok.getEndCharPositionInLine(), 27);
assertEquals(((ProToken) src.nextToken()).getNodeType(), ABLNodeType.WS);
@@ -108,7 +108,7 @@ public void testTokenList02() {
assertEquals(tok.getNodeType(), ABLNodeType.ID);
assertEquals(tok.getText(), "Progress.117x.clsName");
assertEquals(tok.getLine(), 7);
- assertEquals(tok.getCharPositionInLine(), 1);
+ assertEquals(tok.getCharPositionInLine(), 0);
assertEquals(tok.getEndLine(), 7);
assertEquals(tok.getEndCharPositionInLine(), 21);
assertEquals(tok.getChannel(), 0);
diff --git a/proparse/src/test/resources/data/preprocessor/preprocessor25-01.i b/proparse/src/test/resources/data/preprocessor/preprocessor25-01.i
new file mode 100644
index 000000000..7ce83f216
--- /dev/null
+++ b/proparse/src/test/resources/data/preprocessor/preprocessor25-01.i
@@ -0,0 +1,3 @@
+DEFINE VARIABLE xxx AS CHARACTER NO-UNDO.
+
+ASSIGN xxx = {&DefaultValue}.
diff --git a/proparse/src/test/resources/data/preprocessor/preprocessor25.p b/proparse/src/test/resources/data/preprocessor/preprocessor25.p
new file mode 100644
index 000000000..ab32f804b
--- /dev/null
+++ b/proparse/src/test/resources/data/preprocessor/preprocessor25.p
@@ -0,0 +1 @@
+{ preprocessor/preprocessor25-01.i &DefaultValue=""-"" }
diff --git a/proparse/src/test/resources/data/rssw/pct/TestThisObject.cls b/proparse/src/test/resources/data/rssw/pct/TestThisObject.cls
index fa181861a..643d48565 100644
--- a/proparse/src/test/resources/data/rssw/pct/TestThisObject.cls
+++ b/proparse/src/test/resources/data/rssw/pct/TestThisObject.cls
@@ -8,6 +8,8 @@ CLASS rssw.pct.TestThisObject:
DEFINE PUBLIC PROPERTY prop2 AS INTEGER NO-UNDO GET. PRIVATE SET.
DEFINE PUBLIC PROPERTY prop3 AS Progress.Lang.Object NO-UNDO GET. PRIVATE SET.
DEFINE PRIVATE VARIABLE var1 AS MEMPTR NO-UNDO.
+ DEFINE PRIVATE STATIC VARIABLE var2 AS INTEGER NO-UNDO.
+ DEFINE PRIVATE VARIABLE var3 AS INTEGER NO-UNDO.
METHOD PUBLIC VOID method1():
THIS-OBJECT:prop1 = 123.
@@ -20,12 +22,20 @@ CLASS rssw.pct.TestThisObject:
END METHOD.
METHOD PUBLIC VOID method3():
- prop3:NEXT-SIBLING = 789.
+ prop3:NEXT-SIBLING = 789. // Yes, that doesn't compile, but we just need a test case
MESSAGE prop3:NEXT-SIBLING.
END METHOD.
METHOD PUBLIC VOID method4():
- COPY-LOB FROM "xxx.txt" TO THIS-OBJECT:var1.
+ COPY-LOB FROM FILE "xxx.txt" TO THIS-OBJECT:var1.
+ END METHOD.
+
+ METHOD PUBLIC VOID method5():
+ VAR rssw.pct.TestThisObject x2.
+ rssw.pct.TestThisObject:var2 = 1.
+ TestThisObject:var2 = 1.
+ x2:var3 = 0.
+ message x2:var3.
END METHOD.
END CLASS.
diff --git a/proparse/src/test/resources/treeparser03/test42.p b/proparse/src/test/resources/treeparser03/test42.p
new file mode 100644
index 000000000..74add9f3d
--- /dev/null
+++ b/proparse/src/test/resources/treeparser03/test42.p
@@ -0,0 +1,4 @@
+define query qry for customer.
+open query qry for each customer.
+get first qry. // Missing lock as it's not specified in the open query statement
+get next qry. // Ditto
diff --git a/proparse/src/test/resources/treeparser06-expect/test01.p b/proparse/src/test/resources/treeparser06-expect/test01.p
index a945d5269..9fd45f37b 100644
--- a/proparse/src/test/resources/treeparser06-expect/test01.p
+++ b/proparse/src/test/resources/treeparser06-expect/test01.p
@@ -1,49 +1,49 @@
PROGRAM_ROOT F0/0:0 -- Block -- Scope
- PROCEDURE F0/1:1 -- Block -- Scope
- IF F0/2:3
- THEN F0/2:11
- DO F0/2:16 -- Block
- IF F0/3:5
- THEN F0/3:33
- DO F0/3:38 -- Block
- MESSAGE F0/4:7
- ELSE F0/6:5
- MESSAGE F0/6:10
- MESSAGE F0/8:3
- DEFINE F0/11:1
- CASE F0/12:3
- WHEN F0/13:5
- THEN F0/13:12
- RETURN F0/13:17
- WHEN F0/14:5
- THEN F0/14:12
- RETURN F0/14:17
- WHEN F0/15:5
- THEN F0/15:12
- DO F0/15:17 -- Block
- MESSAGE F0/16:7
- RETURN F0/17:7
- OTHERWISE F0/19:5
- RETURN F0/19:15
- IF F0/22:1
- THEN F0/22:9
- CASE F0/23:3
- WHEN F0/24:5
- THEN F0/24:12
- RETURN F0/24:17
- WHEN F0/25:5
- THEN F0/25:12
- RETURN F0/25:17
- OTHERWISE F0/26:5
- RETURN F0/26:15
- ELSE F0/28:1
- CASE F0/29:3
- WHEN F0/30:5
- THEN F0/30:12
- RETURN F0/30:17
- WHEN F0/31:5
- THEN F0/31:12
- RETURN F0/31:17
- OTHERWISE F0/32:5
- RETURN F0/32:15
+ PROCEDURE F0/1:0 -- Block -- Scope
+ IF F0/2:2
+ THEN F0/2:10
+ DO F0/2:15 -- Block
+ IF F0/3:4
+ THEN F0/3:32
+ DO F0/3:37 -- Block
+ MESSAGE F0/4:6
+ ELSE F0/6:4
+ MESSAGE F0/6:9
+ MESSAGE F0/8:2
+ DEFINE F0/11:0
+ CASE F0/12:2
+ WHEN F0/13:4
+ THEN F0/13:11
+ RETURN F0/13:16
+ WHEN F0/14:4
+ THEN F0/14:11
+ RETURN F0/14:16
+ WHEN F0/15:4
+ THEN F0/15:11
+ DO F0/15:16 -- Block
+ MESSAGE F0/16:6
+ RETURN F0/17:6
+ OTHERWISE F0/19:4
+ RETURN F0/19:14
+ IF F0/22:0
+ THEN F0/22:8
+ CASE F0/23:2
+ WHEN F0/24:4
+ THEN F0/24:11
+ RETURN F0/24:16
+ WHEN F0/25:4
+ THEN F0/25:11
+ RETURN F0/25:16
+ OTHERWISE F0/26:4
+ RETURN F0/26:14
+ ELSE F0/28:0
+ CASE F0/29:2
+ WHEN F0/30:4
+ THEN F0/30:11
+ RETURN F0/30:16
+ WHEN F0/31:4
+ THEN F0/31:11
+ RETURN F0/31:16
+ OTHERWISE F0/32:4
+ RETURN F0/32:14
diff --git a/proparse/src/test/resources/treeparser06-expect/test02.cls b/proparse/src/test/resources/treeparser06-expect/test02.cls
index 5e434de12..9d8a4be87 100644
--- a/proparse/src/test/resources/treeparser06-expect/test02.cls
+++ b/proparse/src/test/resources/treeparser06-expect/test02.cls
@@ -1,18 +1,18 @@
PROGRAM_ROOT F0/0:0 -- Block -- Scope
- CLASS F0/1:1
- DEFINE F0/2:3
- DEFINE F0/3:3
- DEFINE F0/4:3
- CONSTRUCTOR F0/10:3 -- Block -- Scope
- MESSAGE F0/11:5
- MESSAGE F0/12:5
- METHOD F0/15:3 -- Block -- Scope
- DO F0/16:5 -- Block
- MESSAGE F0/17:7
- DO F0/18:7 -- Block
- REPEAT F0/19:9 -- Block
- MESSAGE F0/20:11
- FINALLY F0/24:5
- MESSAGE F0/25:7
- MESSAGE F0/26:7
+ CLASS F0/1:0
+ DEFINE F0/2:2
+ DEFINE F0/3:2
+ DEFINE F0/4:2
+ CONSTRUCTOR F0/10:2 -- Block -- Scope
+ MESSAGE F0/11:4
+ MESSAGE F0/12:4
+ METHOD F0/15:2 -- Block -- Scope
+ DO F0/16:4 -- Block
+ MESSAGE F0/17:6
+ DO F0/18:6 -- Block
+ REPEAT F0/19:8 -- Block
+ MESSAGE F0/20:10
+ FINALLY F0/24:4
+ MESSAGE F0/25:6
+ MESSAGE F0/26:6
diff --git a/proparse/src/test/resources/treeparser06-expect/test03.p b/proparse/src/test/resources/treeparser06-expect/test03.p
index ff7909d24..61e1e3589 100644
--- a/proparse/src/test/resources/treeparser06-expect/test03.p
+++ b/proparse/src/test/resources/treeparser06-expect/test03.p
@@ -1,9 +1,9 @@
PROGRAM_ROOT F0/0:0 -- Block -- Scope
- FOR F0/1:1 -- Block
- UPDATE F0/2:5
- DISPLAY F0/4:8
- IF F0/5:8
- THEN F0/5:39
- MESSAGE F0/6:12
- MESSAGE F0/8:5
+ FOR F0/1:0 -- Block
+ UPDATE F0/2:4
+ DISPLAY F0/4:7
+ IF F0/5:7
+ THEN F0/5:38
+ MESSAGE F0/6:11
+ MESSAGE F0/8:4
diff --git a/proparse/src/test/resources/treeparser06-expect/test04.p b/proparse/src/test/resources/treeparser06-expect/test04.p
index 0a7fc0ea0..ccdcdf354 100644
--- a/proparse/src/test/resources/treeparser06-expect/test04.p
+++ b/proparse/src/test/resources/treeparser06-expect/test04.p
@@ -1,8 +1,8 @@
PROGRAM_ROOT F0/0:0 -- Block -- Scope
- ON F0/1:1 -- Block -- Scope
- DO F0/2:1 -- Block
- FIND F0/3:5
- RUN F0/4:5
- ON F0/7:1 -- Block -- Scope
+ ON F0/1:0 -- Block -- Scope
+ DO F0/2:0 -- Block
+ FIND F0/3:4
+ RUN F0/4:4
+ ON F0/7:0 -- Block -- Scope
EXPR_STATEMENT F0/0:0
diff --git a/rcode-reader/pom.xml b/rcode-reader/pom.xml
index 848bc8c92..b00a6b7c3 100644
--- a/rcode-reader/pom.xml
+++ b/rcode-reader/pom.xml
@@ -5,13 +5,12 @@
eu.rssw
sonar-openedge
- 2.29.1
+ 2.30.0
eu.rssw.openedge.rcode
rcode-reader
- rcode-reader
- rcode reader
+ RCode Reader
diff --git a/rcode-reader/src/main/java/eu/rssw/pct/elements/ITypeInfo.java b/rcode-reader/src/main/java/eu/rssw/pct/elements/ITypeInfo.java
index e6711e426..b87cd6783 100644
--- a/rcode-reader/src/main/java/eu/rssw/pct/elements/ITypeInfo.java
+++ b/rcode-reader/src/main/java/eu/rssw/pct/elements/ITypeInfo.java
@@ -23,6 +23,8 @@
import java.util.List;
import java.util.function.Function;
+import org.prorefactor.core.Pair;
+
public interface ITypeInfo {
String getTypeName();
@@ -90,7 +92,7 @@ default boolean isAssignableFrom(String clsName, Function pro
return isAssignableFrom(info.getParentTypeName(), provider);
}
- default IMethodElement getExactMatch(Function provider, String method, DataType... parameters) {
+ default Pair getExactMatch(Function provider, String method, DataType... parameters) {
for (IMethodElement elem : getMethods()) {
if (method.equalsIgnoreCase(elem.getName()) && (elem.getParameters().length == parameters.length)) {
boolean match = true;
@@ -98,7 +100,7 @@ default IMethodElement getExactMatch(Function provider, Strin
match &= elem.getParameters()[zz].getDataType().equals(parameters[zz]);
}
if (match)
- return elem;
+ return Pair.of(this, elem);
}
}
ITypeInfo parent = provider.apply(getParentTypeName());
@@ -108,7 +110,7 @@ default IMethodElement getExactMatch(Function provider, Strin
return null;
}
- default IMethodElement getCompatibleMatch(Function provider, String method, DataType... parameters) {
+ default Pair getCompatibleMatch(Function provider, String method, DataType... parameters) {
for (IMethodElement elem : getMethods()) {
if (method.equalsIgnoreCase(elem.getName()) && (elem.getParameters().length == parameters.length)) {
boolean match = true;
@@ -116,7 +118,7 @@ default IMethodElement getCompatibleMatch(Function provider,
match &= elem.getParameters()[zz].getDataType().isCompatible(parameters[zz], provider);
}
if (match)
- return elem;
+ return Pair.of(this, elem);
}
}
ITypeInfo parent = provider.apply(getParentTypeName());
@@ -126,8 +128,8 @@ default IMethodElement getCompatibleMatch(Function provider,
return null;
}
- default IMethodElement getMethod(Function provider, String method, DataType... parameters) {
- IMethodElement exactMatch = getExactMatch(provider, method, parameters);
+ default Pair getMethod(Function provider, String method, DataType... parameters) {
+ Pair exactMatch = getExactMatch(provider, method, parameters);
if (exactMatch != null)
return exactMatch;
return getCompatibleMatch(provider, method, parameters);
diff --git a/rcode-reader/src/main/java/org/prorefactor/core/Pair.java b/rcode-reader/src/main/java/org/prorefactor/core/Pair.java
new file mode 100644
index 000000000..f808c431b
--- /dev/null
+++ b/rcode-reader/src/main/java/org/prorefactor/core/Pair.java
@@ -0,0 +1,42 @@
+/*
+ * OpenEdge plugin for SonarQube
+ * Copyright (c) 2015-2024 Riverside Software
+ * contact AT riverside DASH software DOT fr
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.prorefactor.core;
+
+public class Pair {
+ private final X o1;
+ private final Y o2;
+
+ public Pair(X o1, Y o2) {
+ this.o1 = o1;
+ this.o2 = o2;
+ }
+
+ public static Pair of(A x, B y) {
+ return new Pair<>(x, y);
+ }
+
+ public X getO1() {
+ return o1;
+ }
+
+ public Y getO2() {
+ return o2;
+ }
+}
diff --git a/rcode-reader/src/test/java/eu/rssw/pct/ITypeInfoTest.java b/rcode-reader/src/test/java/eu/rssw/pct/ITypeInfoTest.java
index 1a14abd88..630aa6f63 100644
--- a/rcode-reader/src/test/java/eu/rssw/pct/ITypeInfoTest.java
+++ b/rcode-reader/src/test/java/eu/rssw/pct/ITypeInfoTest.java
@@ -26,6 +26,7 @@
import java.util.HashMap;
import java.util.function.Function;
+import org.prorefactor.core.Pair;
import org.testng.annotations.Test;
import eu.rssw.pct.elements.BuiltinClasses;
@@ -65,9 +66,10 @@ public void test2() {
assertNotNull(info.getMethod(TYPE_INFO_PROVIDER, "Add", new DataType("Progress.Json.ObjectModel.JsonArray")));
assertNull(info.getMethod(TYPE_INFO_PROVIDER, "Add", new DataType("Progress.Lang.Object")));
- IMethodElement m1 = info.getMethod(TYPE_INFO_PROVIDER, "GetDatetime", DataType.INTEGER, DataType.INTEGER);
- assertNotNull(m1);
- assertEquals(m1.getReturnType(), DataType.DATETIME);
+ Pair val1 = info.getMethod(TYPE_INFO_PROVIDER, "GetDatetime", DataType.INTEGER, DataType.INTEGER);
+ assertNotNull(val1);
+ assertEquals(val1.getO1().getTypeName(), "Progress.Json.ObjectModel.JsonArray");
+ assertEquals(val1.getO2().getReturnType(), DataType.DATETIME);
}
@Test
@@ -95,12 +97,14 @@ public void test4() {
map.put(typeInfo02.getTypeName(), typeInfo02);
// Expected is method from parent class
- IMethodElement m1 = typeInfo02.getMethod(name -> map.get(name), "method1", DataType.INTEGER);
- assertNotNull(m1);
- assertEquals(m1.getReturnType(), DataType.VOID);
+ Pair val1 = typeInfo02.getMethod(map::get, "method1", DataType.INTEGER);
+ assertNotNull(val1);
+ assertEquals(val1.getO1().getTypeName(), "rssw.ParentClass");
+ assertEquals(val1.getO2().getReturnType(), DataType.VOID);
// Expected is method from child class
- IMethodElement m2 = typeInfo02.getMethod(name -> map.get(name), "method1", DataType.INT64);
- assertNotNull(m2);
- assertEquals(m2.getReturnType(), DataType.INTEGER);
+ Pair val2 = typeInfo02.getMethod(map::get, "method1", DataType.INT64);
+ assertNotNull(val2);
+ assertEquals(val2.getO1().getTypeName(), "rssw.ChildClass");
+ assertEquals(val2.getO2().getReturnType(), DataType.INTEGER);
}
}