MCPcopy Index your code
hub / github.com/nodejs/node / includesProxiesOrGetters

Function includesProxiesOrGetters

lib/internal/repl/completion.js:660–769  ·  view source on GitHub ↗

* Utility used to determine if an expression includes object getters or proxies. * * Example: given `obj.foo`, the function lets you know if `foo` has a getter function * associated to it, or if `obj` is a proxy * @param {any} expr The expression, in AST format to analyze * @param {string} expr

(expr, exprStr, evalFn, ctx, callback)

Source from the content-addressed store, hash-verified

658 * @returns {void}
659 */
660function includesProxiesOrGetters(expr, exprStr, evalFn, ctx, callback) {
661 if (expr?.type !== 'MemberExpression') {
662 // If the expression is not a member one for obvious reasons no getters are involved
663 return callback(false);
664 }
665
666 if (expr.object.type === 'MemberExpression') {
667 // The object itself is a member expression, so we need to recurse (e.g. the expression is `obj.foo.bar`)
668 return includesProxiesOrGetters(
669 expr.object,
670 exprStr.slice(0, expr.object.end),
671 evalFn,
672 ctx,
673 (includes, lastEvaledObj) => {
674 if (includes) {
675 // If the recurred call found a getter we can also terminate
676 return callback(includes);
677 }
678
679 if (isProxy(lastEvaledObj)) {
680 return callback(true);
681 }
682
683 // If a getter/proxy hasn't been found by the recursion call we need to check if maybe a getter/proxy
684 // is present here (e.g. in `obj.foo.bar` we found that `obj.foo` doesn't involve any getters so we now
685 // need to check if `bar` on `obj.foo` (i.e. `lastEvaledObj`) has a getter or if `obj.foo.bar` is a proxy)
686 return hasGetterOrIsProxy(lastEvaledObj, expr.property, (doesHaveGetterOrIsProxy) => {
687 return callback(doesHaveGetterOrIsProxy);
688 });
689 },
690 );
691 }
692
693 // This is the base of the recursion we have an identifier for the object and an identifier or literal
694 // for the property (e.g. we have `obj.foo` or `obj['foo']`, `obj` is the object identifier and `foo`
695 // is the property identifier/literal)
696 if (expr.object.type === 'Identifier') {
697 return evalFn(`try { ${expr.object.name} } catch {}`, ctx, getREPLResourceName(), (err, obj) => {
698 if (err) {
699 return callback(false);
700 }
701
702 if (isProxy(obj)) {
703 return callback(true);
704 }
705
706 return hasGetterOrIsProxy(obj, expr.property, (doesHaveGetterOrIsProxy) => {
707 if (doesHaveGetterOrIsProxy) {
708 return callback(true);
709 }
710
711 return evalFn(
712 `try { ${exprStr} } catch {} `, ctx, getREPLResourceName(), (err, obj) => {
713 if (err) {
714 return callback(false);
715 }
716 return callback(false, obj);
717 });

Callers 1

completeFunction · 0.85

Calls 4

hasGetterOrIsProxyFunction · 0.85
getREPLResourceNameFunction · 0.85
sliceMethod · 0.65
callbackFunction · 0.50

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…