Skip to content

Commit

Permalink
Merge pull request #42217 from poorna2152/xml_nav_stmt_2
Browse files Browse the repository at this point in the history
Fix XML navigation result when namespace is declared in a statement after the the expression
  • Loading branch information
KavinduZoysa authored Mar 25, 2024
2 parents 7d8decc + ace31bb commit 71fdc93
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8308,25 +8308,16 @@ public void visit(BLangXMLElementAccess xmlElementAccess) {
}

private ArrayList<BLangExpression> expandFilters(List<BLangXMLElementFilter> filters) {
Map<Name, BXMLNSSymbol> nameBXMLNSSymbolMap = symResolver.resolveAllNamespaces(env);
BXMLNSSymbol defaultNSSymbol = nameBXMLNSSymbolMap.get(names.fromString(XMLConstants.DEFAULT_NS_PREFIX));
String defaultNS = defaultNSSymbol != null ? defaultNSSymbol.namespaceURI : null;

ArrayList<BLangExpression> args = new ArrayList<>();
for (BLangXMLElementFilter filter : filters) {
BSymbol nsSymbol = symResolver.lookupSymbolInPrefixSpace(env, names.fromString(filter.namespace));
if (nsSymbol == symTable.notFoundSymbol) {
if (defaultNS != null && !filter.name.equals("*")) {
String expandedName = createExpandedQName(defaultNS, filter.name);
args.add(createStringLiteral(filter.elemNamePos, expandedName));
} else {
args.add(createStringLiteral(filter.elemNamePos, filter.name));
}
BSymbol nsSymbol = filter.namespaceSymbol;
String filterName = filter.name;
if (nsSymbol != null &&
!(filter.namespace.equals(XMLConstants.DEFAULT_NS_PREFIX) && filterName.equals("*"))) {
String expandedName = createExpandedQName(((BXMLNSSymbol) nsSymbol).namespaceURI, filterName);
args.add(createStringLiteral(filter.elemNamePos, expandedName));
} else {
BXMLNSSymbol bxmlnsSymbol = (BXMLNSSymbol) nsSymbol;
String expandedName = createExpandedQName(bxmlnsSymbol.namespaceURI, filter.name);
BLangLiteral stringLiteral = createStringLiteral(filter.elemNamePos, expandedName);
args.add(stringLiteral);
args.add(createStringLiteral(filter.elemNamePos, filterName));
}
}
return args;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -484,14 +484,20 @@ public void visit(BLangXMLNavigationAccess xmlNavigation, AnalyzerData data) {
}

private void checkXMLNamespacePrefixes(List<BLangXMLElementFilter> filters, AnalyzerData data) {
Map<Name, BXMLNSSymbol> nameBXMLNSSymbolMap = symResolver.resolveAllNamespaces(data.env);
BXMLNSSymbol defaultNSSymbol = nameBXMLNSSymbolMap.get(Names.fromString(XMLConstants.DEFAULT_NS_PREFIX));
boolean hasDefaultNS = defaultNSSymbol != null;
for (BLangXMLElementFilter filter : filters) {
if (!filter.namespace.isEmpty()) {
Name nsName = names.fromString(filter.namespace);
BSymbol nsSymbol = symResolver.lookupSymbolInPrefixSpace(data.env, nsName);
filter.namespaceSymbol = nsSymbol;
if (nsSymbol.getKind() != SymbolKind.XMLNS) {
String namespace = filter.namespace;
if (!namespace.isEmpty()) {
Name nsName = Names.fromString(namespace);
BXMLNSSymbol nsSymbol = nameBXMLNSSymbolMap.get(nsName);
if (nsSymbol == null) {
dlog.error(filter.nsPos, DiagnosticErrorCode.CANNOT_FIND_XML_NAMESPACE, nsName);
}
filter.namespaceSymbol = nsSymbol;
} else if (hasDefaultNS) {
filter.namespaceSymbol = defaultNSSymbol;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,8 @@ public void testXMLNavigationOnSequenceWithNamespaces() {
"<child xmlns=\"foo\">A</child><child xmlns=\"foo\" xmlns:ns=\"foo\">B</child><k:child xmlns=\"foo\" " +
"xmlns:k=\"bar\">C</k:child><it-child xmlns=\"foo\">D</it-child>TEXT");
Assert.assertEquals(returns.get(2).toString(),
"<child xmlns=\"foo\">A</child>" +
"<child xmlns=\"foo\" xmlns:ns=\"foo\">B</child>" +
"<it-child xmlns=\"foo\">D</it-child>");
"<child xmlns=\"foo\">A</child><child xmlns=\"foo\" xmlns:ns=\"foo\">B</child><k:child xmlns=\"foo\" " +
"xmlns:k=\"bar\">C</k:child><it-child xmlns=\"foo\">D</it-child>");
Assert.assertEquals(returns.get(3).toString(),
"<child xmlns=\"foo\">A</child><child xmlns=\"foo\" xmlns:ns=\"foo\">B</child>");
Assert.assertEquals(returns.get(4).toString(),
Expand All @@ -180,8 +179,8 @@ public void testXMLNavigationOnSequenceWithNamespacesAndMultipleFilters() {
"<child xmlns=\"foo\">A</child><child xmlns=\"foo\" xmlns:ns=\"foo\">B</child>" +
"<child2 xmlns=\"foo\">D</child2>");
Assert.assertEquals(returns.get(2).toString(),
"<child xmlns=\"foo\">A</child><child xmlns=\"foo\" xmlns:ns=\"foo\">B</child>" +
"<child2 xmlns=\"foo\">D</child2>");
"<child xmlns=\"foo\">A</child><child xmlns=\"foo\" xmlns:ns=\"foo\">B</child><k:child xmlns=\"foo\" " +
"xmlns:k=\"bar\">C</k:child><child2 xmlns=\"foo\">D</child2>");
Assert.assertEquals(returns.get(3).toString(),
"<child xmlns=\"foo\">A</child><child xmlns=\"foo\" xmlns:ns=\"foo\">B</child><k:child xmlns=\"foo\" " +
"xmlns:k=\"bar\">C</k:child><child2 xmlns=\"foo\">D</child2>");
Expand Down Expand Up @@ -284,6 +283,11 @@ public void testXmlNavigationWithUnionType() {
BRunUtil.invoke(navigation, "testXmlNavigationWithUnionType");
}

@Test
public void testXmlNavigationWithDefaultNamespaceDefinedAfter() {
BRunUtil.invoke(navigation, "testXmlNavigationWithDefaultNamespaceDefinedAfter");
}

@Test
public void testXMLNavExpressionNegative() {
String methodInvocMessage = "method invocations are not yet supported within XML navigation expressions, " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,69 @@ function testXmlNavigationWithUnionType() {
assert(x6/<m>, xml `<m><n></n></m>`);
}

function testXmlNavigationWithDefaultNamespaceDefinedAfter() {
xml[] results = [];
xml x1 = xml `<a>a<b>b<c>c</c></b><d>d</d></a><f/>`;
results[0] = x1.<a>;
results[1] = x1/*;
results[2] = x1/<b>;
results[3] = x1/<*>;
results[4] = x1/**/<c>;

xmlns "http://example2.com/" as p1;
xml x2 = xml `<l>l<m>m<n>n</n></m><p1:q>q1</p1:q><q>q2</q></l>`;
{
xmlns "http://example2.com/";
}
results[5] = x2.<l>;
results[6] = x2/<m>;
results[7] = x2/<q>;
results[8] = x2/**/<n>;

{
xmlns "http://example2.com/";
{
results[9] = x2.<l>;
results[10] = x2/<q>;
}
}
xmlns "http://example.com/" as p2;
xml x3 = xml `<e>no-ns</e><f/><p2:e>with-ns</p2:e>`;
results[11] = x3.<e>;

xml x4 = xml `<e>e<f><g>f</g></f><h>h</h></e><j/>`;
xmlns "http://example.com/";
results[12] = x3.<e>;
results[13] = x4.<e>;
results[14] = x4/*;
results[15] = x4/<f>;
results[16] = x4/<*>;
results[17] = x4/**/<g>;

assertXmlNavigationWithDefaultNamespaceDefinedAfter(results);
}

function assertXmlNavigationWithDefaultNamespaceDefinedAfter(xml[] results) {
assert(results[0], xml `<a>a<b>b<c>c</c></b><d>d</d></a>`);
assert(results[1], xml `a<b>b<c>c</c></b><d>d</d>`);
assert(results[2], xml `<b>b<c>c</c></b>`);
assert(results[3], xml `<b>b<c>c</c></b><d>d</d>`);
assert(results[4], xml `<c>c</c>`);
assert(results[5], xml `<l>l<m>m<n>n</n></m><p1:q xmlns:p1="http://example2.com/">q1</p1:q><q>q2</q></l>`);
assert(results[6], xml `<m>m<n>n</n></m>`);
assert(results[7], xml `<q>q2</q>`);
assert(results[8], xml `<n>n</n>`);
assert(results[9], xml ``);
assert(results[10], xml `<p1:q xmlns:p1="http://example2.com/">q1</p1:q>`);
assert(results[11], xml `<e>no-ns</e>`);
assert(results[12], xml `<p2:e xmlns:p2="http://example.com/">with-ns</p2:e>`);
assert(results[13], xml ``);
assert(results[14], xml `e<f><g>f</g></f><h>h</h>`);
assert(results[15], xml ``);
assert(results[16], xml `<f><g>f</g></f><h>h</h>`);
assert(results[17], xml ``);
}

function assert(anydata actual, anydata expected) {
if (expected != actual) {
string reason = "expected `" + expected.toString() + "`, but found `" + actual.toString() + "`";
Expand Down

0 comments on commit 71fdc93

Please sign in to comment.