Releases: vapor/leaf-kit
Improved #export/#import Behavior
This update provides significantly improved resolution of #export/#import.
API Changes
The unbodied usage of #export("exportkey", value)
now supports any acceptable single parameter as the exported value. Example uses:
// Exports context variable
#export("isAdmin", admin)
// Exports an expression
#export("specialKey", username == "tdotclare")
// Exports a custom tag call
#export("baseURL", baseURL())
#import
can now be used inside parameters, allowing behavior like:
#if(import("showSidebar")): <div id="sidebar"><div> #endif
Observable Behavior Changes/Fixes
- Fixes Issue #57 -
#import
syntaxes are now correctly replaced when nested inside other objects like loops
Internal Changes
Syntax.Conditional
is now a chained-block struct instead of linked classes- Adds
BodiedSyntax
protocol to applicableSyntax
es, replacing monolithic extensions- Publish & maintain external or import dependency sets for adherants
- Provide
inlineRefs
methods to adherents to self-rebuild
- Smarter
LeafAST
resolution - Provides applicable
import
capabilities to ParameterDescription and Parameter
General File Cleanup
This patch was authored and released by @tdotclare.
General housekeeping
- Top level files are primary public interfaces to LeafKit -
LeafRenderer
LeafAST
LeafError
- Files for internal objects/methods now grouped by general pipeline stage of rendering:
LeafSource/*
for protocol/implementation of sources of raw templates (LeafFiles
,NIOLeafFiles
)LeafLexer/*
forLeafLexer
and raw template and token structsLeafSyntax/*
for syntax and tag objects generated during Lex->ParseLeafParser/*
forLeafParser
& other related filesLeafSerialize/*
forLeafSerializer
,LeafContext
,LeafData
objectsLeafCache/*
for protocol/implementation of LeafAST caching (LeafCache
,DefaultLeafCache
This release also includes various cleanups of whitespace, code formatting for readability, and improved documentation in places.
Deep Extension Resolution
This patch was authored and released by @tdotclare.
DEEP RESOLVE
- Significantly improved LeafAST resolution
- Syntax items now recursively rebuild themselves to allow deeply-nested #extend tags to properly resolve
- Simplify LeafAST resolution steps, correct tail recursion
- Adds appropriate test cases
This is an ugly but nonetheless functional update to the referenced template resolution; ASTs will now recursively examine ALL Syntax objects during loading and resolution to inline templates no matter how deeply buried.
I used tons of inouts on associated value Enums, don't @ me. This is not ideal in terms of code beauty but it does what it purports to.
Resolves #50
Robustify - Improved/Extended Lexing Behavior & Error Handling
This patch was authored and released by @tdotclare.
Major Changes
- Converts
LeafError
from Enum to source-reporting Struct - Adjusts
Lexer
state change table for human clarity - Adds
Lexer
robustness for parameters with no whitespace boundaries - Adds
Lexer
parameter handling for bin/oct/hex constantInt
s and hexDouble
s - Adds
Lexer
internal methods for additional checking peek/pop sequences - Makes
Parameter
depth a state variable inLexer
instead of an enum property - Adjusts
Character
exts for additional granularity on token types - Adjusts
Character
exts for start/body validity of token types - Adds
Character
exts for bin/oct/hex numerics - Adjusts
Parser
behavior to allow decayingtagBodyIndicators
toraw
when tag is known to have no body - Adjusts
Parser
to allow replacingLexed
tokens when necessary for above - Re-enables a number of
TestCase
functions from Leaf3 and adjusts for Leaf4 syntax
Problems Solved
Better/clearer error handling properties
Much easier to follow state changes during lexing In most cases
Parameter
processing is still complicated but other cases are clearly handled
Better Parameter
handling with whitespace
EG, the varying inputs below all properly lex to the correct interpretation now. Before, the first three would inaccurately lex, and only the fourth would correctly lex the parameters to
operator(not) variable(one) operator(||) operator(not) variable(two)
"#if(!one||!two)"
"#if(!one || !two)"
"#if(! one||! two)"
"#if(! one || ! two)"
Better handling of tagBodyIndicator
Previously syntax like #(index):#(value)
would error because the colon was universally assumed to indicate the start of a body - now, cases where it's impossible for a tag to take a body (eg, anonymous functions for now) will mutate the tBI back to a raw colon. Next step to improving this is to make observers on tag and built-in control structures to allow parsing to inquire as to expected state (eg, a function may take two parameters and no body or one parameter and a body and both are acceptable)
Improved syntax options for constant numerics
You can specify bin/oct/hex Int
and hex Double
constants now in Swift-manner literals... eg
0b1111 // Constant Int
1_000_000 // Constant Int
0x0.50 // Constant Double
Why? Why not?
LeafRenderer.resolve Recursive Resolution of LeafAST
This patch was authored and released by @tdotclare.
In cases where extend
introduces new external references (eg, via import/export as in Issue #33 ), recursively resolve the AST until no new dependencies exist.
LeafAST - Substantial Refactoring of LeafKit processing chain
API & Performance Changes
- Replaces
Unresolved/ResolvedDocument
withLeafAST
, a document structure capable of representing both unknown state and resolved state AST with public observers on its state. - Adjusts
LeafRenderer
andLeafCache
to use LeafAST- Note:
LeafCache
protocol retainsResolvedDocument
as an alias toLeafAST
to prevent breaking changes in this release
- Note:
- Adds
.insert
method toLeafCache
protocol with areplace
parameter to clarify whether inserting an AST is allowed to replace the current cached AST if such a key already exists - Adds
.remove
method toLeafCache
protocol to allow removing individual ASTs from the cache - Improves routine case rendering speed on flat ASTs
- Collapses sequential
.raw
Syntax
es during AST resolution for faster serialization - Initial introduction of
LeafError
type for enhanced error handling- Note: - not stable, to be changed from
Enum
toStruct
in next PR for codifying the type and allowing source document referencing
- Note: - not stable, to be changed from
- Changes DefaultLeafCache behavior to return provided AST or nil if caching is off
Bug Fixes
- Prevents crash on malformed external Leaf documents that cause cyclical loops (eg,
a.leaf
extendsb.leaf
andb.leaf
extendsa.leaf
) - Re-introduces
index
,isFirst
,isLast
variables insideloop
bodies from Leaf 3- Note: - collision is possible between variable names if a key in the
LeafData
provided to a template shares the same name as the variables
- Note: - collision is possible between variable names if a key in the
Testing Changes
- Add test cases for measuring speed of linear & randomly accessed templates
- Add tests cases for cyclical error handling and missing templates
- Make
TestFiles
threadsafe - Deactivate
testTagIndicator
for causing data race when actual MultiThreaded Event Loops are running in tests
Add Underscore as Valid in Parameter
This patch was authored by @jagreenwood and released by @tanner0101.
Adds underscore
to Character
extension, then ORs .underscore
in isValidInParameter
(#41, fixes #39).
Add requirement methods to LeafContext
This patch was authored by @tonyarnold and released by @tanner0101.
Adds methods to LeafContext
to verify the existence, or non-existence of a context body, as well as to verify the context contains a specific number of parameters.
User info, tag config, and files protocol
This patch was authored and released by @tanner0101.
-
Adds
userInfo
toLeafRenderer
andLeafContext
for passing user-defined data. -
Adds
tags
property toLeafRenderer
anddefaultTags
global for configuring custom tags. -
Adds
LeafFiles
protocol for customizing how Leaf fetches files. -
Publicizes properties on
LeafContext
as well as simplifying parameter access.
Fix #if Conditional Logix
Fixes #if
to support checking a value's truthiness like Leaf 3 did (#28, fixes #31).
- Fix null handling for conditionals
- Fix boolean reduction for future parameter lists with > 1 boolean values
- Restored and updated leaf3 "testStringIf" test
- Added tests for conditional and/or
This patch was authored by @b-straub and released by @tanner0101.