Skip to content

Commit

Permalink
Ensures wrapped VFL extents are parsed correctly (#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
johnpatrickmorgan committed Nov 5, 2020
1 parent 28df2fc commit f070daa
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 12 deletions.
10 changes: 10 additions & 0 deletions Sources/App/Parsing/ConstraintsParser+AutoLayoutPrimitives.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ extension ConstraintsParser {

static let number = numberString.map(parseDouble)
.named("number")

static let spacing = number.otherwise(spacedNumber)

static let defaultedRelation = optional(relation).map { $0 ?? .equal }

static let extent = defaultedRelation.then(spacing)
}

private extension ConstraintsParser {
Expand All @@ -35,6 +41,10 @@ private extension ConstraintsParser {
static let decimal = signedInteger.then(optional(postDecimal)).map { "\($0)\($1 ?? "")" }
static let numberString = decimal.then(optional(exponent)).map { "\($0)\($1 ?? "")" }

static let spacingTerm = string("NSSpace")
.otherwise(string("NSLayoutAnchorConstraintSpace"))
static let spacedNumber = spacingTerm.skipThen(string("(")).skipThen(number).thenSkip(")")

static func parserForAttribute(_ attribute: Attribute) -> Parser<Attribute> {
let attributeParser = attribute.labels.reduce(pureError(), { string($1).otherwise($0) })
return attributeParser.map { _ in return attribute }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@ extension ConstraintsParser {
private extension ConstraintsParser {

static let layoutItemAttribute = partialInstance.then(dotAttribute)
static let anyConstant = nsSpaceConstant.otherwise(constant)
static let anyConstant = extent.map { Constant($1) }.otherwise(constant)
static let constant = number.map(Constant.init).otherwise(pure(Constant()))
static let nsSpaceConstant = unbracketedNSSpace.map { Constant($0.1) }
static let preMultiplier = optional(number.thenSkip(string("*")).map(Multiplier.init))
.named("prefixed multiplier")
static let postMultiplier = optional(string("*").skipThen(wss).skipThen(number).map(Multiplier.init))
Expand Down
12 changes: 2 additions & 10 deletions Sources/App/Parsing/ConstraintsParser+VFLConstraint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,14 @@ import Sparse

extension ConstraintsParser {

static let vflSpaceConstraint = vflAxis.then(vflBoundedEntity).thenSkip(dash).then(spacer).thenSkip(dash).then(vflBoundedEntity).thenSkip(vflDirection).then(optionalInfo)
static let vflSpaceConstraint = vflAxis.then(vflBoundedEntity).thenSkip(dash).then(vflExtent).thenSkip(dash).then(vflBoundedEntity).thenSkip(vflDirection).then(optionalInfo)
.map(flatten).map(AnonymousConstraint.init)

static let vflExtentConstraint = vflAxis.thenSkip(character("[")).then(vflEntity).then(vflExtent).thenSkip(character("]")).thenSkip(vflDirection).then(optionalInfo)
.map(flatten).map(AnonymousConstraint.init)

static let vflConstraint = vflExtentConstraint.otherwise(vflSpaceConstraint)

static let unbracketedNSSpace = string("NSSpace")
.otherwise(string("NSLayoutAnchorConstraintSpace"))
.skipThen(vflExtent)

static let nsSpacer = character("(").skipThen(unbracketedNSSpace).thenSkip(character(")"))
static let vflExtent = character("(").skipThen(extent).thenSkip(character(")"))
}

// MARK: - Private
Expand All @@ -29,12 +24,9 @@ private extension ConstraintsParser {
static let vAxis = character("V").map { _ in Attribute.Axis.vertical }
static let superview = character("|")
static let vflAxis = hAxis.otherwise(vAxis).thenSkip(colon)
static let vflRelation = optional(relation).map { $0 ?? .equal }
static let vflExtent = character("(").skipThen(vflRelation).then(number).thenSkip(character(")"))
static let vflIdentifierCharacter = characterNot(in: "[]|()")
static let vflIdentifier = many(identifierCharacter.and(vflIdentifierCharacter)).asString()
static let vflEntity = instance.map({ PartialInstance.instance($0) }).otherwise(vflIdentifier.map({ PartialInstance.identifier($0) }))
static let vflBoundedEntity = character("[").skipThen(vflEntity).thenSkip(character("]")).otherwise(string("|").map({ _ in PartialInstance.superview }))
static let vflDirection = optional(string("(LTR)").otherwise(string("(RTL)")))
static let spacer = vflExtent.otherwise(nsSpacer)
}
125 changes: 125 additions & 0 deletions Tests/AppTests/__Snapshots__/ParserTests/testGitHubIssues.9.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
{
"constraints" : [
{
"constant" : {
"prefix" : "+ ",
"value" : "8"
},
"description" : "<code style=\"box-shadow: 0px -1px 0px #F39C12 inset; padding-bottom: 1px;\">Label<\/code>'s top edge should be at least <code style=\"box-shadow: 0px -1px 0px #C0392B inset; padding-bottom: 1px;\">ClassName<\/code>'s top edge plus 8.",
"first" : {
"attribute" : {
"includesMargin" : false,
"name" : "top"
},
"instance" : {
"address" : "0x111b35c20",
"className" : "UILabel",
"color" : "rgb(243,156,18)",
"initial" : "L",
"name" : "Label",
"suffix" : ""
}
},
"identity" : {
"address" : "0x2828051d0",
"className" : "_UISystemBaselineConstraint",
"color" : "rgb(26,188,156)",
"initial" : "U",
"name" : "_UISystemBaselineConstraint"
},
"relation" : ">=",
"second" : {
"attribute" : {
"includesMargin" : false,
"name" : "top"
},
"instance" : {
"address" : "0x111b35a60",
"className" : "ModuleName.ClassName",
"color" : "rgb(192,57,43)",
"initial" : "C",
"name" : "ClassName",
"suffix" : ""
}
}
},
{
"description" : "<code style=\"box-shadow: 0px -1px 0px #F39C12 inset; padding-bottom: 1px;\">Label<\/code>'s vertical center should equal <code style=\"box-shadow: 0px -1px 0px #C0392B inset; padding-bottom: 1px;\">ClassName<\/code>'s vertical center.",
"first" : {
"attribute" : {
"includesMargin" : false,
"name" : "centerY"
},
"instance" : {
"address" : "0x111b35c20",
"className" : "UILabel",
"color" : "rgb(243,156,18)",
"initial" : "L",
"name" : "Label",
"suffix" : ""
}
},
"identity" : {
"address" : "0x282805130",
"className" : "NSLayoutConstraint",
"color" : "rgb(26,188,156)",
"initial" : "N",
"name" : "NSLayoutConstraint"
},
"relation" : "==",
"second" : {
"attribute" : {
"includesMargin" : false,
"name" : "centerY"
},
"instance" : {
"address" : "0x111b35a60",
"className" : "ModuleName.ClassName",
"color" : "rgb(192,57,43)",
"initial" : "C",
"name" : "ClassName",
"suffix" : ""
}
}
},
{
"constant" : {
"value" : "0"
},
"description" : "<code style=\"box-shadow: 0px -1px 0px #C0392B inset; padding-bottom: 1px;\">ClassName<\/code>'s height should equal 0.",
"first" : {
"attribute" : {
"includesMargin" : false,
"name" : "height"
},
"instance" : {
"address" : "0x111b35a60",
"className" : "ModuleName.ClassName",
"color" : "rgb(192,57,43)",
"initial" : "C",
"name" : "ClassName",
"suffix" : ""
}
},
"footnote" : {
"marker" : "",
"text" : "This constraint was added by a table or collection view to enforce its cell size."
},
"identity" : {
"address" : "0x282803ed0",
"className" : "NSLayoutConstraint",
"color" : "rgb(26,188,156)",
"identifier" : "UIView-Encapsulated-Layout-Height",
"initial" : "U",
"name" : "UIView-Encapsulated-Layout-Height"
},
"relation" : "=="
}
],
"footnotes" : [
{
"marker" : "",
"text" : "This constraint was added by a table or collection view to enforce its cell size."
}
]
}

0 comments on commit f070daa

Please sign in to comment.