/// <summary> /// Pushes the source file path being executed. This should have enough information so that template loading/include can work correctly. /// </summary> /// <param name="sourceFile">The source file.</param> public void PushSourceFile(string sourceFile) { if (sourceFile == null) { throw new ArgumentNullException(nameof(sourceFile)); } _sourceFiles.Push(sourceFile); }
internal void PushPipeArguments() { ScriptPipeArguments pipeArguments = _availablePipeArguments.Count > 0 ? _availablePipeArguments.Pop() : new ScriptPipeArguments(4); _pipeArguments.Push(pipeArguments); _currentPipeArguments = pipeArguments; }
/// <summary> /// Pushes a new object context accessible to the template. /// </summary> /// <param name="scriptObject">The script object.</param> /// <exception cref="ArgumentNullException"></exception> public void PushGlobal(IScriptObject scriptObject) { if (scriptObject == null) { new ArgumentNullException(nameof(scriptObject)); } _globalStores.Push(scriptObject); PushVariableScope(ScriptVariableScope.Local); }
/// <summary> /// Push a new <see cref="CultureInfo"/> to be used when rendering/parsing numbers. /// </summary> /// <param name="culture">The new culture to use when rendering/parsing numbers</param> public void PushCulture(CultureInfo culture) { if (culture == null) { throw new ArgumentNullException(nameof(culture)); } // Create a stack for cultures if they are actually used _cultures.Push(culture); }
/// <summary> /// Notifies this context when entering a loop. /// </summary> /// <param name="loop"></param> internal void EnterLoop(ScriptLoopStatementBase loop) { if (loop == null) { throw new ArgumentNullException(nameof(loop)); } _loops.Push(loop); _loopStep = 0; PushVariableScope(ScriptVariableScope.Loop); OnEnterLoop(loop); }
/// <summary> /// Initializes a new instance of the <see cref="TemplateContext" /> class. /// </summary> /// <param name="builtin">The builtin object used to expose builtin functions, default is <see cref="GetDefaultBuiltinObject"/>.</param> public TemplateContext(ScriptObject builtin) { BuiltinObject = builtin ?? GetDefaultBuiltinObject(); EnableOutput = true; EnableBreakAndContinueAsReturnOutsideLoop = false; LoopLimit = 1000; RecursiveLimit = 100; MemberRenamer = StandardMemberRenamer.Default; RegexTimeOut = TimeSpan.FromSeconds(10); TemplateLoaderParserOptions = new ParserOptions(); TemplateLoaderLexerOptions = LexerOptions.Default; _outputs = new FastStack <IScriptOutput>(4); _output = new StringBuilderOutput(); _outputs.Push(_output); _globalStores = new FastStack <IScriptObject>(4); _localStores = new FastStack <ScriptObject>(4); _loopStores = new FastStack <ScriptObject>(4); _availableStores = new FastStack <ScriptObject>(4); _cultures = new FastStack <CultureInfo>(4); _caseValues = new FastStack <object>(4); _localTagsStack = new FastStack <Dictionary <object, object> >(1); _loopTagsStack = new FastStack <Dictionary <object, object> >(1); _availableTags = new FastStack <Dictionary <object, object> >(4); _sourceFiles = new FastStack <string>(4); _memberAccessors = new Dictionary <Type, IObjectAccessor>(); _listAccessors = new Dictionary <Type, IListAccessor>(); _loops = new FastStack <ScriptLoopStatementBase>(4); BlockDelegates = new FastStack <ScriptBlockStatement>(4); _availablePipeArguments = new FastStack <ScriptPipeArguments>(4); _pipeArguments = new FastStack <ScriptPipeArguments>(4); _isFunctionCallDisabled = false; CachedTemplates = new Dictionary <string, Template>(); Tags = new Dictionary <object, object>(); PushPipeArguments(); // Ensure that builtin is registered first PushGlobal(BuiltinObject); }
internal void PopPipeArguments() { if (_pipeArguments.Count == 1) { throw new InvalidOperationException(RS.PopPipeArgOverflow); } ScriptPipeArguments pipeArguments = _pipeArguments.Pop(); // Might be not null in case of an exception pipeArguments.Clear(); _availablePipeArguments.Push(pipeArguments); _currentPipeArguments = _pipeArguments.Peek(); }
/// <summary> /// Pops a previous <see cref="ScriptVariableScope"/>. /// </summary> internal void PopVariableScope(ref FastStack <ScriptObject> stores) { if (stores.Count == 0) { // Should not happen at runtime throw new InvalidOperationException(RS.PopVariableScopeOverflow); } ScriptObject store = stores.Pop(); // The store is cleanup once it is pushed back store.Clear(); _availableStores.Push(store); }
/// <summary> /// Push a new <see cref="ScriptVariableScope"/> for variables /// </summary> /// <param name="scope"></param> internal void PushVariableScope(ScriptVariableScope scope) { ScriptObject store = _availableStores.Count > 0 ? _availableStores.Pop() : new ScriptObject(); Dictionary <object, object> tags = _availableTags.Count > 0 ? _availableTags.Pop() : new Dictionary <object, object>(); if (scope == ScriptVariableScope.Local) { _localStores.Push(store); _localTagsStack.Push(tags); } else { _loopStores.Push(store); _loopTagsStack.Push(tags); } }
/// <summary> /// Pops a previous <see cref="ScriptVariableScope"/>. /// </summary> /// <param name="scope"></param> internal void PopVariableScope(ScriptVariableScope scope) { Dictionary <object, object> tags; if (scope == ScriptVariableScope.Local) { PopVariableScope(ref _localStores); tags = _localTagsStack.Pop(); } else { PopVariableScope(ref _loopStores); tags = _loopTagsStack.Pop(); } // Make sure that tags are clear tags.Clear(); _availableTags.Push(tags); }
internal void PushCase(object caseValue) { _caseValues.Push(caseValue); }
/// <summary> /// Pushes a new output used for rendering the current template while keeping the previous output. /// </summary> public void PushOutput(IScriptOutput output) { _output = output ?? throw new ArgumentNullException(nameof(output)); _outputs.Push(_output); }