You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
111 lines
2.7 KiB
111 lines
2.7 KiB
"use strict"; |
|
|
|
Object.defineProperty(exports, "__esModule", { |
|
value: true |
|
}); |
|
exports.default = void 0; |
|
|
|
var _helperPluginUtils = require("@babel/helper-plugin-utils"); |
|
|
|
var _core = require("@babel/core"); |
|
|
|
var _helperAnnotateAsPure = _interopRequireDefault(require("@babel/helper-annotate-as-pure")); |
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } |
|
|
|
var _default = (0, _helperPluginUtils.declare)((api, options) => { |
|
api.assertVersion(7); |
|
const { |
|
allowMutablePropsOnTags |
|
} = options; |
|
|
|
if (allowMutablePropsOnTags != null && !Array.isArray(allowMutablePropsOnTags)) { |
|
throw new Error(".allowMutablePropsOnTags must be an array, null, or undefined."); |
|
} |
|
|
|
const HOISTED = new WeakSet(); |
|
const immutabilityVisitor = { |
|
enter(path, state) { |
|
const stop = () => { |
|
state.isImmutable = false; |
|
path.stop(); |
|
}; |
|
|
|
if (path.isJSXClosingElement()) { |
|
path.skip(); |
|
return; |
|
} |
|
|
|
if (path.isJSXIdentifier({ |
|
name: "ref" |
|
}) && path.parentPath.isJSXAttribute({ |
|
name: path.node |
|
})) { |
|
return stop(); |
|
} |
|
|
|
if (path.isJSXIdentifier() || path.isIdentifier() || path.isJSXMemberExpression()) { |
|
return; |
|
} |
|
|
|
if (!path.isImmutable()) { |
|
if (path.isPure()) { |
|
const expressionResult = path.evaluate(); |
|
|
|
if (expressionResult.confident) { |
|
const { |
|
value |
|
} = expressionResult; |
|
const isMutable = !state.mutablePropsAllowed && value && typeof value === "object" || typeof value === "function"; |
|
|
|
if (!isMutable) { |
|
path.skip(); |
|
return; |
|
} |
|
} else if (_core.types.isIdentifier(expressionResult.deopt)) { |
|
return; |
|
} |
|
} |
|
|
|
stop(); |
|
} |
|
} |
|
|
|
}; |
|
return { |
|
name: "transform-react-constant-elements", |
|
visitor: { |
|
JSXElement(path) { |
|
if (HOISTED.has(path.node)) return; |
|
HOISTED.add(path.node); |
|
const state = { |
|
isImmutable: true |
|
}; |
|
|
|
if (allowMutablePropsOnTags != null) { |
|
let namePath = path.get("openingElement.name"); |
|
|
|
while (namePath.isJSXMemberExpression()) { |
|
namePath = namePath.get("property"); |
|
} |
|
|
|
const elementName = namePath.node.name; |
|
state.mutablePropsAllowed = allowMutablePropsOnTags.indexOf(elementName) > -1; |
|
} |
|
|
|
path.traverse(immutabilityVisitor, state); |
|
|
|
if (state.isImmutable) { |
|
const hoisted = path.hoist(); |
|
|
|
if (hoisted) { |
|
(0, _helperAnnotateAsPure.default)(hoisted); |
|
} |
|
} |
|
} |
|
|
|
} |
|
}; |
|
}); |
|
|
|
exports.default = _default; |