marko 6.0.95 → 6.0.96

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7967,7 +7967,12 @@ function trackReferencesForBinding(babelBinding, binding) {
7967
7967
  const { referencePaths, constantViolations } = babelBinding;
7968
7968
  for (const ref of referencePaths) {
7969
7969
  const refSection = getOrCreateSection(ref);
7970
- if (isReferenceHoisted(babelBinding.path, ref)) {
7970
+ const markoRoot = getMarkoRoot(ref);
7971
+ if (markoRoot?.type === "MarkoAttribute" && markoRoot.parentPath === babelBinding.path) {
7972
+ throw ref.buildCodeFrameError(
7973
+ `Tag variable circular references are not supported.`
7974
+ );
7975
+ } else if (isReferenceHoisted(babelBinding.path, ref)) {
7971
7976
  trackHoistedReference(ref, binding);
7972
7977
  } else if (binding.type !== 4 /* local */ || refSection !== binding.section) {
7973
7978
  trackReference(ref, binding);
@@ -8810,14 +8815,38 @@ function getReadReplacement(node) {
8810
8815
  replacement = import_compiler35.types.identifier(binding.name);
8811
8816
  }
8812
8817
  } else if (read) {
8813
- replacement = toMemberExpression(
8814
- import_compiler35.types.identifier(read.binding.name),
8815
- Array.isArray(read.props) ? read.props[0] : read.props
8816
- );
8817
- if (Array.isArray(read.props)) {
8818
- for (let i = 1; i < read.props.length; i++) {
8819
- replacement = toMemberExpression(replacement, read.props[i]);
8818
+ const props = read.props ? Array.isArray(read.props) ? read.props.slice() : [read.props] : [];
8819
+ let curNode = node;
8820
+ let curBinding = read.binding;
8821
+ let replaceMember;
8822
+ replacement = import_compiler35.types.identifier(read.binding.name);
8823
+ while (props.length && (curNode.type === "MemberExpression" || curNode.type === "OptionalMemberExpression")) {
8824
+ const prop = props.pop();
8825
+ const memberProp = getMemberExpressionPropString(curNode);
8826
+ if (memberProp !== prop) break;
8827
+ replaceMember = curNode;
8828
+ curNode = curNode.object;
8829
+ }
8830
+ for (const prop of props) {
8831
+ if (curBinding) {
8832
+ curBinding = curBinding.propertyAliases.get(prop);
8833
+ }
8834
+ replacement = toMemberExpression(
8835
+ replacement,
8836
+ prop,
8837
+ !!curBinding?.nullable
8838
+ );
8839
+ }
8840
+ if (replaceMember) {
8841
+ if (read.binding.nullable && replaceMember.object.type !== replacement.type) {
8842
+ replaceMember.type = "OptionalMemberExpression";
8843
+ replaceMember.optional = true;
8820
8844
  }
8845
+ replaceMember.object = withPreviousLocation(
8846
+ replacement,
8847
+ replaceMember.object
8848
+ );
8849
+ replacement = void 0;
8821
8850
  }
8822
8851
  }
8823
8852
  return replacement && withPreviousLocation(replacement, node);
@@ -8875,7 +8904,6 @@ function findClosestReference(from, refs) {
8875
8904
  const closest = findClosestUpstream(from, refs);
8876
8905
  if (closest) return closest;
8877
8906
  }
8878
- throw new Error("Unable to resolve closest binding reference.");
8879
8907
  }
8880
8908
  function findClosestUpstream(from, to) {
8881
8909
  let closest = from;
@@ -8885,13 +8913,32 @@ function findClosestUpstream(from, to) {
8885
8913
  }
8886
8914
  } while (closest = closest.upstreamAlias);
8887
8915
  }
8916
+ function getRootBindings(reads) {
8917
+ let rootRefs;
8918
+ let allBindings;
8919
+ for (const { binding } of reads) {
8920
+ allBindings = bindingUtil.add(allBindings, binding);
8921
+ }
8922
+ for (const { binding } of reads) {
8923
+ let alias = binding.upstreamAlias;
8924
+ while (alias) {
8925
+ if (bindingUtil.has(allBindings, alias)) break;
8926
+ alias = alias.upstreamAlias;
8927
+ }
8928
+ if (!alias) {
8929
+ rootRefs = bindingUtil.add(rootRefs, binding);
8930
+ }
8931
+ }
8932
+ return rootRefs;
8933
+ }
8888
8934
  function resolveReferencedBindings(expr, reads, intersectionsBySection) {
8889
8935
  let referencedBindings;
8890
8936
  if (Array.isArray(reads)) {
8937
+ const rootBindings = getRootBindings(reads);
8891
8938
  for (const read of reads) {
8892
8939
  let { binding } = read;
8893
8940
  if (read.node) {
8894
- const exprReference = (read.node.extra ??= {}).read ??= resolveExpressionReference(reads, binding, void 0);
8941
+ const exprReference = (read.node.extra ??= {}).read ??= resolveExpressionReference(rootBindings, binding);
8895
8942
  ({ binding } = (read.node.extra ??= {}).read = exprReference);
8896
8943
  }
8897
8944
  referencedBindings = bindingUtil.add(referencedBindings, binding);
@@ -8920,38 +8967,29 @@ function resolveReferencedBindings(expr, reads, intersectionsBySection) {
8920
8967
  }
8921
8968
  return referencedBindings;
8922
8969
  }
8923
- function resolveExpressionReference(reads, readBinding, readProps) {
8924
- const { upstreamAlias } = readBinding;
8925
- if (upstreamAlias && Array.isArray(reads)) {
8926
- const prop = getCanonicalProperty(readBinding);
8927
- const aliasProps = prop === void 0 ? readProps : push(readProps, prop);
8928
- for (const { binding } of reads) {
8929
- if (binding !== readBinding) {
8930
- let alias = upstreamAlias;
8931
- while (alias) {
8932
- if (binding === alias) {
8933
- return resolveExpressionReference(reads, alias, aliasProps);
8934
- }
8935
- alias = alias.upstreamAlias;
8936
- }
8937
- }
8970
+ function resolveExpressionReference(rootBindings, readBinding) {
8971
+ const upstreamRoot = readBinding.upstreamAlias && findClosestReference(readBinding.upstreamAlias, rootBindings);
8972
+ if (!upstreamRoot) {
8973
+ return createRead(readBinding, void 0);
8974
+ }
8975
+ let curBinding = readBinding;
8976
+ let props;
8977
+ while (curBinding !== upstreamRoot) {
8978
+ if (curBinding.property !== void 0) {
8979
+ props = push(props, curBinding.property);
8938
8980
  }
8981
+ curBinding = curBinding.upstreamAlias;
8939
8982
  }
8940
- return createRead(readBinding, readProps);
8983
+ if (Array.isArray(props)) {
8984
+ props.reverse();
8985
+ }
8986
+ return createRead(upstreamRoot, props);
8941
8987
  }
8942
8988
  function isSupersetSources(a, b) {
8943
8989
  if (!b.sources) return true;
8944
8990
  if (!a.sources) return false;
8945
8991
  return bindingUtil.isSuperset(a.sources.state, b.sources.state) && bindingUtil.isSuperset(a.sources.param, b.sources.param);
8946
8992
  }
8947
- function getCanonicalProperty(binding) {
8948
- if (binding.property !== void 0) {
8949
- return binding.property;
8950
- }
8951
- if (binding.upstreamAlias && binding.excludeProperties === void 0) {
8952
- return binding.upstreamAlias.property;
8953
- }
8954
- }
8955
8993
  function createRead(binding, props) {
8956
8994
  return { binding, props };
8957
8995
  }
@@ -112,7 +112,7 @@ export declare function getDebugName(binding: Binding): string;
112
112
  export declare function getDebugNames(refs: ReferencedBindings): string;
113
113
  export declare function getSectionInstancesAccessor(section: Section): string;
114
114
  export declare function getSectionInstancesAccessorLiteral(section: Section): t.StringLiteral | t.NumericLiteral | undefined;
115
- export declare function getReadReplacement(node: t.Identifier | t.MemberExpression | t.OptionalMemberExpression): t.Node | undefined;
115
+ export declare function getReadReplacement(node: t.Identifier | t.MemberExpression | t.OptionalMemberExpression): t.Expression | undefined;
116
116
  export interface ReferencedExtra extends t.NodeExtra {
117
117
  section: Section;
118
118
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "marko",
3
- "version": "6.0.95",
3
+ "version": "6.0.96",
4
4
  "description": "Optimized runtime for Marko templates.",
5
5
  "keywords": [
6
6
  "api",