Skip to content

Commit

Permalink
fix: parse reserved word when property name includes reserved word on…
Browse files Browse the repository at this point in the history
… reearth/core (#508)

* wip

* fix: replace reserved word

* fix

* Update src/core/mantle/evaluator/simple/expression/runtime.ts

Co-authored-by: rot1024 <aayhrot@gmail.com>

* Update src/core/mantle/evaluator/simple/expression/variableReplacer.ts

Co-authored-by: Piyush Chauhan <42397980+pyshx@users.noreply.github.com>

* Update src/core/mantle/evaluator/simple/expression/variableReplacer.test.ts

Co-authored-by: Piyush Chauhan <42397980+pyshx@users.noreply.github.com>

* fix: use $

---------

Co-authored-by: rot1024 <aayhrot@gmail.com>
Co-authored-by: Piyush Chauhan <42397980+pyshx@users.noreply.github.com>
  • Loading branch information
3 people committed Mar 6, 2023
1 parent 01bffdb commit aa247e9
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 2 deletions.
3 changes: 2 additions & 1 deletion src/core/mantle/evaluator/simple/expression/runtime.ts
Expand Up @@ -4,6 +4,7 @@ import { ExpressionNodeType, unaryOperators, binaryOperators, replacementRegex }
import { Expression } from "./expression";
import { unaryFunctions, binaryFunctions } from "./functions";
import { Node } from "./node";
import { restoreReservedWord } from "./variableReplacer";

export function createRuntimeAst(expression: Expression, ast: any): Node | Error {
let node: Node | Error = new Error("failed to parse");
Expand Down Expand Up @@ -260,5 +261,5 @@ function isVariable(name: string): boolean {
}

function getPropertyName(variable: string): string {
return variable.substring(4);
return restoreReservedWord(variable).substring(4);
}
Expand Up @@ -37,4 +37,13 @@ describe("replaceVariables", () => {
});
expect(res[0].literalValue).toBe("iPhone");
});

test("should replace reserved word", () => {
const [result, _] = replaceVariables(
"${va[ria]ble} + ${variable[0]} + ${variable['key']} + ${variable[\"key\"]} + ${variable[variable]} + ${variable[variable].nested} + ${variable[variable]['nested']}",
);
expect(result).toBe(
`czm_va$reearth_opened_square_bracket_$ria$reearth_closed_square_bracket_$ble + czm_variable[0] + czm_variable['key'] + czm_variable["key"] + czm_variable[variable] + czm_variable[variable].nested + czm_variable[variable]['nested']`,
);
});
});
25 changes: 24 additions & 1 deletion src/core/mantle/evaluator/simple/expression/variableReplacer.ts
Expand Up @@ -43,7 +43,8 @@ export function replaceVariables(expression: string, feature?: any): [string, JP
throw new Error(`replaceVariable: ${varExp} is not a valid JSONPath`);
}
} else {
result += `czm_${varExp}`;
const replacedVarExp = replaceReservedWord(varExp);
result += `czm_${replacedVarExp}`;
}
exp = exp.substring(j + 1);
i = exp.indexOf("${");
Expand Down Expand Up @@ -95,3 +96,25 @@ function containsValidJSONPath(expression: string, feature: Feature): boolean {
return false;
}
}

const makeReservedWord = (str: string) => `$reearth_${str}_$`;
const RESERVED_WORDS: Record<string, string> = {
"[": makeReservedWord("opened_square_bracket"),
"]": makeReservedWord("closed_square_bracket"),
"{": makeReservedWord("opened_curly_bracket"),
"}": makeReservedWord("closed_curly_bracket"),
"(": makeReservedWord("opened_parentheses"),
")": makeReservedWord("closed_parentheses"),
};

const replaceReservedWord = (word: string) => {
return word.replaceAll(
/(.*)(\[|\{|\()(.*)(\]|\}|\))(?!\.|\[)(.+)/g,
(_match, prefix, openedBracket, inner, closedBracket, suffix) => {
return `${prefix}${RESERVED_WORDS[openedBracket]}${inner}${RESERVED_WORDS[closedBracket]}${suffix}`;
},
);
};

export const restoreReservedWord = (text: string) =>
Object.entries(RESERVED_WORDS).reduce((res, [key, val]) => res.replace(val, key), text);
32 changes: 32 additions & 0 deletions src/core/mantle/evaluator/simple/index.test.ts
Expand Up @@ -421,4 +421,36 @@ describe("Conditional styling", () => {
},
});
});

test("Property has reserved word", () => {
expect(
evalLayerAppearances(
{
marker: {
pointColor: "#FF0000",
pointSize: {
expression: {
conditions: [
["${he[llo]world} === 'value'", "100"],
["true", "1"],
],
},
},
},
},
{
id: "x",
type: "simple",
properties: {
"he[llo]world": "value",
},
},
),
).toEqual({
marker: {
pointColor: "#FF0000", // blue
pointSize: 100,
},
});
});
});

0 comments on commit aa247e9

Please sign in to comment.