diff --git a/src/main/java/com/hubspot/jinjava/el/ext/eager/EvalResultHolder.java b/src/main/java/com/hubspot/jinjava/el/ext/eager/EvalResultHolder.java index b34edad65..425cc0ddd 100644 --- a/src/main/java/com/hubspot/jinjava/el/ext/eager/EvalResultHolder.java +++ b/src/main/java/com/hubspot/jinjava/el/ext/eager/EvalResultHolder.java @@ -5,6 +5,7 @@ import com.hubspot.jinjava.el.ext.IdentifierPreservationStrategy; import com.hubspot.jinjava.interpret.DeferredValueException; import com.hubspot.jinjava.interpret.JinjavaInterpreter; +import com.hubspot.jinjava.interpret.MetaContextVariables; import com.hubspot.jinjava.interpret.PartiallyDeferredValue; import com.hubspot.jinjava.util.EagerExpressionResolver; import de.odysseus.el.tree.Bindings; @@ -125,11 +126,12 @@ static String reconstructNode( if (astNode instanceof AstIdentifier) { String name = ((AstIdentifier) astNode).getName(); if ( - ((JinjavaInterpreter) context - .getELResolver() - .getValue(context, null, ExtendedParser.INTERPRETER)).getContext() - .getComputedMetaContextVariables() - .contains(name) + MetaContextVariables.isMetaContextVariable( + name, + ((JinjavaInterpreter) context + .getELResolver() + .getValue(context, null, ExtendedParser.INTERPRETER)).getContext() + ) ) { return name; } diff --git a/src/main/java/com/hubspot/jinjava/interpret/Context.java b/src/main/java/com/hubspot/jinjava/interpret/Context.java index e99b8a84a..4126371e6 100644 --- a/src/main/java/com/hubspot/jinjava/interpret/Context.java +++ b/src/main/java/com/hubspot/jinjava/interpret/Context.java @@ -338,6 +338,9 @@ public void addResolvedFunction(String function) { } } + /** + * @deprecated Use {@link MetaContextVariables#isMetaContextVariable(String, Context)} + */ @Deprecated @Beta public Set getMetaContextVariables() { @@ -345,7 +348,7 @@ public Set getMetaContextVariables() { } @Beta - public Set getComputedMetaContextVariables() { + Set getComputedMetaContextVariables() { return Sets.difference(metaContextVariables, overriddenNonMetaContextVariables); } @@ -354,6 +357,10 @@ public void addMetaContextVariables(Collection variables) { metaContextVariables.addAll(variables); } + Set getNonMetaContextVariables() { + return overriddenNonMetaContextVariables; + } + @Beta public void addNonMetaContextVariables(Collection variables) { overriddenNonMetaContextVariables.addAll( diff --git a/src/main/java/com/hubspot/jinjava/interpret/MetaContextVariables.java b/src/main/java/com/hubspot/jinjava/interpret/MetaContextVariables.java new file mode 100644 index 000000000..2630a41ac --- /dev/null +++ b/src/main/java/com/hubspot/jinjava/interpret/MetaContextVariables.java @@ -0,0 +1,52 @@ +package com.hubspot.jinjava.interpret; + +import com.google.common.annotations.Beta; +import java.util.Objects; + +@Beta +public class MetaContextVariables { + + public static final String TEMPORARY_META_CONTEXT_PREFIX = "__temp_meta_"; + private static final String TEMPORARY_IMPORT_ALIAS_PREFIX = + TEMPORARY_META_CONTEXT_PREFIX + "import_alias_"; + + private static final String TEMPORARY_IMPORT_ALIAS_FORMAT = + TEMPORARY_IMPORT_ALIAS_PREFIX + "%d__"; + private static final String TEMP_CURRENT_PATH_PREFIX = + TEMPORARY_META_CONTEXT_PREFIX + "current_path_"; + private static final String TEMP_CURRENT_PATH_FORMAT = + TEMP_CURRENT_PATH_PREFIX + "%d__"; + + public static boolean isMetaContextVariable(String varName, Context context) { + if (isTemporaryMetaContextVariable(varName)) { + return true; + } + return ( + context.getMetaContextVariables().contains(varName) && + !context.getNonMetaContextVariables().contains(varName) + ); + } + + private static boolean isTemporaryMetaContextVariable(String varName) { + return varName.startsWith(TEMPORARY_META_CONTEXT_PREFIX); + } + + public static boolean isTemporaryImportAlias(String varName) { + // This is just faster than checking a regex + return varName.startsWith(TEMPORARY_IMPORT_ALIAS_PREFIX); + } + + public static String getTemporaryImportAlias(String fullAlias) { + return String.format( + TEMPORARY_IMPORT_ALIAS_FORMAT, + Math.abs(Objects.hashCode(fullAlias)) + ); + } + + public static String getTemporaryCurrentPathVarName(String newPath) { + return String.format( + TEMP_CURRENT_PATH_FORMAT, + Math.abs(Objects.hash(newPath, TEMPORARY_META_CONTEXT_PREFIX) >> 1) + ); + } +} diff --git a/src/main/java/com/hubspot/jinjava/lib/fn/MacroFunction.java b/src/main/java/com/hubspot/jinjava/lib/fn/MacroFunction.java index 9e6cd9a17..fa3af998a 100644 --- a/src/main/java/com/hubspot/jinjava/lib/fn/MacroFunction.java +++ b/src/main/java/com/hubspot/jinjava/lib/fn/MacroFunction.java @@ -127,6 +127,11 @@ public String getEvaluationResult( ); } else { if (!alreadyDeferredInEarlierCall(scopeEntry.getKey(), interpreter)) { + if ( + interpreter.getContext().get(scopeEntry.getKey()) == scopeEntry.getValue() + ) { + continue; // don't override if it's the same object + } interpreter.getContext().put(scopeEntry.getKey(), scopeEntry.getValue()); } } diff --git a/src/main/java/com/hubspot/jinjava/lib/fn/eager/EagerMacroFunction.java b/src/main/java/com/hubspot/jinjava/lib/fn/eager/EagerMacroFunction.java index 9e805daa3..7b12d66bd 100644 --- a/src/main/java/com/hubspot/jinjava/lib/fn/eager/EagerMacroFunction.java +++ b/src/main/java/com/hubspot/jinjava/lib/fn/eager/EagerMacroFunction.java @@ -126,6 +126,12 @@ public Object doEvaluate( ); throw new DeferredInvocationResolutionException(tempVarName); } + if (!eagerExecutionResult.getResult().isFullyResolved()) { + return EagerReconstructionUtils.wrapInChildScope( + eagerExecutionResult.getResult().toString(true), + interpreter + ); + } return eagerExecutionResult.getResult().toString(true); } diff --git a/src/main/java/com/hubspot/jinjava/lib/tag/eager/DeferredToken.java b/src/main/java/com/hubspot/jinjava/lib/tag/eager/DeferredToken.java index 6ee5c8e61..31dfee7ac 100644 --- a/src/main/java/com/hubspot/jinjava/lib/tag/eager/DeferredToken.java +++ b/src/main/java/com/hubspot/jinjava/lib/tag/eager/DeferredToken.java @@ -10,6 +10,7 @@ import com.hubspot.jinjava.interpret.DeferredValue; import com.hubspot.jinjava.interpret.DeferredValueShadow; import com.hubspot.jinjava.interpret.JinjavaInterpreter; +import com.hubspot.jinjava.interpret.MetaContextVariables; import com.hubspot.jinjava.tree.parse.Token; import com.hubspot.jinjava.tree.parse.TokenScannerSymbols; import com.hubspot.jinjava.util.EagerExpressionResolver; @@ -376,7 +377,7 @@ private static Collection markDeferredWordsAndFindSources( } return !(val instanceof DeferredValue); }) - .filter(prop -> !context.getComputedMetaContextVariables().contains(prop)) + .filter(prop -> !MetaContextVariables.isMetaContextVariable(prop, context)) .filter(prop -> { DeferredValue deferredValue = convertToDeferredValue(context, prop); context.put(prop, deferredValue); diff --git a/src/main/java/com/hubspot/jinjava/lib/tag/eager/EagerBlockSetTagStrategy.java b/src/main/java/com/hubspot/jinjava/lib/tag/eager/EagerBlockSetTagStrategy.java index e6ea02fd6..66952147e 100644 --- a/src/main/java/com/hubspot/jinjava/lib/tag/eager/EagerBlockSetTagStrategy.java +++ b/src/main/java/com/hubspot/jinjava/lib/tag/eager/EagerBlockSetTagStrategy.java @@ -170,7 +170,7 @@ protected Triple getPrefixTokenAndSuffix( .build() ) ); - String suffixToPreserveState = getSuffixToPreserveState(variables[0], interpreter); + String suffixToPreserveState = getSuffixToPreserveState(variables, interpreter); return Triple.of( prefixToPreserveState.toString(), joiner.toString(), diff --git a/src/main/java/com/hubspot/jinjava/lib/tag/eager/EagerImportTag.java b/src/main/java/com/hubspot/jinjava/lib/tag/eager/EagerImportTag.java index ea46cae3b..6671aaee8 100644 --- a/src/main/java/com/hubspot/jinjava/lib/tag/eager/EagerImportTag.java +++ b/src/main/java/com/hubspot/jinjava/lib/tag/eager/EagerImportTag.java @@ -38,8 +38,6 @@ public String getEagerTagImage(TagToken tagToken, JinjavaInterpreter interpreter importingData ); - final String newPathSetter; - Optional maybeTemplateFile; try { maybeTemplateFile = @@ -53,7 +51,6 @@ public String getEagerTagImage(TagToken tagToken, JinjavaInterpreter interpreter String templateFile = maybeTemplateFile.get(); try { Node node = ImportTag.parseTemplateAsNode(interpreter, templateFile); - newPathSetter = EagerImportingStrategyFactory.getSetTagForCurrentPath(interpreter); JinjavaInterpreter child = interpreter .getConfig() @@ -96,7 +93,11 @@ public String getEagerTagImage(TagToken tagToken, JinjavaInterpreter interpreter return ""; } return EagerReconstructionUtils.wrapInTag( - eagerImportingStrategy.getFinalOutput(newPathSetter, output, child), + EagerReconstructionUtils.wrapPathAroundText( + eagerImportingStrategy.getFinalOutput(output, child), + templateFile, + interpreter + ), DoTag.TAG_NAME, interpreter, true diff --git a/src/main/java/com/hubspot/jinjava/lib/tag/eager/EagerIncludeTag.java b/src/main/java/com/hubspot/jinjava/lib/tag/eager/EagerIncludeTag.java index 7bfa805f4..601b7deba 100644 --- a/src/main/java/com/hubspot/jinjava/lib/tag/eager/EagerIncludeTag.java +++ b/src/main/java/com/hubspot/jinjava/lib/tag/eager/EagerIncludeTag.java @@ -3,8 +3,6 @@ import com.google.common.annotations.Beta; import com.hubspot.jinjava.interpret.JinjavaInterpreter; import com.hubspot.jinjava.lib.tag.IncludeTag; -import com.hubspot.jinjava.lib.tag.eager.importing.EagerImportingStrategyFactory; -import com.hubspot.jinjava.loader.RelativePathResolver; import com.hubspot.jinjava.tree.TagNode; import com.hubspot.jinjava.util.EagerReconstructionUtils; import com.hubspot.jinjava.util.HelperStringTokenizer; @@ -30,14 +28,11 @@ public String innerInterpret(TagNode tagNode, JinjavaInterpreter interpreter) { tagNode.getStartPosition() ); templateFile = interpreter.resolveResourceLocation(templateFile); - final String initialPathSetter = - EagerImportingStrategyFactory.getSetTagForCurrentPath(interpreter); - final String newPathSetter = EagerReconstructionUtils.buildBlockOrInlineSetTag( - RelativePathResolver.CURRENT_PATH_CONTEXT_KEY, + return EagerReconstructionUtils.wrapPathAroundText( + output, templateFile, interpreter ); - return newPathSetter + output + initialPathSetter; } return output; } diff --git a/src/main/java/com/hubspot/jinjava/lib/tag/eager/EagerInlineSetTagStrategy.java b/src/main/java/com/hubspot/jinjava/lib/tag/eager/EagerInlineSetTagStrategy.java index 50c7682c9..2c05052e8 100644 --- a/src/main/java/com/hubspot/jinjava/lib/tag/eager/EagerInlineSetTagStrategy.java +++ b/src/main/java/com/hubspot/jinjava/lib/tag/eager/EagerInlineSetTagStrategy.java @@ -101,10 +101,7 @@ public Triple getPrefixTokenAndSuffix( .build() ) ); - String suffixToPreserveState = getSuffixToPreserveState( - String.join(",", Arrays.asList(variables)), - interpreter - ); + String suffixToPreserveState = getSuffixToPreserveState(variables, interpreter); return Triple.of( prefixToPreserveState.toString(), joiner.toString(), diff --git a/src/main/java/com/hubspot/jinjava/lib/tag/eager/EagerSetTagStrategy.java b/src/main/java/com/hubspot/jinjava/lib/tag/eager/EagerSetTagStrategy.java index 09e45b68b..9af7f2263 100644 --- a/src/main/java/com/hubspot/jinjava/lib/tag/eager/EagerSetTagStrategy.java +++ b/src/main/java/com/hubspot/jinjava/lib/tag/eager/EagerSetTagStrategy.java @@ -3,8 +3,9 @@ import com.google.common.annotations.Beta; import com.hubspot.jinjava.interpret.DeferredValueException; import com.hubspot.jinjava.interpret.JinjavaInterpreter; +import com.hubspot.jinjava.interpret.MetaContextVariables; import com.hubspot.jinjava.lib.tag.SetTag; -import com.hubspot.jinjava.lib.tag.eager.importing.AliasedEagerImportingStrategy; +import com.hubspot.jinjava.loader.RelativePathResolver; import com.hubspot.jinjava.tree.TagNode; import com.hubspot.jinjava.util.EagerReconstructionUtils; import com.hubspot.jinjava.util.PrefixToPreserveState; @@ -13,6 +14,7 @@ import java.util.Optional; import java.util.StringJoiner; import java.util.stream.Collectors; +import java.util.stream.Stream; import org.apache.commons.lang3.tuple.Triple; @Beta @@ -52,9 +54,14 @@ public String run(TagNode tagNode, JinjavaInterpreter interpreter) { expression, interpreter ); + boolean triedResolve = false; if ( eagerExecutionResult.getResult().isFullyResolved() && - !interpreter.getContext().isDeferredExecutionMode() + !interpreter.getContext().isDeferredExecutionMode() && + (Arrays + .stream(variables) + .noneMatch(RelativePathResolver.CURRENT_PATH_CONTEXT_KEY::equals) || + interpreter.getContext().getPenultimateParent().getDeferredTokens().isEmpty()) // Prevents set tags from disappearing in nested interpretation ) { EagerReconstructionUtils.commitSpeculativeBindings( interpreter, @@ -66,6 +73,7 @@ public String run(TagNode tagNode, JinjavaInterpreter interpreter) { eagerExecutionResult, interpreter ); + triedResolve = true; if (maybeResolved.isPresent()) { return maybeResolved.get(); } @@ -76,10 +84,7 @@ public String run(TagNode tagNode, JinjavaInterpreter interpreter) { eagerExecutionResult, interpreter ); - if ( - eagerExecutionResult.getResult().isFullyResolved() && - interpreter.getContext().isDeferredExecutionMode() - ) { + if (eagerExecutionResult.getResult().isFullyResolved() && !triedResolve) { attemptResolve(tagNode, variables, eagerExecutionResult, interpreter); } return buildImage(tagNode, variables, eagerExecutionResult, triple, interpreter); @@ -155,39 +160,66 @@ protected PrefixToPreserveState getPrefixToPreserveState( } public static String getSuffixToPreserveState( - String variables, + List varList, + JinjavaInterpreter interpreter + ) { + if (varList.isEmpty()) { + return ""; + } + return getSuffixToPreserveState(varList.stream(), interpreter); + } + + public static String getSuffixToPreserveState( + String[] varList, JinjavaInterpreter interpreter ) { - if (variables.isEmpty()) { + if (varList.length == 0) { return ""; } + return getSuffixToPreserveState(Arrays.stream(varList), interpreter); + } + + private static String getSuffixToPreserveState( + Stream varStream, + JinjavaInterpreter interpreter + ) { StringBuilder suffixToPreserveState = new StringBuilder(); - Optional maybeTemporaryImportAlias = - AliasedEagerImportingStrategy.getTemporaryImportAlias(interpreter.getContext()); - if ( - maybeTemporaryImportAlias.isPresent() && - !AliasedEagerImportingStrategy.isTemporaryImportAlias(variables) && - !interpreter.getContext().getComputedMetaContextVariables().contains(variables) - ) { - if (!interpreter.getContext().containsKey(maybeTemporaryImportAlias.get())) { - if ( - interpreter.retraceVariable( - String.format( - "%s.%s", - interpreter.getContext().getImportResourceAlias().get(), - variables - ), - -1 - ) != - null - ) { - throw new DeferredValueException( - "Cannot modify temporary import alias outside of import tag" - ); - } + Optional maybeTemporaryImportAlias = interpreter + .getContext() + .getImportResourceAlias() + .map(MetaContextVariables::getTemporaryImportAlias); + if (maybeTemporaryImportAlias.isPresent()) { + boolean stillInsideImportTag = interpreter + .getContext() + .containsKey(maybeTemporaryImportAlias.get()); + List filteredVars = varStream + .filter(var -> + !MetaContextVariables.isMetaContextVariable(var, interpreter.getContext()) + ) + .peek(var -> { + if (!stillInsideImportTag) { + if ( + interpreter.retraceVariable( + String.format( + "%s.%s", + interpreter.getContext().getImportResourceAlias().get(), + var + ), + -1 + ) != + null + ) { + throw new DeferredValueException( + "Cannot modify temporary import alias outside of import tag" + ); + } + } + }) + .collect(Collectors.toList()); + if (filteredVars.isEmpty()) { + return ""; } - String updateString = getUpdateString(variables); - + String updateString = getUpdateString(filteredVars); // Don't need to render because the temporary import alias's value is always deferred, and rendering will do nothing suffixToPreserveState.append( EagerReconstructionUtils.buildDoUpdateTag( @@ -197,15 +229,10 @@ public static String getSuffixToPreserveState( ) ); } - return suffixToPreserveState.toString(); } - private static String getUpdateString(String variables) { - List varList = Arrays - .stream(variables.split(",")) - .map(String::trim) - .collect(Collectors.toList()); + private static String getUpdateString(List varList) { StringJoiner updateString = new StringJoiner(","); // Update the alias map to the value of the set variable. varList.forEach(var -> updateString.add(String.format("'%s': %s", var, var))); diff --git a/src/main/java/com/hubspot/jinjava/lib/tag/eager/importing/AliasedEagerImportingStrategy.java b/src/main/java/com/hubspot/jinjava/lib/tag/eager/importing/AliasedEagerImportingStrategy.java index 74932f7fb..fa211714f 100644 --- a/src/main/java/com/hubspot/jinjava/lib/tag/eager/importing/AliasedEagerImportingStrategy.java +++ b/src/main/java/com/hubspot/jinjava/lib/tag/eager/importing/AliasedEagerImportingStrategy.java @@ -7,6 +7,7 @@ import com.hubspot.jinjava.interpret.DeferredValueException; import com.hubspot.jinjava.interpret.InterpretException; import com.hubspot.jinjava.interpret.JinjavaInterpreter; +import com.hubspot.jinjava.interpret.MetaContextVariables; import com.hubspot.jinjava.lib.fn.MacroFunction; import com.hubspot.jinjava.lib.tag.eager.DeferredToken; import com.hubspot.jinjava.objects.collections.PyMap; @@ -16,35 +17,12 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; -import java.util.Objects; import java.util.Optional; import java.util.StringJoiner; import java.util.stream.Stream; public class AliasedEagerImportingStrategy implements EagerImportingStrategy { - private static final String TEMPORARY_IMPORT_ALIAS_PREFIX = "__temp_import_alias_"; - private static final String TEMPORARY_IMPORT_ALIAS_FORMAT = - TEMPORARY_IMPORT_ALIAS_PREFIX + "%d__"; - - public static Optional getTemporaryImportAlias(Context context) { - return context - .getImportResourceAlias() - .map(AliasedEagerImportingStrategy::getTemporaryImportAlias); - } - - public static boolean isTemporaryImportAlias(String varName) { - // This is just faster than checking a regex - return varName.startsWith(TEMPORARY_IMPORT_ALIAS_PREFIX); - } - - private static String getTemporaryImportAlias(String fullAlias) { - return String.format( - TEMPORARY_IMPORT_ALIAS_FORMAT, - Math.abs(Objects.hashCode(fullAlias)) - ); - } - private final ImportingData importingData; private final String currentImportAlias; private final String fullImportAlias; @@ -95,7 +73,10 @@ public void setup(JinjavaInterpreter child) { importingData .getOriginalInterpreter() .getContext() - .put(getTemporaryImportAlias(fullImportAlias), DeferredValue.instance()); + .put( + MetaContextVariables.getTemporaryImportAlias(fullImportAlias), + DeferredValue.instance() + ); } @Override @@ -108,7 +89,9 @@ public void integrateChild(JinjavaInterpreter child) { } Map childBindings = child.getContext().getSessionBindings(); childBindings.putAll(child.getContext().getGlobalMacros()); - String temporaryImportAlias = getTemporaryImportAlias(fullImportAlias); + String temporaryImportAlias = MetaContextVariables.getTemporaryImportAlias( + fullImportAlias + ); Map mapForCurrentContextAlias = getMapForCurrentContextAlias( currentImportAlias, child @@ -127,14 +110,11 @@ public void integrateChild(JinjavaInterpreter child) { } @Override - public String getFinalOutput( - String newPathSetter, - String output, - JinjavaInterpreter child - ) { - String temporaryImportAlias = getTemporaryImportAlias(fullImportAlias); + public String getFinalOutput(String output, JinjavaInterpreter child) { + String temporaryImportAlias = MetaContextVariables.getTemporaryImportAlias( + fullImportAlias + ); return ( - newPathSetter + EagerReconstructionUtils.buildBlockOrInlineSetTag( temporaryImportAlias, Collections.emptyMap(), @@ -153,8 +133,7 @@ public String getFinalOutput( ImmutableMap.of(currentImportAlias, temporaryImportAlias), importingData.getOriginalInterpreter(), true - ) + - importingData.getInitialPathSetter() + ) ); } @@ -243,7 +222,9 @@ private String getDoTagToPreserve( JinjavaInterpreter child ) { StringJoiner keyValueJoiner = new StringJoiner(","); - String temporaryImportAlias = getTemporaryImportAlias(fullImportAlias); + String temporaryImportAlias = MetaContextVariables.getTemporaryImportAlias( + fullImportAlias + ); Map currentAliasMap = getMapForCurrentContextAlias( currentImportAlias, child diff --git a/src/main/java/com/hubspot/jinjava/lib/tag/eager/importing/EagerImportingStrategy.java b/src/main/java/com/hubspot/jinjava/lib/tag/eager/importing/EagerImportingStrategy.java index 77ac4ab7c..33e6fce8f 100644 --- a/src/main/java/com/hubspot/jinjava/lib/tag/eager/importing/EagerImportingStrategy.java +++ b/src/main/java/com/hubspot/jinjava/lib/tag/eager/importing/EagerImportingStrategy.java @@ -12,7 +12,7 @@ public interface EagerImportingStrategy { void setup(JinjavaInterpreter child); void integrateChild(JinjavaInterpreter child); - String getFinalOutput(String newPathSetter, String output, JinjavaInterpreter child); + String getFinalOutput(String output, JinjavaInterpreter child); static String getSetTagForDeferredChildBindings( JinjavaInterpreter interpreter, diff --git a/src/main/java/com/hubspot/jinjava/lib/tag/eager/importing/EagerImportingStrategyFactory.java b/src/main/java/com/hubspot/jinjava/lib/tag/eager/importing/EagerImportingStrategyFactory.java index c8833852b..1ab5fefc4 100644 --- a/src/main/java/com/hubspot/jinjava/lib/tag/eager/importing/EagerImportingStrategyFactory.java +++ b/src/main/java/com/hubspot/jinjava/lib/tag/eager/importing/EagerImportingStrategyFactory.java @@ -30,15 +30,7 @@ public static EagerImportingStrategy create(ImportingData importingData) { public static String getSetTagForCurrentPath(JinjavaInterpreter interpreter) { return EagerReconstructionUtils.buildBlockOrInlineSetTag( RelativePathResolver.CURRENT_PATH_CONTEXT_KEY, - interpreter - .getContext() - .getCurrentPathStack() - .peek() - .orElseGet(() -> - (String) interpreter - .getContext() - .getOrDefault(RelativePathResolver.CURRENT_PATH_CONTEXT_KEY, "") - ), + RelativePathResolver.getCurrentPathFromStackOrKey(interpreter), interpreter ); } diff --git a/src/main/java/com/hubspot/jinjava/lib/tag/eager/importing/FlatEagerImportingStrategy.java b/src/main/java/com/hubspot/jinjava/lib/tag/eager/importing/FlatEagerImportingStrategy.java index bb274441e..17b4e4d68 100644 --- a/src/main/java/com/hubspot/jinjava/lib/tag/eager/importing/FlatEagerImportingStrategy.java +++ b/src/main/java/com/hubspot/jinjava/lib/tag/eager/importing/FlatEagerImportingStrategy.java @@ -5,12 +5,12 @@ import com.hubspot.jinjava.interpret.DeferredValue; import com.hubspot.jinjava.interpret.DeferredValueException; import com.hubspot.jinjava.interpret.JinjavaInterpreter; +import com.hubspot.jinjava.interpret.MetaContextVariables; import com.hubspot.jinjava.lib.fn.MacroFunction; import com.hubspot.jinjava.lib.tag.ImportTag; import com.hubspot.jinjava.util.EagerReconstructionUtils; import java.util.Map; import java.util.Map.Entry; -import java.util.Set; import java.util.stream.Collectors; public class FlatEagerImportingStrategy implements EagerImportingStrategy { @@ -63,17 +63,10 @@ public void integrateChild(JinjavaInterpreter child) { } @Override - public String getFinalOutput( - String newPathSetter, - String output, - JinjavaInterpreter child - ) { + public String getFinalOutput(String output, JinjavaInterpreter child) { if (importingData.getOriginalInterpreter().getContext().isDeferredExecutionMode()) { - Set metaContextVariables = importingData - .getOriginalInterpreter() - .getContext() - .getComputedMetaContextVariables(); // defer imported variables + Context context = importingData.getOriginalInterpreter().getContext(); EagerReconstructionUtils.buildSetTag( child .getContext() @@ -83,21 +76,21 @@ public String getFinalOutput( .filter(entry -> !(entry.getValue() instanceof DeferredValue) && entry.getValue() != null ) - .filter(entry -> !metaContextVariables.contains(entry.getKey())) + .filter(entry -> + !MetaContextVariables.isMetaContextVariable(entry.getKey(), context) + ) .collect(Collectors.toMap(Entry::getKey, entry -> "")), importingData.getOriginalInterpreter(), true ); } return ( - newPathSetter + EagerImportingStrategy.getSetTagForDeferredChildBindings( importingData.getOriginalInterpreter(), null, child.getContext().getSessionBindings() ) + - output + - importingData.getInitialPathSetter() + output ); } } diff --git a/src/main/java/com/hubspot/jinjava/loader/RelativePathResolver.java b/src/main/java/com/hubspot/jinjava/loader/RelativePathResolver.java index 77690aef5..77a4493c3 100644 --- a/src/main/java/com/hubspot/jinjava/loader/RelativePathResolver.java +++ b/src/main/java/com/hubspot/jinjava/loader/RelativePathResolver.java @@ -11,13 +11,7 @@ public class RelativePathResolver implements LocationResolver { @Override public String resolve(String path, JinjavaInterpreter interpreter) { if (path.startsWith("./") || path.startsWith("../")) { - String parentPath = interpreter - .getContext() - .getCurrentPathStack() - .peek() - .orElseGet(() -> - (String) interpreter.getContext().getOrDefault(CURRENT_PATH_CONTEXT_KEY, "") - ); + String parentPath = getCurrentPathFromStackOrKey(interpreter); Path templatePath = Paths.get(parentPath); Path folderPath = templatePath.getParent() != null @@ -29,4 +23,14 @@ public String resolve(String path, JinjavaInterpreter interpreter) { } return path; } + + public static String getCurrentPathFromStackOrKey(JinjavaInterpreter interpreter) { + return interpreter + .getContext() + .getCurrentPathStack() + .peek() + .orElseGet(() -> + (String) interpreter.getContext().getOrDefault(CURRENT_PATH_CONTEXT_KEY, "") + ); + } } diff --git a/src/main/java/com/hubspot/jinjava/util/DeferredValueUtils.java b/src/main/java/com/hubspot/jinjava/util/DeferredValueUtils.java index ba26fb6d5..a2f11f8f9 100644 --- a/src/main/java/com/hubspot/jinjava/util/DeferredValueUtils.java +++ b/src/main/java/com/hubspot/jinjava/util/DeferredValueUtils.java @@ -6,6 +6,7 @@ import com.hubspot.jinjava.interpret.Context; import com.hubspot.jinjava.interpret.DeferredValue; import com.hubspot.jinjava.interpret.JinjavaInterpreter; +import com.hubspot.jinjava.interpret.MetaContextVariables; import com.hubspot.jinjava.interpret.PartiallyDeferredValue; import com.hubspot.jinjava.lib.tag.SetTag; import com.hubspot.jinjava.tree.ExpressionNode; @@ -119,7 +120,7 @@ private static void markDeferredProperties(Context context, Set props) { props .stream() .filter(prop -> !(context.get(prop) instanceof DeferredValue)) - .filter(prop -> !context.getComputedMetaContextVariables().contains(prop)) + .filter(prop -> !MetaContextVariables.isMetaContextVariable(prop, context)) .forEach(prop -> { Object value = context.get(prop); if (value != null) { diff --git a/src/main/java/com/hubspot/jinjava/util/EagerContextWatcher.java b/src/main/java/com/hubspot/jinjava/util/EagerContextWatcher.java index 6dcb266b3..5a3e8b3d5 100644 --- a/src/main/java/com/hubspot/jinjava/util/EagerContextWatcher.java +++ b/src/main/java/com/hubspot/jinjava/util/EagerContextWatcher.java @@ -2,11 +2,13 @@ import com.google.common.annotations.Beta; import com.hubspot.jinjava.interpret.CannotReconstructValueException; +import com.hubspot.jinjava.interpret.Context; import com.hubspot.jinjava.interpret.DeferredValue; import com.hubspot.jinjava.interpret.DeferredValueException; import com.hubspot.jinjava.interpret.JinjavaInterpreter; import com.hubspot.jinjava.interpret.JinjavaInterpreter.InterpreterScopeClosable; import com.hubspot.jinjava.interpret.LazyExpression; +import com.hubspot.jinjava.interpret.MetaContextVariables; import com.hubspot.jinjava.interpret.OneTimeReconstructible; import com.hubspot.jinjava.interpret.RevertibleObject; import com.hubspot.jinjava.lib.tag.eager.EagerExecutionResult; @@ -15,6 +17,7 @@ import com.hubspot.jinjava.objects.serialization.PyishObjectMapper; import com.hubspot.jinjava.util.EagerExpressionResolver.EagerExpressionResult; import java.util.AbstractMap; +import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; @@ -48,16 +51,13 @@ public static EagerExecutionResult executeInChildContext( JinjavaInterpreter interpreter, EagerChildContextConfig eagerChildContextConfig ) { - final Set metaContextVariables = interpreter - .getContext() - .getComputedMetaContextVariables(); final EagerExecutionResult initialResult; final Map speculativeBindings; if (eagerChildContextConfig.checkForContextChanges) { final Set> entrySet = interpreter.getContext().entrySet(); final Map initiallyResolvedHashes = getInitiallyResolvedHashes( entrySet, - metaContextVariables + interpreter.getContext() ); final Map initiallyResolvedAsStrings = getInitiallyResolvedAsStrings(interpreter, entrySet, initiallyResolvedHashes); @@ -66,15 +66,13 @@ public static EagerExecutionResult executeInChildContext( getAllSpeculativeBindings( interpreter, eagerChildContextConfig, - metaContextVariables, initiallyResolvedHashes, initiallyResolvedAsStrings, initialResult ); } else { - Set ignoredKeys = getKeysToIgnore( + Set ignoredKeys = getAdditionalKeysToIgnore( interpreter, - metaContextVariables, eagerChildContextConfig ); initialResult = applyFunction(function, interpreter, eagerChildContextConfig); @@ -140,12 +138,14 @@ private static Map getInitiallyResolvedAsStrings( private static Map getInitiallyResolvedHashes( Set> entrySet, - Set metaContextVariables + Context context ) { Map mapOfHashes = new HashMap<>(); entrySet .stream() - .filter(entry -> !metaContextVariables.contains(entry.getKey())) + .filter(entry -> + !MetaContextVariables.isMetaContextVariable(entry.getKey(), context) + ) .filter(entry -> !(entry.getValue() instanceof DeferredValue) && entry.getValue() != null ) @@ -155,9 +155,8 @@ private static Map getInitiallyResolvedHashes( return mapOfHashes; } - private static Set getKeysToIgnore( + private static Set getAdditionalKeysToIgnore( JinjavaInterpreter interpreter, - Set metaContextVariables, EagerChildContextConfig eagerChildContextConfig ) { // We don't need to reconstruct already deferred keys. @@ -166,18 +165,14 @@ private static Set getKeysToIgnore( interpreter.getContext().isDeferredExecutionMode() && !eagerChildContextConfig.takeNewValue ) - ? Stream - .concat( - metaContextVariables.stream(), - interpreter - .getContext() - .entrySet() - .stream() - .filter(entry -> entry.getValue() instanceof DeferredValue) - .map(Entry::getKey) - ) + ? interpreter + .getContext() + .entrySet() + .stream() + .filter(entry -> entry.getValue() instanceof DeferredValue) + .map(Entry::getKey) .collect(Collectors.toSet()) - : metaContextVariables; + : Collections.emptySet(); } private static Map getBasicSpeculativeBindings( @@ -209,6 +204,12 @@ private static Map getBasicSpeculativeBindings( .getSpeculativeBindings() .entrySet() .stream() + .filter(entry -> + !MetaContextVariables.isMetaContextVariable( + entry.getKey(), + interpreter.getContext() + ) + ) .filter(entry -> !ignoredKeys.contains(entry.getKey())) .filter(entry -> !"loop".equals(entry.getKey())) .map(entry -> { @@ -245,7 +246,6 @@ private static Map getBasicSpeculativeBindings( private static Map getAllSpeculativeBindings( JinjavaInterpreter interpreter, EagerChildContextConfig eagerChildContextConfig, - Set metaContextVariables, Map initiallyResolvedHashes, Map initiallyResolvedAsStrings, EagerExecutionResult eagerExecutionResult @@ -295,7 +295,12 @@ private static Map getAllSpeculativeBindings( speculativeBindings .entrySet() .stream() - .filter(entry -> !metaContextVariables.contains(entry.getKey())) + .filter(entry -> + !MetaContextVariables.isMetaContextVariable( + entry.getKey(), + interpreter.getContext() + ) + ) .filter(entry -> entry.getValue() != null) .filter(entry -> !isDeferredWithOriginalValueNull(entry.getValue())) .collect(Collectors.toMap(Entry::getKey, Entry::getValue)); diff --git a/src/main/java/com/hubspot/jinjava/util/EagerReconstructionUtils.java b/src/main/java/com/hubspot/jinjava/util/EagerReconstructionUtils.java index eb12536f5..85925b291 100644 --- a/src/main/java/com/hubspot/jinjava/util/EagerReconstructionUtils.java +++ b/src/main/java/com/hubspot/jinjava/util/EagerReconstructionUtils.java @@ -10,6 +10,7 @@ import com.hubspot.jinjava.interpret.DeferredValueShadow; import com.hubspot.jinjava.interpret.DisabledException; import com.hubspot.jinjava.interpret.JinjavaInterpreter; +import com.hubspot.jinjava.interpret.MetaContextVariables; import com.hubspot.jinjava.interpret.OneTimeReconstructible; import com.hubspot.jinjava.lib.fn.MacroFunction; import com.hubspot.jinjava.lib.fn.eager.EagerMacroFunction; @@ -21,8 +22,6 @@ import com.hubspot.jinjava.lib.tag.eager.DeferredToken; import com.hubspot.jinjava.lib.tag.eager.EagerExecutionResult; import com.hubspot.jinjava.lib.tag.eager.EagerSetTagStrategy; -import com.hubspot.jinjava.lib.tag.eager.importing.AliasedEagerImportingStrategy; -import com.hubspot.jinjava.lib.tag.eager.importing.EagerImportingStrategyFactory; import com.hubspot.jinjava.loader.RelativePathResolver; import com.hubspot.jinjava.objects.serialization.PyishBlockSetSerializable; import com.hubspot.jinjava.objects.serialization.PyishObjectMapper; @@ -37,9 +36,11 @@ import com.hubspot.jinjava.util.EagerContextWatcher.EagerChildContextConfig; import com.hubspot.jinjava.util.EagerExpressionResolver.EagerExpressionResult; import java.util.AbstractMap; +import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Objects; @@ -311,12 +312,11 @@ private static PrefixToPreserveState hydrateReconstructionOfVariablesBeforeDefer JinjavaInterpreter interpreter, int depth ) { - Set metaContextVariables = interpreter - .getContext() - .getComputedMetaContextVariables(); deferredWords .stream() - .filter(w -> !metaContextVariables.contains(w)) + .filter(w -> + !MetaContextVariables.isMetaContextVariable(w, interpreter.getContext()) + ) .filter(w -> !prefixToPreserveState.containsKey(w)) .map(word -> new AbstractMap.SimpleImmutableEntry<>(word, interpreter.getContext().get(word)) @@ -476,12 +476,12 @@ public static String buildSetTag( StringJoiner vars = new StringJoiner(","); StringJoiner values = new StringJoiner(","); - StringJoiner varsRequiringSuffix = new StringJoiner(","); + List varsRequiringSuffix = new ArrayList<>(); deferredValuesToSet.forEach((key, value) -> { // This ensures they are properly aligned to each other. vars.add(key); values.add(value); - if (!AliasedEagerImportingStrategy.isTemporaryImportAlias(value)) { + if (!MetaContextVariables.isTemporaryImportAlias(value)) { varsRequiringSuffix.add(key); } }); @@ -498,7 +498,7 @@ public static String buildSetTag( .add(interpreter.getConfig().getTokenScannerSymbols().getExpressionEndWithTag()); String image = result.toString(); String suffix = EagerSetTagStrategy.getSuffixToPreserveState( - varsRequiringSuffix.toString(), + varsRequiringSuffix, interpreter ); // Don't defer if we're sticking with the new value @@ -561,7 +561,10 @@ public static String buildBlockSetTag( .add("end" + SetTag.TAG_NAME) .add(interpreter.getConfig().getTokenScannerSymbols().getExpressionEndWithTag()); String image = blockSetTokenBuilder + value + endTokenBuilder; - String suffix = EagerSetTagStrategy.getSuffixToPreserveState(name, interpreter); + String suffix = EagerSetTagStrategy.getSuffixToPreserveState( + new String[] { name }, + interpreter + ); if (registerDeferredToken) { return ( new PrefixToPreserveState( @@ -914,26 +917,64 @@ public static void reconstructPathAroundBlock( OutputList blockValueBuilder, JinjavaInterpreter interpreter ) { - String blockPathSetter = EagerImportingStrategyFactory.getSetTagForCurrentPath( - interpreter - ); - String tempVarName = "temp_current_path_" + Math.abs(blockPathSetter.hashCode() >> 1); + String blockPath = RelativePathResolver.getCurrentPathFromStackOrKey(interpreter); + String tempVarName = MetaContextVariables.getTemporaryCurrentPathVarName(blockPath); prefix.setValue( buildSetTag( - ImmutableMap.of(tempVarName, RelativePathResolver.CURRENT_PATH_CONTEXT_KEY), + ImmutableMap.of( + tempVarName, + RelativePathResolver.CURRENT_PATH_CONTEXT_KEY, + RelativePathResolver.CURRENT_PATH_CONTEXT_KEY, + PyishObjectMapper.getAsPyishString(blockPath) + ), interpreter, false - ) + - EagerImportingStrategyFactory.getSetTagForCurrentPath(interpreter) + ) ); blockValueBuilder.addNode( new RenderedOutputNode( buildSetTag( - ImmutableMap.of(RelativePathResolver.CURRENT_PATH_CONTEXT_KEY, tempVarName), + ImmutableMap.of( + RelativePathResolver.CURRENT_PATH_CONTEXT_KEY, + tempVarName, + tempVarName, + "null" + ), interpreter, false ) ) ); } + + public static String wrapPathAroundText( + String text, + String newPath, + JinjavaInterpreter interpreter + ) { + String tempVarName = MetaContextVariables.getTemporaryCurrentPathVarName(newPath); + return ( + buildSetTag( + ImmutableMap.of( + tempVarName, + RelativePathResolver.CURRENT_PATH_CONTEXT_KEY, + RelativePathResolver.CURRENT_PATH_CONTEXT_KEY, + PyishObjectMapper.getAsPyishString(newPath) + ), + interpreter, + false + ) + + text + + buildSetTag( + ImmutableMap.of( + RelativePathResolver.CURRENT_PATH_CONTEXT_KEY, + tempVarName, + tempVarName, + "null" + ), + interpreter, + false + ) + ); + } } diff --git a/src/test/java/com/hubspot/jinjava/EagerTest.java b/src/test/java/com/hubspot/jinjava/EagerTest.java index d62d359a2..2f39838a8 100644 --- a/src/test/java/com/hubspot/jinjava/EagerTest.java +++ b/src/test/java/com/hubspot/jinjava/EagerTest.java @@ -1634,4 +1634,14 @@ public void prepareContext(Context context) { "keeps-meta-context-variables-through-import/test" ); } + + @Test + public void itWrapsMacroThatWouldChangeCurrentPathInChildScope() { + interpreter + .getContext() + .put(RelativePathResolver.CURRENT_PATH_CONTEXT_KEY, "starting path"); + expectedTemplateInterpreter.assertExpectedOutputNonIdempotent( + "wraps-macro-that-would-change-current-path-in-child-scope/test" + ); + } } diff --git a/src/test/java/com/hubspot/jinjava/ExpectedTemplateInterpreter.java b/src/test/java/com/hubspot/jinjava/ExpectedTemplateInterpreter.java index 7af7bd559..e12907b74 100644 --- a/src/test/java/com/hubspot/jinjava/ExpectedTemplateInterpreter.java +++ b/src/test/java/com/hubspot/jinjava/ExpectedTemplateInterpreter.java @@ -6,6 +6,7 @@ import com.google.common.io.Resources; import com.hubspot.jinjava.interpret.JinjavaInterpreter; import com.hubspot.jinjava.interpret.JinjavaInterpreter.InterpreterScopeClosable; +import com.hubspot.jinjava.loader.RelativePathResolver; import com.hubspot.jinjava.mode.DefaultExecutionMode; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -147,6 +148,12 @@ public String getFixtureTemplate(String name) { .getContext() .getCurrentPathStack() .push(String.format("%s/%s.jinja", path, name), 0, 0); + interpreter + .getContext() + .put( + RelativePathResolver.CURRENT_PATH_CONTEXT_KEY, + String.format("%s/%s.jinja", path, name) + ); } return simplify( Resources.toString( diff --git a/src/test/java/com/hubspot/jinjava/interpret/ContextTest.java b/src/test/java/com/hubspot/jinjava/interpret/ContextTest.java index 7ed722a58..71a310a63 100644 --- a/src/test/java/com/hubspot/jinjava/interpret/ContextTest.java +++ b/src/test/java/com/hubspot/jinjava/interpret/ContextTest.java @@ -6,6 +6,9 @@ import com.google.common.collect.ImmutableMap; import com.hubspot.jinjava.Jinjava; import com.hubspot.jinjava.lib.fn.ELFunctionDefinition; +import com.hubspot.jinjava.loader.RelativePathResolver; +import com.hubspot.jinjava.mode.EagerExecutionMode; +import java.util.Collections; import org.junit.Before; import org.junit.Test; @@ -93,6 +96,30 @@ public void itThrowsFromChildContext() throws Exception { } } + @Test + public void itRemovesOtherMetaContextVariables() { + String variableName = "foo"; + EagerExecutionMode.instance().prepareContext(context); + context.addMetaContextVariables(Collections.singleton(variableName)); + assertThat(context.getComputedMetaContextVariables()).contains(variableName); + context.addNonMetaContextVariables(Collections.singleton(variableName)); + assertThat(context.getComputedMetaContextVariables()).doesNotContain(variableName); + context.removeNonMetaContextVariables(Collections.singleton(variableName)); + assertThat(context.getComputedMetaContextVariables()).contains(variableName); + } + + @Test + public void itDoesNotRemoveStaticMetaContextVariables() { + EagerExecutionMode.instance().prepareContext(context); + assertThat(context.getComputedMetaContextVariables()) + .contains(RelativePathResolver.CURRENT_PATH_CONTEXT_KEY); + context.addNonMetaContextVariables( + Collections.singleton(RelativePathResolver.CURRENT_PATH_CONTEXT_KEY) + ); + assertThat(context.getComputedMetaContextVariables()) + .contains(RelativePathResolver.CURRENT_PATH_CONTEXT_KEY); + } + public static void throwException() { throw new RuntimeException(); } diff --git a/src/test/java/com/hubspot/jinjava/lib/fn/eager/EagerMacroFunctionTest.java b/src/test/java/com/hubspot/jinjava/lib/fn/eager/EagerMacroFunctionTest.java index b14b56a33..142f81298 100644 --- a/src/test/java/com/hubspot/jinjava/lib/fn/eager/EagerMacroFunctionTest.java +++ b/src/test/java/com/hubspot/jinjava/lib/fn/eager/EagerMacroFunctionTest.java @@ -111,7 +111,7 @@ public void itPartiallyEvaluatesMacroFunction() { .isInstanceOf(DeferredValueException.class); try (TemporaryValueClosable ignored = context.withPartialMacroEvaluation()) { assertThat(eagerMacroFunction.evaluate("Bar")) - .isEqualTo("It's: Bar, {{ deferred }}"); + .isEqualTo("{% for __ignored__ in [0] %}It's: Bar, {{ deferred }}{% endfor %}"); } } diff --git a/src/test/java/com/hubspot/jinjava/lib/tag/eager/EagerImportTagTest.java b/src/test/java/com/hubspot/jinjava/lib/tag/eager/EagerImportTagTest.java index 632de43a6..031f7183d 100644 --- a/src/test/java/com/hubspot/jinjava/lib/tag/eager/EagerImportTagTest.java +++ b/src/test/java/com/hubspot/jinjava/lib/tag/eager/EagerImportTagTest.java @@ -331,6 +331,7 @@ public void itDefersTripleLayer() { removeDeferredContextKeys(); context.put("a_val", "a"); // There are some extras due to deferred values copying up the context stack. + context.getDeferredTokens().clear(); assertThat(interpreter.render(result).trim()) .isEqualTo( interpreter.render( @@ -363,6 +364,7 @@ public void itDefersQuadLayer() { removeDeferredContextKeys(); context.put("a_val", "a"); + context.getDeferredTokens().clear(); assertThat(interpreter.render(result).trim()).isEqualTo("12345 cbaabaaba"); } @@ -376,11 +378,11 @@ public void itHandlesQuadLayerInDeferredIf() { ); assertThat(result) .isEqualTo( - "{% if deferred %}{% do %}{% set current_path = 'import-tree-b.jinja' %}{% set __temp_import_alias_98__ = {} %}{% for __ignored__ in [0] %}{% do %}{% set current_path = 'import-tree-a.jinja' %}{% set __temp_import_alias_95701__ = {} %}{% for __ignored__ in [0] %}{% set something = 'somn' %}{% do __temp_import_alias_95701__.update({'something': something}) %}\n" + - "{% set foo_a = 'a' %}{% do __temp_import_alias_95701__.update({'foo_a': foo_a}) %}\n" + - "{% do __temp_import_alias_95701__.update({'foo_a': 'a','import_resource_path': 'import-tree-a.jinja','something': 'somn'}) %}{% endfor %}{% set a = __temp_import_alias_95701__ %}{% set current_path = 'import-tree-b.jinja' %}{% enddo %}\n" + - "{% set foo_b = 'b' + a.foo_a %}{% do __temp_import_alias_98__.update({'foo_b': foo_b}) %}\n" + - "{% do __temp_import_alias_98__.update({'a': a,'foo_b': foo_b,'import_resource_path': 'import-tree-b.jinja'}) %}{% endfor %}{% set b = __temp_import_alias_98__ %}{% set current_path = '' %}{% enddo %}{% endif %}" + "{% if deferred %}{% do %}{% set __temp_meta_current_path_930119534__,current_path = current_path,'import-tree-b.jinja' %}{% set __temp_meta_import_alias_98__ = {} %}{% for __ignored__ in [0] %}{% do %}{% set __temp_meta_current_path_58714367__,current_path = current_path,'import-tree-a.jinja' %}{% set __temp_meta_import_alias_95701__ = {} %}{% for __ignored__ in [0] %}{% set something = 'somn' %}{% do __temp_meta_import_alias_95701__.update({'something': something}) %}\n" + + "{% set foo_a = 'a' %}{% do __temp_meta_import_alias_95701__.update({'foo_a': foo_a}) %}\n" + + "{% do __temp_meta_import_alias_95701__.update({'foo_a': 'a','import_resource_path': 'import-tree-a.jinja','something': 'somn'}) %}{% endfor %}{% set a = __temp_meta_import_alias_95701__ %}{% set current_path,__temp_meta_current_path_58714367__ = __temp_meta_current_path_58714367__,null %}{% enddo %}\n" + + "{% set foo_b = 'b' + a.foo_a %}{% do __temp_meta_import_alias_98__.update({'foo_b': foo_b}) %}\n" + + "{% do __temp_meta_import_alias_98__.update({'a': a,'foo_b': foo_b,'import_resource_path': 'import-tree-b.jinja'}) %}{% endfor %}{% set b = __temp_meta_import_alias_98__ %}{% set current_path,__temp_meta_current_path_930119534__ = __temp_meta_current_path_930119534__,null %}{% enddo %}{% endif %}" ); removeDeferredContextKeys(); @@ -562,10 +564,16 @@ public void itHandlesVarFromImportedMacro() { ); assertThat(result.trim()) .isEqualTo( - "{% set var = [] %}{% do var.append('a' ~ deferred) %}" + - "a\n" + + "{% set var = [] %}" + + "{% set __macro_adjust_108896029_temp_variable_0__ %}" + + "{% do var.append('a' ~ deferred) %}" + + "a" + + "{% endset %}" + + "{{ __macro_adjust_108896029_temp_variable_0__ }}\n" + + "{% for __ignored__ in [0] %}" + "{% do var.append('b' ~ deferred) %}" + - "b\n" + + "b" + + "{% endfor %}\n" + "c{{ var }}" ); context.put("deferred", "resolved"); @@ -632,13 +640,24 @@ public void itDoesNotSilentlyOverrideVariable() { assertThat(result) .isEqualTo( "a" + - "{% set vars = {'foo': 'a', 'import_resource_path': 'var-a.jinja'} %}{% if deferred %}" + - "{% do %}{% set current_path = 'var-b.jinja' %}{% set __temp_import_alias_3612204__ = {} %}{% for __ignored__ in [0] %}{% set foo = 'b' %}{% do __temp_import_alias_3612204__.update({'foo': foo}) %}\n" + - "{% do __temp_import_alias_3612204__.update({'foo': 'b','import_resource_path': 'var-b.jinja'}) %}{% endfor %}{% set vars = __temp_import_alias_3612204__ %}{% set current_path = '' %}{% enddo %}" + + "{% set vars = {'foo': 'a', 'import_resource_path': 'var-a.jinja'} %}" + + "{% if deferred %}" + + "{% do %}" + + "{% set __temp_meta_current_path_299252430__,current_path = current_path,'var-b.jinja' %}" + + "{% set __temp_meta_import_alias_3612204__ = {} %}" + + "{% for __ignored__ in [0] %}" + + "{% set foo = 'b' %}" + + "{% do __temp_meta_import_alias_3612204__.update({'foo': foo}) %}\n" + + "{% do __temp_meta_import_alias_3612204__.update({'foo': 'b','import_resource_path': 'var-b.jinja'}) %}" + + "{% endfor %}" + + "{% set vars = __temp_meta_import_alias_3612204__ %}" + + "{% set current_path,__temp_meta_current_path_299252430__ = __temp_meta_current_path_299252430__,null %}" + + "{% enddo %}" + "{% endif %}" + "{{ vars.foo }}" ); interpreter.getContext().put("deferred", "resolved"); + context.getDeferredTokens().clear(); assertThat(interpreter.render(result)).isEqualTo("ab"); } @@ -659,14 +678,19 @@ public void itDoesNotSilentlyOverrideVariableWithoutAlias() { assertThat(result) .isEqualTo( "a" + - "{% set foo = 'a' %}{% if deferred %}" + - "{% do %}{% set current_path = 'var-b.jinja' %}{% set foo = 'b' %}\n" + - "{% set current_path = '' %}{% enddo %}" + + "{% set foo = 'a' %}" + + "{% if deferred %}" + + "{% do %}" + + "{% set __temp_meta_current_path_299252430__,current_path = current_path,'var-b.jinja' %}" + + "{% set foo = 'b' %}\n" + + "{% set current_path,__temp_meta_current_path_299252430__ = __temp_meta_current_path_299252430__,null %}" + + "{% enddo %}" + "{% endif %}" + "{{ foo }}" ); interpreter.getContext().put("deferred", "resolved"); + context.getDeferredTokens().clear(); assertThat(interpreter.render(result)).isEqualTo("ab"); } @@ -678,9 +702,13 @@ public void itDoesNotDeferImportedVariablesWhenNotInDeferredExecutionMode() { .trim(); assertThat(result) .isEqualTo( - "{% do %}{% set current_path = 'set-two-variables.jinja' %}{% set foo = deferred %}\n" + + "{% do %}" + + "{% set __temp_meta_current_path_549676938__,current_path = current_path,'set-two-variables.jinja' %}" + + "{% set foo = deferred %}\n" + "\n" + - "{% set current_path = '' %}{% enddo %}{{ foo }} bar" + "{% set current_path,__temp_meta_current_path_549676938__ = __temp_meta_current_path_549676938__,null %}" + + "{% enddo %}" + + "{{ foo }} bar" ); } diff --git a/src/test/java/com/hubspot/jinjava/util/EagerReconstructionUtilsTest.java b/src/test/java/com/hubspot/jinjava/util/EagerReconstructionUtilsTest.java index 2db59282d..2d15063d9 100644 --- a/src/test/java/com/hubspot/jinjava/util/EagerReconstructionUtilsTest.java +++ b/src/test/java/com/hubspot/jinjava/util/EagerReconstructionUtilsTest.java @@ -18,7 +18,6 @@ import com.hubspot.jinjava.lib.fn.eager.EagerMacroFunction; import com.hubspot.jinjava.lib.tag.eager.DeferredToken; import com.hubspot.jinjava.lib.tag.eager.EagerExecutionResult; -import com.hubspot.jinjava.loader.RelativePathResolver; import com.hubspot.jinjava.mode.DefaultExecutionMode; import com.hubspot.jinjava.mode.EagerExecutionMode; import com.hubspot.jinjava.mode.PreserveRawExecutionMode; @@ -343,37 +342,6 @@ public void itIgnoresMetaContextVariables() { .isEmpty(); } - @Test - public void itRemovesOtherMetaContextVariables() { - String variableName = "foo"; - interpreter.getContext().addMetaContextVariables(Collections.singleton(variableName)); - assertThat(interpreter.getContext().getComputedMetaContextVariables()) - .contains(variableName); - interpreter - .getContext() - .addNonMetaContextVariables(Collections.singleton(variableName)); - assertThat(interpreter.getContext().getComputedMetaContextVariables()) - .doesNotContain(variableName); - interpreter - .getContext() - .removeNonMetaContextVariables(Collections.singleton(variableName)); - assertThat(interpreter.getContext().getComputedMetaContextVariables()) - .contains(variableName); - } - - @Test - public void itDoesNotRemoveStaticMetaContextVariables() { - assertThat(interpreter.getContext().getComputedMetaContextVariables()) - .contains(RelativePathResolver.CURRENT_PATH_CONTEXT_KEY); - interpreter - .getContext() - .addNonMetaContextVariables( - Collections.singleton(RelativePathResolver.CURRENT_PATH_CONTEXT_KEY) - ); - assertThat(interpreter.getContext().getComputedMetaContextVariables()) - .contains(RelativePathResolver.CURRENT_PATH_CONTEXT_KEY); - } - @Test public void itDiscardsSessionBindings() { interpreter.getContext().put("foo", "bar"); diff --git a/src/test/resources/eager/allows-variable-sharing-alias-name/test.expected.jinja b/src/test/resources/eager/allows-variable-sharing-alias-name/test.expected.jinja index bb8d623e4..fd7a323fa 100644 --- a/src/test/resources/eager/allows-variable-sharing-alias-name/test.expected.jinja +++ b/src/test/resources/eager/allows-variable-sharing-alias-name/test.expected.jinja @@ -1,17 +1,17 @@ {% do %}\ -{% set current_path = 'eager/allows-variable-sharing-alias-name/filters.jinja' %}\ -{% set __temp_import_alias_854547461__ = {} %}\ +{% set __temp_meta_current_path_200847175__,current_path = current_path,'eager/allows-variable-sharing-alias-name/filters.jinja' %}\ +{% set __temp_meta_import_alias_854547461__ = {} %}\ {% for __ignored__ in [0] %} {% set bar = deferred %}\ -{% do __temp_import_alias_854547461__.update({'bar': bar}) %} +{% do __temp_meta_import_alias_854547461__.update({'bar': bar}) %} {% set filters = {} %}\ -{% do __temp_import_alias_854547461__.update({'filters': filters}) %}\ +{% do __temp_meta_import_alias_854547461__.update({'filters': filters}) %}\ {% do filters.update(deferred) %} -{% do __temp_import_alias_854547461__.update({'bar': bar,'foo': 123,'import_resource_path': 'eager/allows-variable-sharing-alias-name/filters.jinja','filters': filters}) %}\ +{% do __temp_meta_import_alias_854547461__.update({'bar': bar,'foo': 123,'import_resource_path': 'eager/allows-variable-sharing-alias-name/filters.jinja','filters': filters}) %}\ {% endfor %}\ -{% set filters = __temp_import_alias_854547461__ %}\ -{% set current_path = 'eager/allows-variable-sharing-alias-name/test.jinja' %}\ +{% set filters = __temp_meta_import_alias_854547461__ %}\ +{% set current_path,__temp_meta_current_path_200847175__ = __temp_meta_current_path_200847175__,null %}\ {% enddo %} {{ filters }} diff --git a/src/test/resources/eager/defers-caller/test.expected.jinja b/src/test/resources/eager/defers-caller/test.expected.jinja index 27f605f5b..8063c5857 100644 --- a/src/test/resources/eager/defers-caller/test.expected.jinja +++ b/src/test/resources/eager/defers-caller/test.expected.jinja @@ -1,3 +1,4 @@ +{% for __ignored__ in [0] %}\ Jack says: How do I get a {{ deferred }}\ -? +?{% endfor %} diff --git a/src/test/resources/eager/does-not-override-import-modification-in-for/test.expected.jinja b/src/test/resources/eager/does-not-override-import-modification-in-for/test.expected.jinja index 3273f7c18..0e1e4a8a2 100644 --- a/src/test/resources/eager/does-not-override-import-modification-in-for/test.expected.jinja +++ b/src/test/resources/eager/does-not-override-import-modification-in-for/test.expected.jinja @@ -1,81 +1,81 @@ {% set foo = 'start' %}\ {% for __ignored__ in [0] %} {% do %}\ -{% set current_path = 'eager/supplements/deferred-modification.jinja' %}\ -{% set __temp_import_alias_3016318__ = {} %}\ +{% set __temp_meta_current_path_461135149__,current_path = current_path,'eager/supplements/deferred-modification.jinja' %}\ +{% set __temp_meta_import_alias_3016318__ = {} %}\ {% for __ignored__ in [0] %}\ {% if deferred %} {% set foo = 'starta' %}\ -{% do __temp_import_alias_3016318__.update({'foo': foo}) %} +{% do __temp_meta_import_alias_3016318__.update({'foo': foo}) %} {% endif %} {% set foo = filter:join.filter([foo, 'b'], ____int3rpr3t3r____, '') %}\ -{% do __temp_import_alias_3016318__.update({'foo': foo}) %} -{% do __temp_import_alias_3016318__.update({'foo': foo,'import_resource_path': 'eager/supplements/deferred-modification.jinja'}) %}\ +{% do __temp_meta_import_alias_3016318__.update({'foo': foo}) %} +{% do __temp_meta_import_alias_3016318__.update({'foo': foo,'import_resource_path': 'eager/supplements/deferred-modification.jinja'}) %}\ {% endfor %}\ -{% set bar1 = __temp_import_alias_3016318__ %}\ -{% set current_path = 'eager/does-not-override-import-modification-in-for/test.jinja' %}\ +{% set bar1 = __temp_meta_import_alias_3016318__ %}\ +{% set current_path,__temp_meta_current_path_461135149__ = __temp_meta_current_path_461135149__,null %}\ {% enddo %} {{ bar1.foo }} {% do %}\ -{% set current_path = 'eager/supplements/deferred-modification.jinja' %}\ -{% set __temp_import_alias_3016319__ = {} %}\ +{% set __temp_meta_current_path_461135149__,current_path = current_path,'eager/supplements/deferred-modification.jinja' %}\ +{% set __temp_meta_import_alias_3016319__ = {} %}\ {% for __ignored__ in [0] %}\ {% if deferred %} {% set foo = filter:join.filter([foo, 'a'], ____int3rpr3t3r____, '') %}\ -{% do __temp_import_alias_3016319__.update({'foo': foo}) %} +{% do __temp_meta_import_alias_3016319__.update({'foo': foo}) %} {% endif %} {% set foo = filter:join.filter([foo, 'b'], ____int3rpr3t3r____, '') %}\ -{% do __temp_import_alias_3016319__.update({'foo': foo}) %} -{% do __temp_import_alias_3016319__.update({'import_resource_path': 'eager/supplements/deferred-modification.jinja'}) %}\ +{% do __temp_meta_import_alias_3016319__.update({'foo': foo}) %} +{% do __temp_meta_import_alias_3016319__.update({'import_resource_path': 'eager/supplements/deferred-modification.jinja'}) %}\ {% endfor %}\ -{% set bar2 = __temp_import_alias_3016319__ %}\ -{% set current_path = 'eager/does-not-override-import-modification-in-for/test.jinja' %}\ +{% set bar2 = __temp_meta_import_alias_3016319__ %}\ +{% set current_path,__temp_meta_current_path_461135149__ = __temp_meta_current_path_461135149__,null %}\ {% enddo %} {{ bar2.foo }} {% do %}\ -{% set current_path = 'eager/supplements/deferred-modification.jinja' %}\ -{% set __temp_import_alias_3016318__ = {} %}\ +{% set __temp_meta_current_path_461135149__,current_path = current_path,'eager/supplements/deferred-modification.jinja' %}\ +{% set __temp_meta_import_alias_3016318__ = {} %}\ {% for __ignored__ in [0] %}\ {% if deferred %} {% set foo = filter:join.filter([foo, 'a'], ____int3rpr3t3r____, '') %}\ -{% do __temp_import_alias_3016318__.update({'foo': foo}) %} +{% do __temp_meta_import_alias_3016318__.update({'foo': foo}) %} {% endif %} {% set foo = filter:join.filter([foo, 'b'], ____int3rpr3t3r____, '') %}\ -{% do __temp_import_alias_3016318__.update({'foo': foo}) %} -{% do __temp_import_alias_3016318__.update({'import_resource_path': 'eager/supplements/deferred-modification.jinja'}) %}\ +{% do __temp_meta_import_alias_3016318__.update({'foo': foo}) %} +{% do __temp_meta_import_alias_3016318__.update({'import_resource_path': 'eager/supplements/deferred-modification.jinja'}) %}\ {% endfor %}\ -{% set bar1 = __temp_import_alias_3016318__ %}\ -{% set current_path = 'eager/does-not-override-import-modification-in-for/test.jinja' %}\ +{% set bar1 = __temp_meta_import_alias_3016318__ %}\ +{% set current_path,__temp_meta_current_path_461135149__ = __temp_meta_current_path_461135149__,null %}\ {% enddo %} {{ bar1.foo }} {% do %}\ -{% set current_path = 'eager/supplements/deferred-modification.jinja' %}\ -{% set __temp_import_alias_3016319__ = {} %}\ +{% set __temp_meta_current_path_461135149__,current_path = current_path,'eager/supplements/deferred-modification.jinja' %}\ +{% set __temp_meta_import_alias_3016319__ = {} %}\ {% for __ignored__ in [0] %}\ {% if deferred %} {% set foo = filter:join.filter([foo, 'a'], ____int3rpr3t3r____, '') %}\ -{% do __temp_import_alias_3016319__.update({'foo': foo}) %} +{% do __temp_meta_import_alias_3016319__.update({'foo': foo}) %} {% endif %} {% set foo = filter:join.filter([foo, 'b'], ____int3rpr3t3r____, '') %}\ -{% do __temp_import_alias_3016319__.update({'foo': foo}) %} -{% do __temp_import_alias_3016319__.update({'import_resource_path': 'eager/supplements/deferred-modification.jinja'}) %}\ +{% do __temp_meta_import_alias_3016319__.update({'foo': foo}) %} +{% do __temp_meta_import_alias_3016319__.update({'import_resource_path': 'eager/supplements/deferred-modification.jinja'}) %}\ {% endfor %}\ -{% set bar2 = __temp_import_alias_3016319__ %}\ -{% set current_path = 'eager/does-not-override-import-modification-in-for/test.jinja' %}\ +{% set bar2 = __temp_meta_import_alias_3016319__ %}\ +{% set current_path,__temp_meta_current_path_461135149__ = __temp_meta_current_path_461135149__,null %}\ {% enddo %} {{ bar2.foo }} {% endfor %} -{{ foo }} +{{ foo }} \ No newline at end of file diff --git a/src/test/resources/eager/does-not-reconstruct-variable-in-wrong-scope/test.expected.jinja b/src/test/resources/eager/does-not-reconstruct-variable-in-wrong-scope/test.expected.jinja index 5fe8a8f32..a403d3d68 100644 --- a/src/test/resources/eager/does-not-reconstruct-variable-in-wrong-scope/test.expected.jinja +++ b/src/test/resources/eager/does-not-reconstruct-variable-in-wrong-scope/test.expected.jinja @@ -12,8 +12,8 @@ {% endset %}\ {{ __macro_append_stuff_153654787_temp_variable_0__ }} {% endif %} - +{% for __ignored__ in [0] %} {% do my_list.append('d') %} - +{% endfor %} {{ my_list }} diff --git a/src/test/resources/eager/handles-deferred-from-import-as/test.expected.jinja b/src/test/resources/eager/handles-deferred-from-import-as/test.expected.jinja index 6ac262b61..8bca72eb8 100644 --- a/src/test/resources/eager/handles-deferred-from-import-as/test.expected.jinja +++ b/src/test/resources/eager/handles-deferred-from-import-as/test.expected.jinja @@ -1,7 +1,9 @@ {% set myname = deferred + 7 %}\ {% do %} {% set bar = myname + 19 %} -Hello {{ myname }} +{% for __ignored__ in [0] %}\ +Hello {{ myname }}\ +{% endfor %} {% set from_bar = bar %}\ {% enddo %}\ from_foo: Hello {{ myname }} diff --git a/src/test/resources/eager/handles-deferred-import-vars/test.expected.jinja b/src/test/resources/eager/handles-deferred-import-vars/test.expected.jinja index ec5c2320d..a04803b11 100644 --- a/src/test/resources/eager/handles-deferred-import-vars/test.expected.jinja +++ b/src/test/resources/eager/handles-deferred-import-vars/test.expected.jinja @@ -1,23 +1,29 @@ {% set myname = deferred + 3 %}\ {% do %} {% set bar = myname + 19 %} -Hello {{ myname }} +{% for __ignored__ in [0] %}\ +Hello {{ myname }}\ +{% endfor %} {% enddo %}\ -foo: Hello {{ myname }} +foo: {% for __ignored__ in [0] %}\ +Hello {{ myname }}\ +{% endfor %} bar: {{ bar }} --- {% set myname = deferred + 7 %}\ {% do %}\ -{% set current_path = 'eager/supplements/macro-and-set.jinja' %}\ -{% set __temp_import_alias_902286926__ = {} %}\ +{% set __temp_meta_current_path_822093108__,current_path = current_path,'eager/supplements/macro-and-set.jinja' %}\ +{% set __temp_meta_import_alias_902286926__ = {} %}\ {% for __ignored__ in [0] %} {% set bar = myname + 19 %}\ -{% do __temp_import_alias_902286926__.update({'bar': bar}) %} -Hello {{ myname }} -{% do __temp_import_alias_902286926__.update({'import_resource_path': 'eager/supplements/macro-and-set.jinja'}) %}\ +{% do __temp_meta_import_alias_902286926__.update({'bar': bar}) %} +{% for __ignored__ in [0] %}\ +Hello {{ myname }}\ +{% endfor %} +{% do __temp_meta_import_alias_902286926__.update({'import_resource_path': 'eager/supplements/macro-and-set.jinja'}) %}\ {% endfor %}\ -{% set simple = __temp_import_alias_902286926__ %}\ -{% set current_path = 'eager/handles-deferred-import-vars/test.jinja' %}\ +{% set simple = __temp_meta_import_alias_902286926__ %}\ +{% set current_path,__temp_meta_current_path_822093108__ = __temp_meta_current_path_822093108__,null %}\ {% enddo %}\ simple.foo: {% set deferred_import_resource_path = 'eager/supplements/macro-and-set.jinja' %}\ {% macro simple.foo() %}\ diff --git a/src/test/resources/eager/handles-double-import-modification/test.expected.jinja b/src/test/resources/eager/handles-double-import-modification/test.expected.jinja index 9cb830dff..66acdde36 100644 --- a/src/test/resources/eager/handles-double-import-modification/test.expected.jinja +++ b/src/test/resources/eager/handles-double-import-modification/test.expected.jinja @@ -1,39 +1,39 @@ {% do %}\ -{% set current_path = 'eager/supplements/deferred-modification.jinja' %}\ -{% set __temp_import_alias_3016318__ = {} %}\ +{% set __temp_meta_current_path_461135149__,current_path = current_path,'eager/supplements/deferred-modification.jinja' %}\ +{% set __temp_meta_import_alias_3016318__ = {} %}\ {% for __ignored__ in [0] %}\ {% if deferred %} {% set foo = 'a' %}\ -{% do __temp_import_alias_3016318__.update({'foo': foo}) %} +{% do __temp_meta_import_alias_3016318__.update({'foo': foo}) %} {% endif %} {% set foo = filter:join.filter([foo, 'b'], ____int3rpr3t3r____, '') %}\ -{% do __temp_import_alias_3016318__.update({'foo': foo}) %} -{% do __temp_import_alias_3016318__.update({'foo': foo,'import_resource_path': 'eager/supplements/deferred-modification.jinja'}) %}\ +{% do __temp_meta_import_alias_3016318__.update({'foo': foo}) %} +{% do __temp_meta_import_alias_3016318__.update({'foo': foo,'import_resource_path': 'eager/supplements/deferred-modification.jinja'}) %}\ {% endfor %}\ -{% set bar1 = __temp_import_alias_3016318__ %}\ -{% set current_path = 'eager/handles-double-import-modification/test.jinja' %}\ +{% set bar1 = __temp_meta_import_alias_3016318__ %}\ +{% set current_path,__temp_meta_current_path_461135149__ = __temp_meta_current_path_461135149__,null %}\ {% enddo %} --- {% do %}\ -{% set current_path = 'eager/supplements/deferred-modification.jinja' %}\ -{% set __temp_import_alias_3016319__ = {} %}\ +{% set __temp_meta_current_path_461135149__,current_path = current_path,'eager/supplements/deferred-modification.jinja' %}\ +{% set __temp_meta_import_alias_3016319__ = {} %}\ {% for __ignored__ in [0] %}\ {% if deferred %} {% set foo = 'a' %}\ -{% do __temp_import_alias_3016319__.update({'foo': foo}) %} +{% do __temp_meta_import_alias_3016319__.update({'foo': foo}) %} {% endif %} {% set foo = filter:join.filter([foo, 'b'], ____int3rpr3t3r____, '') %}\ -{% do __temp_import_alias_3016319__.update({'foo': foo}) %} -{% do __temp_import_alias_3016319__.update({'foo': foo,'import_resource_path': 'eager/supplements/deferred-modification.jinja'}) %}\ +{% do __temp_meta_import_alias_3016319__.update({'foo': foo}) %} +{% do __temp_meta_import_alias_3016319__.update({'foo': foo,'import_resource_path': 'eager/supplements/deferred-modification.jinja'}) %}\ {% endfor %}\ -{% set bar2 = __temp_import_alias_3016319__ %}\ -{% set current_path = 'eager/handles-double-import-modification/test.jinja' %}\ +{% set bar2 = __temp_meta_import_alias_3016319__ %}\ +{% set current_path,__temp_meta_current_path_461135149__ = __temp_meta_current_path_461135149__,null %}\ {% enddo %} --- {{ bar1.foo }} diff --git a/src/test/resources/eager/handles-import-in-deferred-if/test.expected.jinja b/src/test/resources/eager/handles-import-in-deferred-if/test.expected.jinja index 7d1cd45a0..b26dd23fc 100644 --- a/src/test/resources/eager/handles-import-in-deferred-if/test.expected.jinja +++ b/src/test/resources/eager/handles-import-in-deferred-if/test.expected.jinja @@ -1,21 +1,21 @@ {% set primary_line_height = 100 %}\ {% if deferred %} {% do %}\ -{% set current_path = 'eager/supplements/set-val.jinja' %}\ -{% set __temp_import_alias_902286926__ = {} %}\ +{% set __temp_meta_current_path_724462665__,current_path = current_path,'eager/supplements/set-val.jinja' %}\ +{% set __temp_meta_import_alias_902286926__ = {} %}\ {% for __ignored__ in [0] %}\ {% set primary_line_height = 42 %}\ -{% do __temp_import_alias_902286926__.update({'primary_line_height': primary_line_height}) %}\ -{% do __temp_import_alias_902286926__.update({'primary_line_height': 42,'import_resource_path': 'eager/supplements/set-val.jinja'}) %}\ +{% do __temp_meta_import_alias_902286926__.update({'primary_line_height': primary_line_height}) %}\ +{% do __temp_meta_import_alias_902286926__.update({'primary_line_height': 42,'import_resource_path': 'eager/supplements/set-val.jinja'}) %}\ {% endfor %}\ -{% set simple = __temp_import_alias_902286926__ %}\ -{% set current_path = 'eager/handles-import-in-deferred-if/test.jinja' %}\ +{% set simple = __temp_meta_import_alias_902286926__ %}\ +{% set current_path,__temp_meta_current_path_724462665__ = __temp_meta_current_path_724462665__,null %}\ {% enddo %} {% else %} {% do %}\ -{% set current_path = 'eager/supplements/set-val.jinja' %}\ +{% set __temp_meta_current_path_724462665__,current_path = current_path,'eager/supplements/set-val.jinja' %}\ {% set primary_line_height = 42 %}\ -{% set current_path = 'eager/handles-import-in-deferred-if/test.jinja' %}\ +{% set current_path,__temp_meta_current_path_724462665__ = __temp_meta_current_path_724462665__,null %}\ {% enddo %} {% endif %} simple.primary_line_height (deferred): {{ simple.primary_line_height }} diff --git a/src/test/resources/eager/handles-same-name-import-var/test.expected.jinja b/src/test/resources/eager/handles-same-name-import-var/test.expected.jinja index 7db97c471..66cfa99f0 100644 --- a/src/test/resources/eager/handles-same-name-import-var/test.expected.jinja +++ b/src/test/resources/eager/handles-same-name-import-var/test.expected.jinja @@ -1,39 +1,39 @@ {% if deferred %} {% do %}\ -{% set current_path = 'eager/handles-same-name-import-var/set-var-and-deferred.jinja' %}\ -{% set __temp_import_alias_1059697132__ = {} %}\ +{% set __temp_meta_current_path_944750549__,current_path = current_path,'eager/handles-same-name-import-var/set-var-and-deferred.jinja' %}\ +{% set __temp_meta_import_alias_1059697132__ = {} %}\ {% for __ignored__ in [0] %}\ {% if deferred %} {% do %}\ {% set path = '' %}\ -{% do __temp_import_alias_1059697132__.update({'path': path}) %}\ +{% do __temp_meta_import_alias_1059697132__.update({'path': path}) %}\ {% set my_var = {'my_var': {'foo': 'bar'} } %}\ -{% do __temp_import_alias_1059697132__.update({'my_var': my_var}) %}\ +{% do __temp_meta_import_alias_1059697132__.update({'my_var': my_var}) %}\ {% set path = 'eager/handles-same-name-import-var/set-var-and-deferred.jinja' %}\ -{% do __temp_import_alias_1059697132__.update({'path': path}) %}\ +{% do __temp_meta_import_alias_1059697132__.update({'path': path}) %}\ {% set value = null %}\ -{% do __temp_import_alias_1059697132__.update({'value': value}) %}\ +{% do __temp_meta_import_alias_1059697132__.update({'value': value}) %}\ {% set my_var = {} %}\ -{% do __temp_import_alias_1059697132__.update({'my_var': my_var}) %}\ +{% do __temp_meta_import_alias_1059697132__.update({'my_var': my_var}) %}\ {% set my_var = {'foo': 'bar'} %}\ -{% do __temp_import_alias_1059697132__.update({'my_var': my_var}) %}\ +{% do __temp_meta_import_alias_1059697132__.update({'my_var': my_var}) %}\ {% set my_var = {'my_var': {'foo': 'bar'} } %}\ -{% do __temp_import_alias_1059697132__.update({'my_var': my_var}) %} +{% do __temp_meta_import_alias_1059697132__.update({'my_var': my_var}) %} {% set value = deferred %}\ -{% do __temp_import_alias_1059697132__.update({'value': value}) %}\ +{% do __temp_meta_import_alias_1059697132__.update({'value': value}) %}\ {% set my_var = {'my_var': {'foo': 'bar'} } %}\ -{% do __temp_import_alias_1059697132__.update({'my_var': my_var}) %}\ +{% do __temp_meta_import_alias_1059697132__.update({'my_var': my_var}) %}\ {% do my_var.update({'value': value}) %} {% do my_var.update({'import_resource_path': 'eager/handles-same-name-import-var/set-var-and-deferred.jinja', 'value': value}) %}\ {% set path = '' %}\ -{% do __temp_import_alias_1059697132__.update({'path': path}) %}\ +{% do __temp_meta_import_alias_1059697132__.update({'path': path}) %}\ {% enddo %} {{ my_var }} {% endif %} -{% do __temp_import_alias_1059697132__.update({'path': path,'import_resource_path': 'eager/handles-same-name-import-var/set-var-and-deferred.jinja','value': value}) %}\ +{% do __temp_meta_import_alias_1059697132__.update({'path': path,'import_resource_path': 'eager/handles-same-name-import-var/set-var-and-deferred.jinja','value': value}) %}\ {% endfor %}\ -{% set my_var = __temp_import_alias_1059697132__ %}\ -{% set current_path = 'eager/handles-same-name-import-var/test.jinja' %}\ +{% set my_var = __temp_meta_import_alias_1059697132__ %}\ +{% set current_path,__temp_meta_current_path_944750549__ = __temp_meta_current_path_944750549__,null %}\ {% enddo %} {{ filter:dictsort.filter(my_var, ____int3rpr3t3r____, false, 'key') }} {% endif %} diff --git a/src/test/resources/eager/reconstructs-block-path-when-deferred-nested/test.expected.jinja b/src/test/resources/eager/reconstructs-block-path-when-deferred-nested/test.expected.jinja index b4dfa0702..5f57b6eac 100644 --- a/src/test/resources/eager/reconstructs-block-path-when-deferred-nested/test.expected.jinja +++ b/src/test/resources/eager/reconstructs-block-path-when-deferred-nested/test.expected.jinja @@ -3,20 +3,18 @@ Parent's current path is: {{ '{{' + prefix + '_path }}\ ' }} -----Pre-First----- -{% set temp_current_path_995476186 = current_path %}\ -{% set current_path = 'eager/reconstructs-block-path-when-deferred-nested/test.jinja' %}\ +{% set __temp_meta_current_path_389897147__,current_path = current_path,'eager/reconstructs-block-path-when-deferred-nested/test.jinja' %}\ {% set prefix = deferred ? 'current' : 'current' %}\ Child's first current path is: {{ '{{' + prefix + '_path }}\ ' }} -{% set current_path = temp_current_path_995476186 %} +{% set current_path,__temp_meta_current_path_389897147__ = __temp_meta_current_path_389897147__,null %} -----Post-First----- -----Pre-Second----- -{% set temp_current_path_751498149 = current_path %}\ -{% set current_path = 'eager/reconstructs-block-path-when-deferred-nested/middle.jinja' %}\ +{% set __temp_meta_current_path_198396781__,current_path = current_path,'eager/reconstructs-block-path-when-deferred-nested/middle.jinja' %}\ {% set prefix = deferred ? 'current' : 'current' %}\ Middle's second current path is: {{ '{{' + prefix + '_path }}\ ' }} -{% set current_path = temp_current_path_751498149 %} +{% set current_path,__temp_meta_current_path_198396781__ = __temp_meta_current_path_198396781__,null %} -----Post-Second----- Parent's current path is: {{ '{{' + prefix + '_path }}\ ' }} \ No newline at end of file diff --git a/src/test/resources/eager/reconstructs-block-path-when-deferred/test.expected.jinja b/src/test/resources/eager/reconstructs-block-path-when-deferred/test.expected.jinja index 6d7c5946f..43c302b3b 100644 --- a/src/test/resources/eager/reconstructs-block-path-when-deferred/test.expected.jinja +++ b/src/test/resources/eager/reconstructs-block-path-when-deferred/test.expected.jinja @@ -3,12 +3,11 @@ Parent's current path is: {{ '{{' + prefix + '_path }}\ ' }} -----Pre-Block----- -{% set temp_current_path_802878910 = current_path %}\ -{% set current_path = 'eager/reconstructs-block-path-when-deferred/test.jinja' %}\ +{% set __temp_meta_current_path_329664044__,current_path = current_path,'eager/reconstructs-block-path-when-deferred/test.jinja' %}\ {% set prefix = deferred ? 'current' : 'current' %}\ Block's current path is: {{ '{{' + prefix + '_path }}\ ' }} -{% set current_path = temp_current_path_802878910 %} +{% set current_path,__temp_meta_current_path_329664044__ = __temp_meta_current_path_329664044__,null %} -----Post-Block----- Parent's current path is: {{ '{{' + prefix + '_path }}\ ' }} diff --git a/src/test/resources/eager/reconstructs-value-used-in-deferred-imported-macro/test.expected.jinja b/src/test/resources/eager/reconstructs-value-used-in-deferred-imported-macro/test.expected.jinja index 81bb1b50f..e83a98c98 100644 --- a/src/test/resources/eager/reconstructs-value-used-in-deferred-imported-macro/test.expected.jinja +++ b/src/test/resources/eager/reconstructs-value-used-in-deferred-imported-macro/test.expected.jinja @@ -1,14 +1,14 @@ {% do %}\ -{% set current_path = 'eager/reconstructs-value-used-in-deferred-imported-macro/uses-deferred-value-in-macro.jinja' %}\ -{% set __temp_import_alias_1081745881__ = {} %}\ +{% set __temp_meta_current_path_528180375__,current_path = current_path,'eager/reconstructs-value-used-in-deferred-imported-macro/uses-deferred-value-in-macro.jinja' %}\ +{% set __temp_meta_import_alias_1081745881__ = {} %}\ {% for __ignored__ in [0] %}\ {% set value = deferred %}\ -{% do __temp_import_alias_1081745881__.update({'value': value}) %} +{% do __temp_meta_import_alias_1081745881__.update({'value': value}) %} -{% do __temp_import_alias_1081745881__.update({'import_resource_path': 'eager/reconstructs-value-used-in-deferred-imported-macro/uses-deferred-value-in-macro.jinja','value': value}) %}\ +{% do __temp_meta_import_alias_1081745881__.update({'import_resource_path': 'eager/reconstructs-value-used-in-deferred-imported-macro/uses-deferred-value-in-macro.jinja','value': value}) %}\ {% endfor %}\ -{% set macros = __temp_import_alias_1081745881__ %}\ -{% set current_path = 'eager/reconstructs-value-used-in-deferred-imported-macro/test.jinja' %}\ +{% set macros = __temp_meta_import_alias_1081745881__ %}\ +{% set current_path,__temp_meta_current_path_528180375__ = __temp_meta_current_path_528180375__,null %}\ {% enddo %} {% set deferred_import_resource_path = 'eager/reconstructs-value-used-in-deferred-imported-macro/uses-deferred-value-in-macro.jinja' %}\ diff --git a/src/test/resources/eager/uses-unique-macro-names/test.expected.jinja b/src/test/resources/eager/uses-unique-macro-names/test.expected.jinja index 2d3e064a5..54c40b809 100644 --- a/src/test/resources/eager/uses-unique-macro-names/test.expected.jinja +++ b/src/test/resources/eager/uses-unique-macro-names/test.expected.jinja @@ -5,12 +5,12 @@ Goodbye {{ myname }} {% endset %}\ {% set a = filter:upper.filter(__macro_foo_97643642_temp_variable_0__, ____int3rpr3t3r____) %} {% do %}\ -{% set current_path = 'eager/uses-unique-macro-names/macro-with-filter.jinja' %} +{% set __temp_meta_current_path_203114534__,current_path = current_path,'eager/uses-unique-macro-names/macro-with-filter.jinja' %} {% set __macro_foo_1717337666_temp_variable_0__ %}\ Hello {{ myname }}\ {% endset %}\ {% set b = filter:upper.filter(__macro_foo_1717337666_temp_variable_0__, ____int3rpr3t3r____) %} -{% set current_path = 'eager/uses-unique-macro-names/test.jinja' %}\ +{% set current_path,__temp_meta_current_path_203114534__ = __temp_meta_current_path_203114534__,null %}\ {% enddo %} {{ a }} -{{ b }} +{{ b }} \ No newline at end of file diff --git a/src/test/resources/eager/wraps-macro-that-would-change-current-path-in-child-scope/dir1/macro.jinja b/src/test/resources/eager/wraps-macro-that-would-change-current-path-in-child-scope/dir1/macro.jinja new file mode 100644 index 000000000..45fb53d08 --- /dev/null +++ b/src/test/resources/eager/wraps-macro-that-would-change-current-path-in-child-scope/dir1/macro.jinja @@ -0,0 +1,4 @@ +{% macro foo_importer() -%} + {%- include "../dir2/included.jinja" -%} + {%- print foo -%} +{%- endmacro %} \ No newline at end of file diff --git a/src/test/resources/eager/wraps-macro-that-would-change-current-path-in-child-scope/dir2/included.jinja b/src/test/resources/eager/wraps-macro-that-would-change-current-path-in-child-scope/dir2/included.jinja new file mode 100644 index 000000000..bde4ef606 --- /dev/null +++ b/src/test/resources/eager/wraps-macro-that-would-change-current-path-in-child-scope/dir2/included.jinja @@ -0,0 +1,2 @@ +{% set foo = deferred %} +{{ foo }} \ No newline at end of file diff --git a/src/test/resources/eager/wraps-macro-that-would-change-current-path-in-child-scope/test.expected.jinja b/src/test/resources/eager/wraps-macro-that-would-change-current-path-in-child-scope/test.expected.jinja new file mode 100644 index 000000000..1627e6490 --- /dev/null +++ b/src/test/resources/eager/wraps-macro-that-would-change-current-path-in-child-scope/test.expected.jinja @@ -0,0 +1,10 @@ +Starting current_path: eager/wraps-macro-that-would-change-current-path-in-child-scope/test.jinja +Intermediate current_path: eager/wraps-macro-that-would-change-current-path-in-child-scope/test.jinja +{% for __ignored__ in [0] %}\ +{% set __temp_meta_current_path_629250870__,current_path = 'eager/wraps-macro-that-would-change-current-path-in-child-scope/test.jinja', 'eager/wraps-macro-that-would-change-current-path-in-child-scope/dir2/included.jinja' %}\ +{% set foo = deferred %} +{{ foo }}\ +{% set current_path,__temp_meta_current_path_629250870__ = 'eager/wraps-macro-that-would-change-current-path-in-child-scope/test.jinja', null %}\ +{% print foo %}\ +{% endfor %} +Ending current_path: eager/wraps-macro-that-would-change-current-path-in-child-scope/test.jinja diff --git a/src/test/resources/eager/wraps-macro-that-would-change-current-path-in-child-scope/test.jinja b/src/test/resources/eager/wraps-macro-that-would-change-current-path-in-child-scope/test.jinja new file mode 100644 index 000000000..e1f64358a --- /dev/null +++ b/src/test/resources/eager/wraps-macro-that-would-change-current-path-in-child-scope/test.jinja @@ -0,0 +1,5 @@ +Starting current_path: {{ current_path }} +{% from "./dir1/macro.jinja" import foo_importer -%} +Intermediate current_path: {{ current_path }} +{{ foo_importer() }} +Ending current_path: {{ current_path }} diff --git a/src/test/resources/tags/eager/extendstag/defers-block-in-extends-child.expected.jinja b/src/test/resources/tags/eager/extendstag/defers-block-in-extends-child.expected.jinja index 3f49c19e6..1e804dbee 100644 --- a/src/test/resources/tags/eager/extendstag/defers-block-in-extends-child.expected.jinja +++ b/src/test/resources/tags/eager/extendstag/defers-block-in-extends-child.expected.jinja @@ -2,12 +2,10 @@ - diff --git a/src/test/resources/tags/eager/extendstag/defers-super-block-with-deferred.expected.jinja b/src/test/resources/tags/eager/extendstag/defers-super-block-with-deferred.expected.jinja index 6da141a82..41b046b1c 100644 --- a/src/test/resources/tags/eager/extendstag/defers-super-block-with-deferred.expected.jinja +++ b/src/test/resources/tags/eager/extendstag/defers-super-block-with-deferred.expected.jinja @@ -2,13 +2,12 @@ diff --git a/src/test/resources/tags/eager/extendstag/reconstructs-deferred-outside-block.expected.jinja b/src/test/resources/tags/eager/extendstag/reconstructs-deferred-outside-block.expected.jinja index 3b14097e4..b01cdf9bf 100644 --- a/src/test/resources/tags/eager/extendstag/reconstructs-deferred-outside-block.expected.jinja +++ b/src/test/resources/tags/eager/extendstag/reconstructs-deferred-outside-block.expected.jinja @@ -9,11 +9,10 @@ diff --git a/src/test/resources/tags/eager/includetag/includes-deferred.expected.jinja b/src/test/resources/tags/eager/includetag/includes-deferred.expected.jinja index 8d0a8632d..606c5930b 100644 --- a/src/test/resources/tags/eager/includetag/includes-deferred.expected.jinja +++ b/src/test/resources/tags/eager/includetag/includes-deferred.expected.jinja @@ -1,7 +1,7 @@ Foo begins as: abc -{% set current_path = 'sets-to-deferred.jinja' %}\ +{% set __temp_meta_current_path_38651297__,current_path = current_path,'sets-to-deferred.jinja' %}\ {% set foo = deferred %} foo is now {{ deferred }}\ . -{% set current_path = '' %} +{% set current_path,__temp_meta_current_path_38651297__ = __temp_meta_current_path_38651297__,null %} Foo ends as: {{ foo }}