refText = "opt_ijData" + genCodeForKeyAccess(firstKey);
if (node.isNullSafeIjDataRef()) {
nullSafetyPrefix = "(opt_ijData == null) ? null : ";
}
} else {
JsExpr translation = getLocalVarTranslation(firstKey);
if (translation != null) {
// Case 2: In-scope local var.
refText = translation.getText();
} else {
// Case 3: Data reference.
refText = "opt_data" + genCodeForKeyAccess(firstKey);
}
}
// ------ Translate the rest of the keys, if any. ------
for (ExprNode child : node.getChildren()) {
DataRefAccessNode accessNode = (DataRefAccessNode) child;
if (accessNode.isNullSafe()) {
// Note: In JavaScript, "x == null" is equivalent to "x === undefined || x === null".
nullSafetyPrefix += "(" + refText + " == null) ? null : ";
}
switch (accessNode.getKind()) {
case DATA_REF_ACCESS_KEY_NODE:
refText += genCodeForKeyAccess(((DataRefAccessKeyNode) accessNode).getKey());
break;
case DATA_REF_ACCESS_INDEX_NODE:
refText += "[" + ((DataRefAccessIndexNode) accessNode).getIndex() + "]";
break;
case DATA_REF_ACCESS_EXPR_NODE:
JsExpr keyJsExpr = visit(accessNode.getChild(0));
refText += "[" + keyJsExpr.getText() + "]";
break;
default:
throw new AssertionError();
}
}
if (nullSafetyPrefix.length() == 0) {
return new JsExpr(refText, Integer.MAX_VALUE);
} else {
return new JsExpr(nullSafetyPrefix + refText, Operator.CONDITIONAL.getPrecedence());
}
}