Skip to content

Commit

Permalink
~ fix lots of assumed top-level Shapes
Browse files Browse the repository at this point in the history
  • Loading branch information
Eric Prud'hommeaux committed Jun 16, 2022
1 parent eeb820c commit 2fc9d26
Show file tree
Hide file tree
Showing 12 changed files with 144 additions and 111 deletions.
92 changes: 56 additions & 36 deletions packages/extension-map/doc/webpacks/shexmap-webapp.js
Original file line number Diff line number Diff line change
Expand Up @@ -4649,11 +4649,26 @@ function ShExMaterializer_constructor(schema, mapper, options) {
shape: shapeLabel
};
seen[seenKey] = { point: point, shapeLabel: shapeLabel };
const ret = this._validateShapeExpr(db, point, schema._index.shapeExprs[shapeLabel], shapeLabel, depth, seen);
const ret = this._validateShapeDecl(db, point, schema._index.shapeExprs[shapeLabel], shapeLabel, depth, seen);
delete seen[seenKey];
return ret;
}

this._validateShapeDecl = function (db, point, shapeExpr, shapeLabel, depth, tracker, seen, subgraph) {
const expr = shapeExpr.type === "ShapeDecl" ? shapeExpr.shapeExpr : shapeExpr;
return this._validateShapeExpr(db, point, expr, shapeLabel, depth, tracker, seen, subgraph);
}

this._lookupShape = function (label) {
if (!("shapes" in this.schema) || this.schema.shapes.length === 0) {
runtimeError("shape " + label + " not found; no shapes in schema");
} else if (label in index.shapeExprs) {
return index.shapeExprs[label]
} else {
runtimeError("shape " + label + " not found in:\n" + Object.keys(index.shapeExprs || []).map(s => " " + s).join("\n"));
}
}

this._validateShapeExpr = function (db, point, shapeExpr, shapeLabel, depth, seen) {
if ("known" in this && this.known.cached(point, shapeExpr))
return this.known.cached(point, shapeExpr);
Expand Down Expand Up @@ -6648,7 +6663,7 @@ function trivialMaterializer (schema, nextBNode) {
const oldVisitShapeRef = v.visitShapeRef;

v.visitShapeRef = function (shapeRef) {
this.visitShapeExpr(index.shapeExprs[shapeRef], shapeRef);
this.visitShapeDecl(index.shapeExprs[shapeRef], shapeRef);
return oldVisitShapeRef.call(v, shapeRef);
};

Expand Down Expand Up @@ -8269,13 +8284,9 @@ this.$ = appendTo($$[$0-1], $$[$0]) // t: startCode3;
break;
case 26:
// t: 1dot 1val1vsMinusiri3??
if ($$[$0-3].abstract || $$[$0-1].length) { // t: $$[$0-3]: 1dotAbstractShapeCode1 $$[$0-2]: @@
yy.addShape($$[$0-2], Object.assign({type: "ShapeDecl"}, $$[$0-3],
$$[$0-1].length > 0 ? { restricts: $$[$0-1] } : { },
{shapeExpr: $$[$0]})) // $$[$01]: t: @@
} else {
yy.addShape($$[$0-2], $$[$0]);
}
yy.addShape($$[$0-2], Object.assign({type: "ShapeDecl"}, $$[$0-3],
$$[$0-1].length > 0 ? { restricts: $$[$0-1] } : { },
{shapeExpr: $$[$0]})) // $$[$01]: t: @@

break;
case 27:
Expand Down Expand Up @@ -9790,7 +9801,7 @@ const ShExUtil = {
shapes: schema.shapes.reduce(function (ret, shape) {
ret[shape.id] = {
type: "ASTshape",
expression: _compileShapeToAST(shape.expression, [], schema)
expression: _compileShapeToAST(shape.shapeExpr.expression, [], schema)
};
return ret;
}, {})
Expand Down Expand Up @@ -10020,14 +10031,19 @@ const ShExUtil = {
schema.start = v.visitShapeExpr(schema.start);
if ("shapes" in schema)
schema.shapes = schema.shapes.map((sh, idx) => {
return sh.type === SX.ShapeDecl ?
return sh.type === SX.ShapeExternal
?
{
type: "ShapeDecl",
type: "ShapeExternal",
id: sh.id,
abstract: sh.abstract,
shapeExpr: v.visitShapeExpr(sh.shapeExpr)
} :
knownShapeExprs.get(sh.id) ? knownShapeExprs.get(sh.id) : (() => {const n = v.keepShapeExpr(sh); knownShapeExprs.set(sh.id, n); return n;})();
}
:
{
type: "ShapeDecl",
id: sh.id,
abstract: sh.abstract,
shapeExpr: v.visitShapeExpr(sh.shapeExpr)
};
});

// remove extraneous BNode IDs
Expand Down Expand Up @@ -10114,7 +10130,7 @@ const ShExUtil = {
// Don't delete ret.productions as it's part of the AS.
const v = ShExUtil.Visitor();
const knownExpressions = [];
const oldVisitInclusion = v.visitInclusion, oldVisitExpression = v.visitExpression;
const oldVisitInclusion = v.visitInclusion, oldVisitExpression = v.visitExpression, oldVisitExtra = v.visitExtra;
v.visitInclusion = function (inclusion) {
if (knownExpressions.indexOf(inclusion) === -1 &&
inclusion in index.tripleExprs) {
Expand All @@ -10133,6 +10149,9 @@ const ShExUtil = {
}
return oldVisitExpression.call(v, expression);
};
v.visitExtra = function (l) {
return l.slice().sort();
}
if (trimIRI) {
v.visitIRI = function (i) {
return i.replace(trimIRI, "");
Expand Down Expand Up @@ -10497,10 +10516,10 @@ const ShExUtil = {
*/
getDependencies: function (schema, ret) {
ret = ret || this.BiDiClosure();
(schema.shapes || []).forEach(function (shape) {
(schema.shapes || []).forEach(function (shapeDecl) {
function _walkShapeExpression (shapeExpr, negated) {
if (typeof shapeExpr === "string") { // ShapeRef
ret.add(shape.id, shapeExpr);
ret.add(shapeDecl.id, shapeExpr);
} else if (shapeExpr.type === "ShapeOr" || shapeExpr.type === "ShapeAnd") {
shapeExpr.shapeExprs.forEach(function (expr) {
_walkShapeExpression(expr, negated);
Expand All @@ -10527,15 +10546,15 @@ const ShExUtil = {
function _walkTripleConstraint (tc, negated) {
if (tc.valueExpr)
_walkShapeExpression(tc.valueExpr, negated);
if (negated && ret.inCycle.indexOf(shape.id) !== -1) // illDefined/negatedRefCycle.err
throw Error("Structural error: " + shape.id + " appears in negated cycle");
if (negated && ret.inCycle.indexOf(shapeDecl.id) !== -1) // illDefined/negatedRefCycle.err
throw Error("Structural error: " + shapeDecl.id + " appears in negated cycle");
}

if (typeof tripleExpr === "string") { // Inclusion
ret.add(shape.id, tripleExpr);
ret.add(shapeDecl.id, tripleExpr);
} else {
if ("id" in tripleExpr)
ret.addIn(tripleExpr.id, shape.id)
ret.addIn(tripleExpr.id, shapeDecl.id)
if (tripleExpr.type === "TripleConstraint") {
_walkTripleConstraint(tripleExpr, negated);
} else if (tripleExpr.type === "OneOf" || tripleExpr.type === "EachOf") {
Expand All @@ -10549,15 +10568,13 @@ const ShExUtil = {
(["extends", "restricts"]).forEach(attr => {
if (shape[attr] && shape[attr].length > 0)
shape[attr].forEach(function (i) {
ret.add(shape.id, i);
ret.add(shapeDecl.id, i);
});
})
if (shape.expression)
_walkTripleExpression(shape.expression, negated);
}
if (shape.type === "ShapeDecl")
shape = shape.shapeExpr;
_walkShapeExpression(shape, 0); // 0 means false for bitwise XOR
_walkShapeExpression(shapeDecl.shapeExpr, 0); // 0 means false for bitwise XOR
});
return ret;
},
Expand Down Expand Up @@ -11152,14 +11169,17 @@ const ShExUtil = {
const shapes = values[SX.shapes];
if (shapes) {
ret.shapes = shapes.map(v => { // @@ console.log(v.nested);
var t = v.nested[RDF.type][0].ldterm;
var obj = t === SX.ShapeDecl ?
{
type: SX.ShapeDecl,
abstract: !!v.nested[SX["abstract"]][0].ldterm.value,
shapeExpr: shapeExpr(v.nested[SX.shapeExpr][0].nested)
} :
shapeExpr(v.nested);
var t = v.nested[RDF.type][0].ldterm;debugger;
const obj = t === SX.ShapeExternal
? { type: t }
: Object.assign(
{},
{ type: SX.ShapeDecl },
SX["abstract"] in v.nested
? {abstract: !!v.nested[SX["abstract"]]?.[0].ldterm.value}
: {},
{shapeExpr: shapeExpr(v.nested[SX.shapeExpr][0].nested)}
);
return extend({id: v.ldterm}, obj);
});
}
Expand Down Expand Up @@ -12746,7 +12766,7 @@ function ShExValidator_constructor(schema, db, options) {
// Override visitShapeRef to follow references.
// tests: Extend3G-pass, vitals-RESTRICTS-pass_lie-Vital...
visitor.visitShapeRef = function (inclusion) {
return visitor.visitShapeDecl(this._lookupShape(inclusion));
return visitor.visitShapeDecl(_ShExValidator._lookupShape(inclusion));
};

// Visit shape's EXTENDS and expression.
Expand Down
2 changes: 1 addition & 1 deletion packages/extension-map/doc/webpacks/shexmap-webapp.min.js

Large diffs are not rendered by default.

17 changes: 16 additions & 1 deletion packages/extension-map/lib/ShExMaterializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -287,11 +287,26 @@ function ShExMaterializer_constructor(schema, mapper, options) {
shape: shapeLabel
};
seen[seenKey] = { point: point, shapeLabel: shapeLabel };
const ret = this._validateShapeExpr(db, point, schema._index.shapeExprs[shapeLabel], shapeLabel, depth, seen);
const ret = this._validateShapeDecl(db, point, schema._index.shapeExprs[shapeLabel], shapeLabel, depth, seen);
delete seen[seenKey];
return ret;
}

this._validateShapeDecl = function (db, point, shapeExpr, shapeLabel, depth, tracker, seen, subgraph) {
const expr = shapeExpr.type === "ShapeDecl" ? shapeExpr.shapeExpr : shapeExpr;
return this._validateShapeExpr(db, point, expr, shapeLabel, depth, tracker, seen, subgraph);
}

this._lookupShape = function (label) {
if (!("shapes" in this.schema) || this.schema.shapes.length === 0) {
runtimeError("shape " + label + " not found; no shapes in schema");
} else if (label in index.shapeExprs) {
return index.shapeExprs[label]
} else {
runtimeError("shape " + label + " not found in:\n" + Object.keys(index.shapeExprs || []).map(s => " " + s).join("\n"));
}
}

this._validateShapeExpr = function (db, point, shapeExpr, shapeLabel, depth, seen) {
if ("known" in this && this.known.cached(point, shapeExpr))
return this.known.cached(point, shapeExpr);
Expand Down
2 changes: 1 addition & 1 deletion packages/extension-map/shex-extension-map.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ function trivialMaterializer (schema, nextBNode) {
const oldVisitShapeRef = v.visitShapeRef;

v.visitShapeRef = function (shapeRef) {
this.visitShapeExpr(index.shapeExprs[shapeRef], shapeRef);
this.visitShapeDecl(index.shapeExprs[shapeRef], shapeRef);
return oldVisitShapeRef.call(v, shapeRef);
};

Expand Down
18 changes: 9 additions & 9 deletions packages/shex-cli/test/Parser-Writer-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ describe("A ShEx parser", function () {

it("should use those prefixes", function () {
const schema = "a:a { b:b .+ }";
expect(parser.parse(schema)._index.shapeExprs["http://a.example/abc#a"].expression.predicate)
expect(parser.parse(schema)._index.shapeExprs["http://a.example/abc#a"].shapeExpr.expression.predicate)
.to.deep.equal("http://a.example/def#b");
});

Expand All @@ -314,15 +314,15 @@ describe("A ShEx parser", function () {

it("should use those prefixes", function () {
const schema = "a:a { b:b .+ }";
expect(parser.parse(schema)._index.shapeExprs["http://a.example/abc#a"].expression.predicate)
expect(parser.parse(schema)._index.shapeExprs["http://a.example/abc#a"].shapeExpr.expression.predicate)
.to.deep.equal("http://a.example/def#b");
});

it("should allow temporarily overriding prefixes", function () {
const schema = "PREFIX a: <http://a.example/xyz#> a:a { b:b .+ }";
expect(parser.parse(schema)._index.shapeExprs["http://a.example/xyz#a"].expression.predicate)
expect(parser.parse(schema)._index.shapeExprs["http://a.example/xyz#a"].shapeExpr.expression.predicate)
.to.deep.equal("http://a.example/def#b");
expect(parser.parse("a:a { b:b .+ }")._index.shapeExprs["http://a.example/abc#a"].expression.predicate)
expect(parser.parse("a:a { b:b .+ }")._index.shapeExprs["http://a.example/abc#a"].shapeExpr.expression.predicate)
.to.deep.equal("http://a.example/def#b");
});

Expand All @@ -332,7 +332,7 @@ describe("A ShEx parser", function () {

it("should not take over changes to the original prefixes", function () {
prefixes.a = "http://a.example/xyz#";
expect(parser.parse("a:a { b:b .+ }")._index.shapeExprs["http://a.example/abc#a"].expression.predicate)
expect(parser.parse("a:a { b:b .+ }")._index.shapeExprs["http://a.example/abc#a"].shapeExpr.expression.predicate)
.to.deep.equal("http://a.example/def#b");
});

Expand All @@ -346,15 +346,15 @@ describe("A ShEx parser", function () {

it("should use those prefixes", function () {
const schema = "a: { b: .+ }";
expect(parser.parse(schema)._index.shapeExprs["http://a.example/abc#"].expression.predicate)
expect(parser.parse(schema)._index.shapeExprs["http://a.example/abc#"].shapeExpr.expression.predicate)
.to.deep.equal("http://a.example/def#");
});

it("should allow temporarily overriding prefixes", function () {
const schema = "PREFIX a: <http://a.example/xyz#> a: { b: .+ }";
expect(parser.parse(schema)._index.shapeExprs["http://a.example/xyz#"].expression.predicate)
expect(parser.parse(schema)._index.shapeExprs["http://a.example/xyz#"].shapeExpr.expression.predicate)
.to.deep.equal("http://a.example/def#");
expect(parser.parse("a: { b: .+ }")._index.shapeExprs["http://a.example/abc#"].expression.predicate)
expect(parser.parse("a: { b: .+ }")._index.shapeExprs["http://a.example/abc#"].shapeExpr.expression.predicate)
.to.deep.equal("http://a.example/def#");
});

Expand Down Expand Up @@ -399,7 +399,7 @@ function loadGraphSchema () {

// For testing, wrap TC.valueExprs in ShapeOr to allow references undefined shapes (i.e. no properties ergo empty shape).
const valueExpr_tripleCnstrnt = ret._index.shapeExprs[nsPath + "TripleConstraint"].
expression.expressions.find(e => {
shapeExpr.expression.expressions.find(e => {
return e.predicate === nsPath + "valueExpr";
});
valueExpr_tripleCnstrnt.valueExpr = { type: "ShapeOr",
Expand Down
10 changes: 3 additions & 7 deletions packages/shex-parser/lib/ShExJison.jison
Original file line number Diff line number Diff line change
Expand Up @@ -510,13 +510,9 @@ statement:

shapeExprDecl:
_QIT_ABSTRACT_E_Opt shapeExprLabel _Qrestriction_E_Star _O_QshapeExpression_E_Or_QIT_EXTERNAL_E_C { // t: 1dot 1val1vsMinusiri3??
if ($1.abstract || $3.length) { // t: $1: 1dotAbstractShapeCode1 $2: @@
yy.addShape($2, Object.assign({type: "ShapeDecl"}, $1,
$3.length > 0 ? { restricts: $3 } : { },
{shapeExpr: $4})) // $5: t: @@
} else {
yy.addShape($2, $4);
}
yy.addShape($2, Object.assign({type: "ShapeDecl"}, $1,
$3.length > 0 ? { restricts: $3 } : { },
{shapeExpr: $4})) // $5: t: @@
}
;

Expand Down
10 changes: 3 additions & 7 deletions packages/shex-parser/lib/ShExJison.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 2fc9d26

Please sign in to comment.