Skip to content

Commit

Permalink
Add more logging. Add more tests. Fix some tests. Filter out ValueSet…
Browse files Browse the repository at this point in the history
…Refs from hidden identifier checking.
  • Loading branch information
lukedegruchy committed Nov 3, 2023
1 parent 8a468e3 commit 3eb1740
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2202,6 +2202,13 @@ public Expression resolveIdentifier(String identifier, boolean mustResolve) {
// 10: The name of a property on a specific context
// 11: An unresolved identifier error is thrown

final String id = Optional.ofNullable(this.library.getIdentifier()).map(VersionedIdentifier::getId).orElse(null);
if (id != null) {
if ((id.contains("Test") || id.contains("Authori") ) && !identifier.contains("Test")) {
logger.info("identifier: {}, mustResolve: {}", identifier, mustResolve);
}
}

// In a type specifier context, return the identifier as a Literal for resolution as a type by the caller
ResolvedIdentifierList resolvedIdentifierList = new ResolvedIdentifierList();

Expand Down Expand Up @@ -2288,14 +2295,15 @@ public Expression resolveIdentifier(String identifier, boolean mustResolve) {
//getAllMatchedIdentifiers returns any recorded identifier where MatchType is not NONE
List<ResolvedIdentifier> allHiddenCaseMatches = resolvedIdentifierList.getAllMatchedIdentifiers();

if (id != null) {
if (id.contains("Authoring") || id.contains("Hidden") || id.contains("Test")) {
logger.info("resolvedIdentifierList: {}", resolvedIdentifierList.getResolvedIdentifierList().stream().map(match -> "[" + match.getIdentifier() + "] " + match.getResolvedElement().getClass() + " " + match.getMatchType()).collect(Collectors.toSet()));
logger.info("allHiddenCaseMatches: {}", allHiddenCaseMatches.stream().map(match -> "[" + match.getIdentifier() + "] " + match.getResolvedElement().getClass() + " " + match.getMatchType()).collect(Collectors.toSet()));
}
}

//issue warning that multiple matches occurred:
if (! allHiddenCaseMatches.isEmpty()) {
final String id = Optional.ofNullable(this.library.getIdentifier()).map(VersionedIdentifier::getId).orElse(null);
if (id != null) {
if (id.contains("Case") || id.contains("Hidden") || id.contains("Test")) {
logger.info("allHiddenCaseMatches: {}", allHiddenCaseMatches.stream().map(match -> match.getIdentifier() + match.getResolvedElement().getClass() + " " + match.getMatchType()).collect(Collectors.toSet()));
}
}

final Object resolvedElement = allHiddenCaseMatches.get(0).getResolvedElement();

Expand All @@ -2305,6 +2313,7 @@ public Expression resolveIdentifier(String identifier, boolean mustResolve) {
final List<ResolvedIdentifier> filtered = allHiddenCaseMatches.stream()
// LUKETODO: consider filtering out other "Ref"s
.filter(match -> ! (match.getResolvedElement() instanceof OperandRef))
.filter(match -> ! (match.getResolvedElement() instanceof ValueSetRef))
.collect(Collectors.toList());
// final List<ResolvedIdentifier> filtered = allHiddenCaseMatches;
// LUKETODO: what about "NONE"?
Expand Down Expand Up @@ -2336,6 +2345,12 @@ public Expression resolveIdentifier(String identifier, boolean mustResolve) {
throw new IllegalArgumentException(String.format("Could not resolve identifier %s in the current library.", identifier));
}

if (id != null) {
if (id.contains("Test") && ! identifier.contains("Test")) {
logger.info("returning null");
}
}

return null;
}

Expand Down Expand Up @@ -2999,14 +3014,14 @@ private ResolvedIdentifierList resolveQueryResultElements(String identifier) {
IdentifierRef result = new IdentifierRef().withName(identifier);
result.setResultType(query.getResultElementType());
resolvedIdentifierList.addResolvedIdentifier(identifier, identifier, $_THIS, result);
}

// LUKETODO: when we do this with "$this", it results in an IllegalArgumentException because "resolveProperty()" does not consider "$this"
PropertyResolution resolution = resolveProperty(query.getResultElementType(), identifier, false);
if (resolution != null) {
IdentifierRef result = new IdentifierRef().withName(resolution.getName());
result.setResultType(resolution.getType());
resolvedIdentifierList.addExactMatchIdentifier(identifier, applyTargetMap(result, resolution.getTargetMap()));
} else { // LUKETODO: We do this to prevent an error processing "$this" in resolveProperty()
// LUKETODO: when we do this with "$this", it results in an IllegalArgumentException because "resolveProperty()" does not consider "$this"
PropertyResolution resolution = resolveProperty(query.getResultElementType(), identifier, false);
if (resolution != null) {
IdentifierRef result = new IdentifierRef().withName(resolution.getName());
result.setResultType(resolution.getType());
resolvedIdentifierList.addExactMatchIdentifier(identifier, applyTargetMap(result, resolution.getTargetMap()));
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -742,8 +742,17 @@ public void testSoMuchNestingNormal() throws IOException {
}

@Test
public void testSoMuchNestingHiding() throws IOException {
final CqlTranslator translator = TestUtils.runSemanticTest("TestSoMuchNestingHiding.cql", 0);
public void testSoMuchNestingHidingSimple() throws IOException {
final CqlTranslator translator = TestUtils.runSemanticTest("TestSoMuchNestingHidingSimple.cql", -1);
final List<CqlCompilerException> warnings = translator.getWarnings();

// LUKETODO: this doesn't work because "SoMuchNesting" resolves to null in LibraryBuilder.
assertThat(warnings.toString(), translator.getWarnings().size(), is(1));
}

@Test
public void testSoMuchNestingHidingComplex() throws IOException {
final CqlTranslator translator = TestUtils.runSemanticTest("TestSoMuchNestingHidingComplex.cql", -1);
final List<CqlCompilerException> warnings = translator.getWarnings();

Check failure on line 756 in Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/SemanticTests.java

View workflow job for this annotation

GitHub Actions / JUnit Test Report

SemanticTests.testSoMuchNestingHidingSimple

java.lang.AssertionError: [] Expected: is <1> but: was <0>
Raw output
java.lang.AssertionError: []
Expected: is <1>
     but: was <0>
	at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
	at org.cqframework.cql.cql2elm.SemanticTests.testSoMuchNestingHidingSimple(SemanticTests.java:756)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:133)
	at org.testng.internal.TestInvoker.invokeMethod(TestInvoker.java:598)
	at org.testng.internal.TestInvoker.invokeTestMethod(TestInvoker.java:173)
	at org.testng.internal.MethodRunner.runInSequence(MethodRunner.java:46)
	at org.testng.internal.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:824)
	at org.testng.internal.TestInvoker.invokeTestMethods(TestInvoker.java:146)
	at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
	at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:128)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
	at org.testng.TestRunner.privateRun(TestRunner.java:794)
	at org.testng.TestRunner.run(TestRunner.java:596)
	at org.testng.SuiteRunner.runTest(SuiteRunner.java:377)
	at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:371)
	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:332)
	at org.testng.SuiteRunner.run(SuiteRunner.java:276)
	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53)
	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96)
	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1212)
	at org.testng.TestNG.runSuitesLocally(TestNG.java:1134)
	at org.testng.TestNG.runSuites(TestNG.java:1063)
	at org.testng.TestNG.run(TestNG.java:1031)
	at org.gradle.api.internal.tasks.testing.testng.TestNGTestClassProcessor.runTests(TestNGTestClassProcessor.java:145)
	at org.gradle.api.internal.tasks.testing.testng.TestNGTestClassProcessor.stop(TestNGTestClassProcessor.java:92)
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
	at com.sun.proxy.$Proxy5.stop(Unknown Source)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
	at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)

// LUKETODO: we're getting 4 but I'm not sure if they're dupes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,10 @@ public static CqlTranslator runSemanticTest(NamespaceInfo namespaceInfo, String
System.err.printf("(%d,%d): %s%n",
error.getLocator().getStartLine(), error.getLocator().getStartChar(), error.getMessage());
}
assertThat(translator.getErrors().size(), is(expectedErrors));
// We want to defer asserting on errors to the unit test
if (expectedErrors != -1) {
assertThat(translator.getErrors().size(), is(expectedErrors));
}
return translator;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.stream.Collectors;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.assertNotNull;

public class BaseTest {
Expand All @@ -30,7 +31,20 @@ public void testAuthoringPatterns() throws IOException {
, org.cqframework.cql.cql2elm.CqlSemanticException: Case insensitive clashes detected: Identifier for identifiers: [Application of Intermittent Pneumatic Compression Devices (IPC)] resolved as a value set with case insensitive matching.
, org.cqframework.cql.cql2elm.CqlSemanticException: Case insensitive clashes detected: Identifier for identifiers: [Application of Intermittent Pneumatic Compression Devices (IPC)] resolved as a value set with case insensitive matching.
*/
assertThat(translator.getWarnings().toString(), translator.getWarnings().size(), is(0));

// LUKETODO: false positive: "Identifier hiding detected: Identifier in a broader scope hidden: [Diabetes] resolved as a context accessor with exact case matching."
// LUKETODO: possible dupes
assertThat(translator.getWarnings().toString(), translator.getWarnings().size(), is(4));

final List<String> distinct = translator.getWarnings().stream().map(Throwable::getMessage).distinct().collect(Collectors.toList());

assertThat(distinct.size(), is(2));

// LUKETODO: adjust these assertions
final String first = "Case insensitive clashes detected: Identifier for identifiers: [Application of intermittent pneumatic compression devices (IPC)] resolved as a value set with case insensitive matching.\n";
final String second = "Case insensitive clashes detected: Identifier for identifiers: [Application of Intermittent Pneumatic Compression Devices (IPC)] resolved as a value set with case insensitive matching.\n";

assertThat(distinct, containsInAnyOrder(first, second));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.*;

public class BaseTest {
@Test
Expand Down Expand Up @@ -42,7 +43,19 @@ public void testAuthoringPatterns() throws IOException {
*/
CqlTranslator translator = TestUtils.runSemanticTest("qicore/v500/AuthoringPatterns.cql", 0, LibraryBuilder.SignatureLevel.Overloads);

assertThat(translator.getWarnings().toString(), translator.getWarnings().size(), is(0));
// LUKETODO: false positive: "Identifier hiding detected: Identifier in a broader scope hidden: [Diabetes] resolved as a context accessor with exact case matching."
// LUKETODO: possible dupes
assertThat(translator.getWarnings().toString(), translator.getWarnings().size(), is(4));

final List<String> distinct = translator.getWarnings().stream().map(Throwable::getMessage).distinct().collect(Collectors.toList());

assertThat(distinct.size(), is(2));

// LUKETODO: adjust these assertions
final String first = "Case insensitive clashes detected: Identifier for identifiers: [Application of intermittent pneumatic compression devices (IPC)] resolved as a value set with case insensitive matching.\n";
final String second = "Case insensitive clashes detected: Identifier for identifiers: [Application of Intermittent Pneumatic Compression Devices (IPC)] resolved as a value set with case insensitive matching.\n";

assertThat(distinct, containsInAnyOrder(first, second));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,53 +8,53 @@ valueset "ValueSet": '123'
code "Code": 'XYZ' from "CodeSystem"

define "CodeSystemHidden":
({1, 2, 3}) "CodeSystem" return "CodeSystem" //Warn, hides line 3
({1, 2, 3}) "CodeSystem" return "CodeSystem" //Warn, hides line 6

define "CodeSystemHidden2":
({1, 2, 3}) X
let "CodeSystem" : X + 1 return "CodeSystem" //Warn, hides line 3
let "CodeSystem" : X + 1 return "CodeSystem" //Warn, hides line 6

define "ValueSetHidden":
({1, 2, 3}) "ValueSet" return "ValueSet" //Warn, hides line 4
({1, 2, 3}) "ValueSet" return "ValueSet" //Warn, hides line 7

define "ValueSetHidden2":
({1, 2, 3}) X
let "ValueSet" : X + 1 return "ValueSet" //Warn, hides line 4
let "ValueSet" : X + 1 return "ValueSet" //Warn, hides line 7

define "CodeHidden":
({1, 2, 3}) "Code" return "Code" //Warn, hides line 5
({1, 2, 3}) "Code" return "Code" //Warn, hides line 8

define "CodeHidden2":
({1, 2, 3}) X
let "Code" : X + 1 return "Code" //Warn, hides line 5
let "Code" : X + 1 return "Code" //Warn, hides line 8

define "FHIRHelpersHidden":
({1, 2, 3}) "Code" return "Code" //Warn, hides line 7
({1, 2, 3}) "Code" return "Code" //Warn, hides line 8

define "FHIRHelpersHidden2":
({1, 2, 3}) X
let "Code" : X + 1 return "Code" //Warn, hides line 7
let "Code" : X + 1 return "Code" //Warn, hides line 8

define "FHIRHidden":
({1, 2, 3}) FHIR return FHIR //Warn, hides line 9
({1, 2, 3}) FHIR return FHIR //Warn, hides line 3

define "FHIRHidden2":
({1, 2, 3}) X
let FHIR : X + 1 return FHIR //Warn, hides line 9
let FHIR : X + 1 return FHIR //Warn, hides line 3

define "Definition":
({1, 2, 3}) "Definition" return "Definition" //Warn, hides line 46
({1, 2, 3}) "Definition" return "Definition" //Warn, hides line 45

define "AliasHidden":
({1, 2, 3}) "Alias"
let "Alias": "Alias" + 1 // Warn, hides 50
let "Alias": "Alias" + 1 // Warn, hides 49
return "Alias"

define "VariableHidden":
({1, 2, 3}) X
let var : X + 1
return
var varalias
let var : varalias + 2 // Warn, hides 56
let var : varalias + 2 // Warn, hides 55
return varalias

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
library TestSoMuchNestingHiding

define "SoMuchNesting":
({1, 2, 3})
"SoMuchNesting"
return "SoMuchNesting" + 1

0 comments on commit 3eb1740

Please sign in to comment.