Skip to content

Commit

Permalink
Release 28.11.0
Browse files Browse the repository at this point in the history
  • Loading branch information
booster committed Nov 17, 2023
1 parent 210aef7 commit 4a4f48a
Show file tree
Hide file tree
Showing 50 changed files with 434 additions and 239 deletions.
6 changes: 6 additions & 0 deletions .mapping.json
Original file line number Diff line number Diff line change
Expand Up @@ -691,6 +691,7 @@
"LayoutKit/LayoutKit/ViewModels/GalleryViewModel.swift":"divkit/public-ios/LayoutKit/LayoutKit/ViewModels/GalleryViewModel.swift",
"LayoutKit/LayoutKit/ViewModels/GalleryViewModelDelegate.swift":"divkit/public-ios/LayoutKit/LayoutKit/ViewModels/GalleryViewModelDelegate.swift",
"LayoutKit/LayoutKit/ViewModels/GalleryViewState.swift":"divkit/public-ios/LayoutKit/LayoutKit/ViewModels/GalleryViewState.swift",
"LayoutKit/LayoutKit/ViewModels/InfiniteScroll.swift":"divkit/public-ios/LayoutKit/LayoutKit/ViewModels/InfiniteScroll.swift",
"LayoutKit/LayoutKit/ViewModels/InsetMode.swift":"divkit/public-ios/LayoutKit/LayoutKit/ViewModels/InsetMode.swift",
"LayoutKit/LayoutKit/ViewModels/NinePatchImage.swift":"divkit/public-ios/LayoutKit/LayoutKit/ViewModels/NinePatchImage.swift",
"LayoutKit/LayoutKit/ViewModels/PagerViewLayout.swift":"divkit/public-ios/LayoutKit/LayoutKit/ViewModels/PagerViewLayout.swift",
Expand Down Expand Up @@ -815,6 +816,7 @@
"Specs/DivKit/28.0.1/DivKit.podspec":"divkit/public-ios/Specs/DivKit/28.0.1/DivKit.podspec",
"Specs/DivKit/28.1.0/DivKit.podspec":"divkit/public-ios/Specs/DivKit/28.1.0/DivKit.podspec",
"Specs/DivKit/28.10.0/DivKit.podspec":"divkit/public-ios/Specs/DivKit/28.10.0/DivKit.podspec",
"Specs/DivKit/28.11.0/DivKit.podspec":"divkit/public-ios/Specs/DivKit/28.11.0/DivKit.podspec",
"Specs/DivKit/28.2.0/DivKit.podspec":"divkit/public-ios/Specs/DivKit/28.2.0/DivKit.podspec",
"Specs/DivKit/28.3.0/DivKit.podspec":"divkit/public-ios/Specs/DivKit/28.3.0/DivKit.podspec",
"Specs/DivKit/28.4.0/DivKit.podspec":"divkit/public-ios/Specs/DivKit/28.4.0/DivKit.podspec",
Expand Down Expand Up @@ -844,6 +846,7 @@
"Specs/DivKitExtensions/28.0.1/DivKitExtensions.podspec":"divkit/public-ios/Specs/DivKitExtensions/28.0.1/DivKitExtensions.podspec",
"Specs/DivKitExtensions/28.1.0/DivKitExtensions.podspec":"divkit/public-ios/Specs/DivKitExtensions/28.1.0/DivKitExtensions.podspec",
"Specs/DivKitExtensions/28.10.0/DivKitExtensions.podspec":"divkit/public-ios/Specs/DivKitExtensions/28.10.0/DivKitExtensions.podspec",
"Specs/DivKitExtensions/28.11.0/DivKitExtensions.podspec":"divkit/public-ios/Specs/DivKitExtensions/28.11.0/DivKitExtensions.podspec",
"Specs/DivKitExtensions/28.2.0/DivKitExtensions.podspec":"divkit/public-ios/Specs/DivKitExtensions/28.2.0/DivKitExtensions.podspec",
"Specs/DivKitExtensions/28.3.0/DivKitExtensions.podspec":"divkit/public-ios/Specs/DivKitExtensions/28.3.0/DivKitExtensions.podspec",
"Specs/DivKitExtensions/28.4.0/DivKitExtensions.podspec":"divkit/public-ios/Specs/DivKitExtensions/28.4.0/DivKitExtensions.podspec",
Expand All @@ -855,6 +858,7 @@
"Specs/DivKit_LayoutKit/28.0.1/DivKit_LayoutKit.podspec":"divkit/public-ios/Specs/DivKit_LayoutKit/28.0.1/DivKit_LayoutKit.podspec",
"Specs/DivKit_LayoutKit/28.1.0/DivKit_LayoutKit.podspec":"divkit/public-ios/Specs/DivKit_LayoutKit/28.1.0/DivKit_LayoutKit.podspec",
"Specs/DivKit_LayoutKit/28.10.0/DivKit_LayoutKit.podspec":"divkit/public-ios/Specs/DivKit_LayoutKit/28.10.0/DivKit_LayoutKit.podspec",
"Specs/DivKit_LayoutKit/28.11.0/DivKit_LayoutKit.podspec":"divkit/public-ios/Specs/DivKit_LayoutKit/28.11.0/DivKit_LayoutKit.podspec",
"Specs/DivKit_LayoutKit/28.2.0/DivKit_LayoutKit.podspec":"divkit/public-ios/Specs/DivKit_LayoutKit/28.2.0/DivKit_LayoutKit.podspec",
"Specs/DivKit_LayoutKit/28.3.0/DivKit_LayoutKit.podspec":"divkit/public-ios/Specs/DivKit_LayoutKit/28.3.0/DivKit_LayoutKit.podspec",
"Specs/DivKit_LayoutKit/28.4.0/DivKit_LayoutKit.podspec":"divkit/public-ios/Specs/DivKit_LayoutKit/28.4.0/DivKit_LayoutKit.podspec",
Expand All @@ -866,6 +870,7 @@
"Specs/DivKit_LayoutKitInterface/28.0.1/DivKit_LayoutKitInterface.podspec":"divkit/public-ios/Specs/DivKit_LayoutKitInterface/28.0.1/DivKit_LayoutKitInterface.podspec",
"Specs/DivKit_LayoutKitInterface/28.1.0/DivKit_LayoutKitInterface.podspec":"divkit/public-ios/Specs/DivKit_LayoutKitInterface/28.1.0/DivKit_LayoutKitInterface.podspec",
"Specs/DivKit_LayoutKitInterface/28.10.0/DivKit_LayoutKitInterface.podspec":"divkit/public-ios/Specs/DivKit_LayoutKitInterface/28.10.0/DivKit_LayoutKitInterface.podspec",
"Specs/DivKit_LayoutKitInterface/28.11.0/DivKit_LayoutKitInterface.podspec":"divkit/public-ios/Specs/DivKit_LayoutKitInterface/28.11.0/DivKit_LayoutKitInterface.podspec",
"Specs/DivKit_LayoutKitInterface/28.2.0/DivKit_LayoutKitInterface.podspec":"divkit/public-ios/Specs/DivKit_LayoutKitInterface/28.2.0/DivKit_LayoutKitInterface.podspec",
"Specs/DivKit_LayoutKitInterface/28.3.0/DivKit_LayoutKitInterface.podspec":"divkit/public-ios/Specs/DivKit_LayoutKitInterface/28.3.0/DivKit_LayoutKitInterface.podspec",
"Specs/DivKit_LayoutKitInterface/28.4.0/DivKit_LayoutKitInterface.podspec":"divkit/public-ios/Specs/DivKit_LayoutKitInterface/28.4.0/DivKit_LayoutKitInterface.podspec",
Expand All @@ -877,6 +882,7 @@
"Specs/DivKit_Serialization/28.0.1/DivKit_Serialization.podspec":"divkit/public-ios/Specs/DivKit_Serialization/28.0.1/DivKit_Serialization.podspec",
"Specs/DivKit_Serialization/28.1.0/DivKit_Serialization.podspec":"divkit/public-ios/Specs/DivKit_Serialization/28.1.0/DivKit_Serialization.podspec",
"Specs/DivKit_Serialization/28.10.0/DivKit_Serialization.podspec":"divkit/public-ios/Specs/DivKit_Serialization/28.10.0/DivKit_Serialization.podspec",
"Specs/DivKit_Serialization/28.11.0/DivKit_Serialization.podspec":"divkit/public-ios/Specs/DivKit_Serialization/28.11.0/DivKit_Serialization.podspec",
"Specs/DivKit_Serialization/28.2.0/DivKit_Serialization.podspec":"divkit/public-ios/Specs/DivKit_Serialization/28.2.0/DivKit_Serialization.podspec",
"Specs/DivKit_Serialization/28.3.0/DivKit_Serialization.podspec":"divkit/public-ios/Specs/DivKit_Serialization/28.3.0/DivKit_Serialization.podspec",
"Specs/DivKit_Serialization/28.4.0/DivKit_Serialization.podspec":"divkit/public-ios/Specs/DivKit_Serialization/28.4.0/DivKit_Serialization.podspec",
Expand Down
9 changes: 1 addition & 8 deletions DivKit/Actions/ArrayInsertValueActionHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,10 @@ final class ArrayInsertValueActionHandler {
array.append(value)
}

let typedValue: DivTypedValue = .arrayValue(ArrayValue(value: array))
guard let variableArrayValue = typedValue
.asVariableValue(expressionResolver: expressionResolver)
else {
return
}

context.variablesStorage.update(
cardId: context.cardId,
name: DivVariableName(rawValue: variableName),
value: variableArrayValue
value: .array(array)
)
}
}
3 changes: 2 additions & 1 deletion DivKit/Actions/DivActionHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,8 @@ public final class DivActionHandler {

private func makeExpressionResolver(cardId: DivCardID) -> ExpressionResolver {
ExpressionResolver(
variables: variablesStorage.makeVariables(for: cardId),
cardId: cardId,
variablesStorage: variablesStorage,
persistentValuesStorage: persistentValuesStorage,
errorTracker: reporter.asExpressionErrorTracker(cardId: cardId)
)
Expand Down
3 changes: 2 additions & 1 deletion DivKit/DivBlockModelingContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,8 @@ private func makeExpressionResolver(
variableTracker: DivVariableTracker?
) -> ExpressionResolver {
ExpressionResolver(
variables: variablesStorage.makeVariables(for: cardId),
cardId: cardId,
variablesStorage: variablesStorage,
persistentValuesStorage: persistentValuesStorage,
errorTracker: { [weak errorsStorage] error in
errorsStorage?.add(DivExpressionError(error, path: parentPath))
Expand Down
2 changes: 1 addition & 1 deletion DivKit/DivKitInfo.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
public enum DivKitInfo {
public static let version = "28.10.0"
public static let version = "28.11.0"
}
63 changes: 14 additions & 49 deletions DivKit/Expressions/CalcExpression/AnyCalcExpression.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,14 @@ import Foundation

import CommonCorePublic

protocol ConstantsProvider {
func getValue(_ name: String) -> Any?
}

/// Wrapper for Expression that works with any type of value
struct AnyCalcExpression: CustomStringConvertible {
struct AnyCalcExpression {
private let expression: CalcExpression
private let describer: () -> String
@usableFromInline
let evaluator: () throws -> Any

typealias ValueProvider = (_ name: String) -> Any?

/// Evaluator for individual symbols
typealias SymbolEvaluator = (_ args: [Any]) throws -> Any

Expand All @@ -55,24 +52,19 @@ struct AnyCalcExpression: CustomStringConvertible {
/// Runtime error when parsing or evaluating an expression
typealias Error = CalcExpression.Error

/// Options for configuring an expression
typealias Options = CalcExpression.Options

/// Constructor that accepts parsed expression and constants lookup function
/// Used in Yandex DivKit Expressions
init(
_ expression: ParsedCalcExpression,
options: Options = [.boolSymbols],
constants: ConstantsProvider
variables: ValueProvider
) throws {
try self.init(
expression,
options: options,
impureSymbols: { _ in nil },
pureSymbols: { symbol in
switch symbol {
case let .variable(name):
return constants.getValue(name).map { value in { _ in value } }
return variables(name).map { value in { _ in value } }
default:
return nil
}
Expand All @@ -84,33 +76,26 @@ struct AnyCalcExpression: CustomStringConvertible {
/// constants lookup function and SymbolEvaluators
init(
_ expression: ParsedCalcExpression,
options: Options = [.boolSymbols],
constants: ConstantsProvider,
variables: ValueProvider,
symbols: [Symbol: SymbolEvaluator]
) throws {
// Options
let pureSymbols = options.contains(.pureSymbols)

try self.init(
expression,
options: options,
impureSymbols: { symbol in
switch symbol {
case let .variable(name):
if constants.getValue(name) == nil {
if variables(name) == nil {
return symbols[symbol]
}
default:
if !pureSymbols {
return symbols[symbol]
}
return symbols[symbol]
}
return nil
},
pureSymbols: { symbol in
switch symbol {
case let .variable(name):
return constants.getValue(name).map { value in { _ in value } }
return variables(name).map { value in { _ in value } }
default:
return symbols[symbol]
}
Expand All @@ -125,7 +110,6 @@ struct AnyCalcExpression: CustomStringConvertible {
/// function
private init(
_ expression: ParsedCalcExpression,
options: Options,
impureSymbols: (Symbol) -> SymbolEvaluator?,
pureSymbols: (Symbol) -> SymbolEvaluator?
) throws {
Expand Down Expand Up @@ -243,22 +227,13 @@ struct AnyCalcExpression: CustomStringConvertible {
}
}

// Set description based on the parsed expression, prior to
// performing optimizations. This avoids issues with inlined
// constants and string literals being converted to `nan`
describer = { expression.description }

// Options
let boolSymbols = options.contains(.boolSymbols) ? CalcExpression.boolSymbols : [:]
let shouldOptimize = !options.contains(.noOptimize)

// Evaluators
func defaultEvaluator(for symbol: Symbol) throws -> CalcExpression.SymbolEvaluator? {
if let fn = AnyCalcExpression.standardSymbols[symbol] {
return fn
} else if let fn = CalcExpression.mathSymbols[symbol] {
return fn
} else if let fn = boolSymbols[symbol] {
} else if let fn = CalcExpression.boolSymbols[symbol] {
switch symbol {
case .infix("=="):
return {
Expand Down Expand Up @@ -348,8 +323,8 @@ struct AnyCalcExpression: CustomStringConvertible {
if let fn = funcEvaluator(for: symbol, value) {
return try fn(args)
}
throw Error.typeMismatch(
.infix("()"), [value] + [try args.map(box.load)]
throw try Error.typeMismatch(
.infix("()"), [value] + [args.map(box.load)]
)
}
} else if let fn = pureSymbols(.variable(name)) {
Expand All @@ -362,9 +337,6 @@ struct AnyCalcExpression: CustomStringConvertible {
}
}
}
if !shouldOptimize {
return try (_pureSymbols[symbol] ?? defaultEvaluator(for: symbol))
}
return nil
},
pureSymbols: { symbol in
Expand All @@ -386,9 +358,9 @@ struct AnyCalcExpression: CustomStringConvertible {
if let fn = pureSymbols(.variable(name)) {
return { args in
let value = try fn([])
throw Error.typeMismatch(
throw try Error.typeMismatch(
.infix("()"),
[value] + [try args.map(box.load)]
[value] + [args.map(box.load)]
)
}
}
Expand Down Expand Up @@ -445,13 +417,6 @@ struct AnyCalcExpression: CustomStringConvertible {
}
return value
}

/// All symbols used in the expression
var symbols: Set<Symbol> { expression.symbols }

/// Returns the optmized, pretty-printed expression if it was valid
/// Otherwise, returns the original (invalid) expression string
var description: String { describer() }
}

// MARK: Internal API
Expand Down
51 changes: 1 addition & 50 deletions DivKit/Expressions/CalcExpression/CalcExpression.swift
Original file line number Diff line number Diff line change
Expand Up @@ -182,17 +182,12 @@ final class CalcExpression: CustomStringConvertible {

case escaping

/// Empty expression
static let emptyExpression = unexpectedToken("")

/// The human-readable description of the error
var description: String {
switch self {
case let .message(message),
let .shortMessage(message):
return message
case .emptyExpression:
return "Empty expression"
case let .unexpectedToken(string):
return "Error tokenizing '\(string)'."
case let .missingDelimiter(string):
Expand Down Expand Up @@ -236,28 +231,6 @@ final class CalcExpression: CustomStringConvertible {
}
}

/// Options for configuring an expression
struct Options: OptionSet {
/// Disable optimizations such as constant substitution
static let noOptimize = Options(rawValue: 1 << 1)

/// Enable standard boolean operators and constants
static let boolSymbols = Options(rawValue: 1 << 2)

/// Assume all functions and operators in `symbols` are "pure", i.e.
/// they have no side effects, and always produce the same output
/// for a given set of arguments
static let pureSymbols = Options(rawValue: 1 << 3)

/// Packed bitfield of options
let rawValue: Int

/// Designated initializer
init(rawValue: Int) {
self.rawValue = rawValue
}
}

/// Alternative constructor for advanced usage
/// Allows for dynamic symbol lookup or generation without any performance overhead
/// Note that both math and boolean symbols are enabled by default - to disable them
Expand Down Expand Up @@ -288,28 +261,6 @@ final class CalcExpression: CustomStringConvertible {
)
}

/// Verify that the string is a valid identifier
static func isValidIdentifier(_ string: String) -> Bool {
var characters = UnicodeScalarView(string)
switch characters.parseIdentifier() ?? characters.parseEscapedIdentifier() {
case .symbol(.variable, _, _)?:
return characters.isEmpty
default:
return false
}
}

/// Verify that the string is a valid operator
static func isValidOperator(_ string: String) -> Bool {
var characters = UnicodeScalarView(string)
guard case let .symbol(symbol, _, _)? = characters.parseOperator(),
case let .infix(name) = symbol, name != "(", name != "["
else {
return false
}
return characters.isEmpty
}

/// Parse an expression.
/// Returns an opaque struct that cannot be evaluated but can be queried
/// for symbols or used to construct an executable CalcExpression instance
Expand Down Expand Up @@ -1432,7 +1383,7 @@ extension UnicodeScalarView {
}
throw CalcExpression.Error.unexpectedToken(result.description)
case nil:
throw CalcExpression.Error.emptyExpression
throw CalcExpression.Error.message("Empty expression")
}
}
}
Expand Down
Loading

0 comments on commit 4a4f48a

Please sign in to comment.