expr.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798
  1. // Copyright 2021 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package mk2rbc
  15. import (
  16. "fmt"
  17. "strings"
  18. )
  19. // Represents an expression in the Starlark code. An expression has a type.
  20. type starlarkExpr interface {
  21. starlarkNode
  22. typ() starlarkType
  23. // Emit the code to copy the expression, otherwise we will end up
  24. // with source and target pointing to the same list.
  25. emitListVarCopy(gctx *generationContext)
  26. // Return the expression, calling the transformer func for
  27. // every expression in the tree. If the transformer func returns non-nil,
  28. // its result is used in place of the expression it was called with in the
  29. // resulting expression. The resulting starlarkExpr will contain as many
  30. // of the same objects from the original expression as possible.
  31. transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr
  32. }
  33. func maybeString(expr starlarkExpr) (string, bool) {
  34. if x, ok := expr.(*stringLiteralExpr); ok {
  35. return x.literal, true
  36. }
  37. return "", false
  38. }
  39. type stringLiteralExpr struct {
  40. literal string
  41. }
  42. func (s *stringLiteralExpr) emit(gctx *generationContext) {
  43. gctx.writef("%q", s.literal)
  44. }
  45. func (_ *stringLiteralExpr) typ() starlarkType {
  46. return starlarkTypeString
  47. }
  48. func (s *stringLiteralExpr) emitListVarCopy(gctx *generationContext) {
  49. s.emit(gctx)
  50. }
  51. func (s *stringLiteralExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
  52. if replacement := transformer(s); replacement != nil {
  53. return replacement
  54. } else {
  55. return s
  56. }
  57. }
  58. // Integer literal
  59. type intLiteralExpr struct {
  60. literal int
  61. }
  62. func (s *intLiteralExpr) emit(gctx *generationContext) {
  63. gctx.writef("%d", s.literal)
  64. }
  65. func (_ *intLiteralExpr) typ() starlarkType {
  66. return starlarkTypeInt
  67. }
  68. func (s *intLiteralExpr) emitListVarCopy(gctx *generationContext) {
  69. s.emit(gctx)
  70. }
  71. func (s *intLiteralExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
  72. if replacement := transformer(s); replacement != nil {
  73. return replacement
  74. } else {
  75. return s
  76. }
  77. }
  78. // Boolean literal
  79. type boolLiteralExpr struct {
  80. literal bool
  81. }
  82. func (b *boolLiteralExpr) emit(gctx *generationContext) {
  83. if b.literal {
  84. gctx.write("True")
  85. } else {
  86. gctx.write("False")
  87. }
  88. }
  89. func (_ *boolLiteralExpr) typ() starlarkType {
  90. return starlarkTypeBool
  91. }
  92. func (b *boolLiteralExpr) emitListVarCopy(gctx *generationContext) {
  93. b.emit(gctx)
  94. }
  95. func (b *boolLiteralExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
  96. if replacement := transformer(b); replacement != nil {
  97. return replacement
  98. } else {
  99. return b
  100. }
  101. }
  102. type globalsExpr struct {
  103. }
  104. func (g *globalsExpr) emit(gctx *generationContext) {
  105. gctx.write("g")
  106. }
  107. func (g *globalsExpr) typ() starlarkType {
  108. return starlarkTypeUnknown
  109. }
  110. func (g *globalsExpr) emitListVarCopy(gctx *generationContext) {
  111. g.emit(gctx)
  112. }
  113. func (g *globalsExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
  114. if replacement := transformer(g); replacement != nil {
  115. return replacement
  116. } else {
  117. return g
  118. }
  119. }
  120. // interpolateExpr represents Starlark's interpolation operator <string> % list
  121. // we break <string> into a list of chunks, i.e., "first%second%third" % (X, Y)
  122. // will have chunks = ["first", "second", "third"] and args = [X, Y]
  123. type interpolateExpr struct {
  124. chunks []string // string chunks, separated by '%'
  125. args []starlarkExpr
  126. }
  127. func NewInterpolateExpr(parts []starlarkExpr) starlarkExpr {
  128. result := &interpolateExpr{}
  129. needString := true
  130. for _, part := range parts {
  131. if needString {
  132. if strLit, ok := part.(*stringLiteralExpr); ok {
  133. result.chunks = append(result.chunks, strLit.literal)
  134. } else {
  135. result.chunks = append(result.chunks, "")
  136. }
  137. needString = false
  138. } else {
  139. if strLit, ok := part.(*stringLiteralExpr); ok {
  140. result.chunks[len(result.chunks)-1] += strLit.literal
  141. } else {
  142. result.args = append(result.args, part)
  143. needString = true
  144. }
  145. }
  146. }
  147. if len(result.chunks) == len(result.args) {
  148. result.chunks = append(result.chunks, "")
  149. }
  150. if len(result.args) == 0 {
  151. return &stringLiteralExpr{literal: strings.Join(result.chunks, "")}
  152. }
  153. return result
  154. }
  155. func (xi *interpolateExpr) emit(gctx *generationContext) {
  156. if len(xi.chunks) != len(xi.args)+1 {
  157. panic(fmt.Errorf("malformed interpolateExpr: #chunks(%d) != #args(%d)+1",
  158. len(xi.chunks), len(xi.args)))
  159. }
  160. // Generate format as join of chunks, but first escape '%' in them
  161. format := strings.ReplaceAll(xi.chunks[0], "%", "%%")
  162. for _, chunk := range xi.chunks[1:] {
  163. format += "%s" + strings.ReplaceAll(chunk, "%", "%%")
  164. }
  165. gctx.writef("%q %% ", format)
  166. emitArg := func(arg starlarkExpr) {
  167. if arg.typ() == starlarkTypeList {
  168. gctx.write(`" ".join(`)
  169. arg.emit(gctx)
  170. gctx.write(`)`)
  171. } else {
  172. arg.emit(gctx)
  173. }
  174. }
  175. if len(xi.args) == 1 {
  176. emitArg(xi.args[0])
  177. } else {
  178. sep := "("
  179. for _, arg := range xi.args {
  180. gctx.write(sep)
  181. emitArg(arg)
  182. sep = ", "
  183. }
  184. gctx.write(")")
  185. }
  186. }
  187. func (_ *interpolateExpr) typ() starlarkType {
  188. return starlarkTypeString
  189. }
  190. func (xi *interpolateExpr) emitListVarCopy(gctx *generationContext) {
  191. xi.emit(gctx)
  192. }
  193. func (xi *interpolateExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
  194. for i := range xi.args {
  195. xi.args[i] = xi.args[i].transform(transformer)
  196. }
  197. if replacement := transformer(xi); replacement != nil {
  198. return replacement
  199. } else {
  200. return xi
  201. }
  202. }
  203. type variableRefExpr struct {
  204. ref variable
  205. }
  206. func NewVariableRefExpr(ref variable) starlarkExpr {
  207. if predefined, ok := ref.(*predefinedVariable); ok {
  208. return predefined.value
  209. }
  210. return &variableRefExpr{ref}
  211. }
  212. func (v *variableRefExpr) emit(gctx *generationContext) {
  213. v.ref.emitGet(gctx)
  214. }
  215. func (v *variableRefExpr) typ() starlarkType {
  216. return v.ref.valueType()
  217. }
  218. func (v *variableRefExpr) emitListVarCopy(gctx *generationContext) {
  219. v.emit(gctx)
  220. if v.typ() == starlarkTypeList {
  221. gctx.write("[:]") // this will copy the list
  222. }
  223. }
  224. func (v *variableRefExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
  225. if replacement := transformer(v); replacement != nil {
  226. return replacement
  227. } else {
  228. return v
  229. }
  230. }
  231. type toStringExpr struct {
  232. expr starlarkExpr
  233. }
  234. func (s *toStringExpr) emit(ctx *generationContext) {
  235. switch s.expr.typ() {
  236. case starlarkTypeString, starlarkTypeUnknown:
  237. // Assume unknown types are strings already.
  238. s.expr.emit(ctx)
  239. case starlarkTypeList:
  240. ctx.write(`" ".join(`)
  241. s.expr.emit(ctx)
  242. ctx.write(")")
  243. case starlarkTypeInt:
  244. ctx.write(`("%d" % (`)
  245. s.expr.emit(ctx)
  246. ctx.write("))")
  247. case starlarkTypeBool:
  248. ctx.write(`("true" if (`)
  249. s.expr.emit(ctx)
  250. ctx.write(`) else "")`)
  251. case starlarkTypeVoid:
  252. ctx.write(`""`)
  253. default:
  254. panic("Unknown starlark type!")
  255. }
  256. }
  257. func (s *toStringExpr) typ() starlarkType {
  258. return starlarkTypeString
  259. }
  260. func (s *toStringExpr) emitListVarCopy(gctx *generationContext) {
  261. s.emit(gctx)
  262. }
  263. func (s *toStringExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
  264. s.expr = s.expr.transform(transformer)
  265. if replacement := transformer(s); replacement != nil {
  266. return replacement
  267. } else {
  268. return s
  269. }
  270. }
  271. type notExpr struct {
  272. expr starlarkExpr
  273. }
  274. func (n *notExpr) emit(ctx *generationContext) {
  275. ctx.write("not ")
  276. n.expr.emit(ctx)
  277. }
  278. func (_ *notExpr) typ() starlarkType {
  279. return starlarkTypeBool
  280. }
  281. func (n *notExpr) emitListVarCopy(gctx *generationContext) {
  282. n.emit(gctx)
  283. }
  284. func (n *notExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
  285. n.expr = n.expr.transform(transformer)
  286. if replacement := transformer(n); replacement != nil {
  287. return replacement
  288. } else {
  289. return n
  290. }
  291. }
  292. type eqExpr struct {
  293. left, right starlarkExpr
  294. isEq bool // if false, it's !=
  295. }
  296. func (eq *eqExpr) emit(gctx *generationContext) {
  297. if eq.left.typ() != eq.right.typ() {
  298. eq.left = &toStringExpr{expr: eq.left}
  299. eq.right = &toStringExpr{expr: eq.right}
  300. }
  301. // General case
  302. eq.left.emit(gctx)
  303. if eq.isEq {
  304. gctx.write(" == ")
  305. } else {
  306. gctx.write(" != ")
  307. }
  308. eq.right.emit(gctx)
  309. }
  310. func (_ *eqExpr) typ() starlarkType {
  311. return starlarkTypeBool
  312. }
  313. func (eq *eqExpr) emitListVarCopy(gctx *generationContext) {
  314. eq.emit(gctx)
  315. }
  316. func (eq *eqExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
  317. eq.left = eq.left.transform(transformer)
  318. eq.right = eq.right.transform(transformer)
  319. if replacement := transformer(eq); replacement != nil {
  320. return replacement
  321. } else {
  322. return eq
  323. }
  324. }
  325. type listExpr struct {
  326. items []starlarkExpr
  327. }
  328. func (l *listExpr) emit(gctx *generationContext) {
  329. if !gctx.inAssignment || len(l.items) < 2 {
  330. gctx.write("[")
  331. sep := ""
  332. for _, item := range l.items {
  333. gctx.write(sep)
  334. item.emit(gctx)
  335. sep = ", "
  336. }
  337. gctx.write("]")
  338. return
  339. }
  340. gctx.write("[")
  341. gctx.indentLevel += 2
  342. for _, item := range l.items {
  343. gctx.newLine()
  344. item.emit(gctx)
  345. gctx.write(",")
  346. }
  347. gctx.indentLevel -= 2
  348. gctx.newLine()
  349. gctx.write("]")
  350. }
  351. func (_ *listExpr) typ() starlarkType {
  352. return starlarkTypeList
  353. }
  354. func (l *listExpr) emitListVarCopy(gctx *generationContext) {
  355. l.emit(gctx)
  356. }
  357. func (l *listExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
  358. itemsCopy := make([]starlarkExpr, len(l.items))
  359. for i, item := range l.items {
  360. itemsCopy[i] = item.transform(transformer)
  361. }
  362. l.items = itemsCopy
  363. if replacement := transformer(l); replacement != nil {
  364. return replacement
  365. } else {
  366. return l
  367. }
  368. }
  369. func newStringListExpr(items []string) *listExpr {
  370. v := listExpr{}
  371. for _, item := range items {
  372. v.items = append(v.items, &stringLiteralExpr{item})
  373. }
  374. return &v
  375. }
  376. // concatExpr generates expr1 + expr2 + ... + exprN in Starlark.
  377. type concatExpr struct {
  378. items []starlarkExpr
  379. }
  380. func (c *concatExpr) emit(gctx *generationContext) {
  381. if len(c.items) == 1 {
  382. c.items[0].emit(gctx)
  383. return
  384. }
  385. if !gctx.inAssignment {
  386. c.items[0].emit(gctx)
  387. for _, item := range c.items[1:] {
  388. gctx.write(" + ")
  389. item.emit(gctx)
  390. }
  391. return
  392. }
  393. gctx.write("(")
  394. c.items[0].emit(gctx)
  395. gctx.indentLevel += 2
  396. for _, item := range c.items[1:] {
  397. gctx.write(" +")
  398. gctx.newLine()
  399. item.emit(gctx)
  400. }
  401. gctx.write(")")
  402. gctx.indentLevel -= 2
  403. }
  404. func (_ *concatExpr) typ() starlarkType {
  405. return starlarkTypeList
  406. }
  407. func (c *concatExpr) emitListVarCopy(gctx *generationContext) {
  408. c.emit(gctx)
  409. }
  410. func (c *concatExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
  411. itemsCopy := make([]starlarkExpr, len(c.items))
  412. for i, item := range c.items {
  413. itemsCopy[i] = item.transform(transformer)
  414. }
  415. c.items = itemsCopy
  416. if replacement := transformer(c); replacement != nil {
  417. return replacement
  418. } else {
  419. return c
  420. }
  421. }
  422. // inExpr generates <expr> [not] in <list>
  423. type inExpr struct {
  424. expr starlarkExpr
  425. list starlarkExpr
  426. isNot bool
  427. }
  428. func (i *inExpr) emit(gctx *generationContext) {
  429. i.expr.emit(gctx)
  430. if i.isNot {
  431. gctx.write(" not in ")
  432. } else {
  433. gctx.write(" in ")
  434. }
  435. i.list.emit(gctx)
  436. }
  437. func (_ *inExpr) typ() starlarkType {
  438. return starlarkTypeBool
  439. }
  440. func (i *inExpr) emitListVarCopy(gctx *generationContext) {
  441. i.emit(gctx)
  442. }
  443. func (i *inExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
  444. i.expr = i.expr.transform(transformer)
  445. i.list = i.list.transform(transformer)
  446. if replacement := transformer(i); replacement != nil {
  447. return replacement
  448. } else {
  449. return i
  450. }
  451. }
  452. type indexExpr struct {
  453. array starlarkExpr
  454. index starlarkExpr
  455. }
  456. func (ix *indexExpr) emit(gctx *generationContext) {
  457. ix.array.emit(gctx)
  458. gctx.write("[")
  459. ix.index.emit(gctx)
  460. gctx.write("]")
  461. }
  462. func (ix *indexExpr) typ() starlarkType {
  463. return starlarkTypeString
  464. }
  465. func (ix *indexExpr) emitListVarCopy(gctx *generationContext) {
  466. ix.emit(gctx)
  467. }
  468. func (ix *indexExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
  469. ix.array = ix.array.transform(transformer)
  470. ix.index = ix.index.transform(transformer)
  471. if replacement := transformer(ix); replacement != nil {
  472. return replacement
  473. } else {
  474. return ix
  475. }
  476. }
  477. type callExpr struct {
  478. object starlarkExpr // nil if static call
  479. name string
  480. args []starlarkExpr
  481. returnType starlarkType
  482. }
  483. func (cx *callExpr) emit(gctx *generationContext) {
  484. if cx.object != nil {
  485. gctx.write("(")
  486. cx.object.emit(gctx)
  487. gctx.write(")")
  488. gctx.write(".", cx.name, "(")
  489. } else {
  490. gctx.write(cx.name, "(")
  491. }
  492. sep := ""
  493. for _, arg := range cx.args {
  494. gctx.write(sep)
  495. arg.emit(gctx)
  496. sep = ", "
  497. }
  498. gctx.write(")")
  499. }
  500. func (cx *callExpr) typ() starlarkType {
  501. return cx.returnType
  502. }
  503. func (cx *callExpr) emitListVarCopy(gctx *generationContext) {
  504. cx.emit(gctx)
  505. }
  506. func (cx *callExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
  507. if cx.object != nil {
  508. cx.object = cx.object.transform(transformer)
  509. }
  510. for i := range cx.args {
  511. cx.args[i] = cx.args[i].transform(transformer)
  512. }
  513. if replacement := transformer(cx); replacement != nil {
  514. return replacement
  515. } else {
  516. return cx
  517. }
  518. }
  519. type ifExpr struct {
  520. condition starlarkExpr
  521. ifTrue starlarkExpr
  522. ifFalse starlarkExpr
  523. }
  524. func (i *ifExpr) emit(gctx *generationContext) {
  525. gctx.write("(")
  526. i.ifTrue.emit(gctx)
  527. gctx.write(" if ")
  528. i.condition.emit(gctx)
  529. gctx.write(" else ")
  530. i.ifFalse.emit(gctx)
  531. gctx.write(")")
  532. }
  533. func (i *ifExpr) typ() starlarkType {
  534. tType := i.ifTrue.typ()
  535. fType := i.ifFalse.typ()
  536. if tType != fType && tType != starlarkTypeUnknown && fType != starlarkTypeUnknown {
  537. panic("Conflicting types in if expression")
  538. }
  539. if tType != starlarkTypeUnknown {
  540. return tType
  541. } else {
  542. return fType
  543. }
  544. }
  545. func (i *ifExpr) emitListVarCopy(gctx *generationContext) {
  546. i.emit(gctx)
  547. }
  548. func (i *ifExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
  549. i.condition = i.condition.transform(transformer)
  550. i.ifTrue = i.ifTrue.transform(transformer)
  551. i.ifFalse = i.ifFalse.transform(transformer)
  552. if replacement := transformer(i); replacement != nil {
  553. return replacement
  554. } else {
  555. return i
  556. }
  557. }
  558. type identifierExpr struct {
  559. name string
  560. }
  561. func (i *identifierExpr) emit(gctx *generationContext) {
  562. gctx.write(i.name)
  563. }
  564. func (i *identifierExpr) typ() starlarkType {
  565. return starlarkTypeUnknown
  566. }
  567. func (i *identifierExpr) emitListVarCopy(gctx *generationContext) {
  568. i.emit(gctx)
  569. }
  570. func (i *identifierExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
  571. if replacement := transformer(i); replacement != nil {
  572. return replacement
  573. } else {
  574. return i
  575. }
  576. }
  577. type foreachExpr struct {
  578. varName string
  579. list starlarkExpr
  580. action starlarkExpr
  581. }
  582. func (f *foreachExpr) emit(gctx *generationContext) {
  583. gctx.write("[")
  584. f.action.emit(gctx)
  585. gctx.write(" for " + f.varName + " in ")
  586. f.list.emit(gctx)
  587. gctx.write("]")
  588. }
  589. func (f *foreachExpr) typ() starlarkType {
  590. return starlarkTypeList
  591. }
  592. func (f *foreachExpr) emitListVarCopy(gctx *generationContext) {
  593. f.emit(gctx)
  594. }
  595. func (f *foreachExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
  596. f.list = f.list.transform(transformer)
  597. f.action = f.action.transform(transformer)
  598. if replacement := transformer(f); replacement != nil {
  599. return replacement
  600. } else {
  601. return f
  602. }
  603. }
  604. type binaryOpExpr struct {
  605. left, right starlarkExpr
  606. op string
  607. returnType starlarkType
  608. }
  609. func (b *binaryOpExpr) emit(gctx *generationContext) {
  610. b.left.emit(gctx)
  611. gctx.write(" " + b.op + " ")
  612. b.right.emit(gctx)
  613. }
  614. func (b *binaryOpExpr) typ() starlarkType {
  615. return b.returnType
  616. }
  617. func (b *binaryOpExpr) emitListVarCopy(gctx *generationContext) {
  618. b.emit(gctx)
  619. }
  620. func (b *binaryOpExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
  621. b.left = b.left.transform(transformer)
  622. b.right = b.right.transform(transformer)
  623. if replacement := transformer(b); replacement != nil {
  624. return replacement
  625. } else {
  626. return b
  627. }
  628. }
  629. type badExpr struct {
  630. errorLocation ErrorLocation
  631. message string
  632. }
  633. func (b *badExpr) emit(gctx *generationContext) {
  634. gctx.emitConversionError(b.errorLocation, b.message)
  635. }
  636. func (_ *badExpr) typ() starlarkType {
  637. return starlarkTypeUnknown
  638. }
  639. func (b *badExpr) emitListVarCopy(gctx *generationContext) {
  640. b.emit(gctx)
  641. }
  642. func (b *badExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
  643. if replacement := transformer(b); replacement != nil {
  644. return replacement
  645. } else {
  646. return b
  647. }
  648. }
  649. func maybeConvertToStringList(expr starlarkExpr) starlarkExpr {
  650. if xString, ok := expr.(*stringLiteralExpr); ok {
  651. return newStringListExpr(strings.Fields(xString.literal))
  652. }
  653. return expr
  654. }
  655. func isEmptyString(expr starlarkExpr) bool {
  656. x, ok := expr.(*stringLiteralExpr)
  657. return ok && x.literal == ""
  658. }
  659. func negateExpr(expr starlarkExpr) starlarkExpr {
  660. switch typedExpr := expr.(type) {
  661. case *notExpr:
  662. return typedExpr.expr
  663. case *inExpr:
  664. typedExpr.isNot = !typedExpr.isNot
  665. return typedExpr
  666. case *eqExpr:
  667. typedExpr.isEq = !typedExpr.isEq
  668. return typedExpr
  669. case *binaryOpExpr:
  670. switch typedExpr.op {
  671. case ">":
  672. typedExpr.op = "<="
  673. return typedExpr
  674. case "<":
  675. typedExpr.op = ">="
  676. return typedExpr
  677. case ">=":
  678. typedExpr.op = "<"
  679. return typedExpr
  680. case "<=":
  681. typedExpr.op = ">"
  682. return typedExpr
  683. default:
  684. return &notExpr{expr: expr}
  685. }
  686. default:
  687. return &notExpr{expr: expr}
  688. }
  689. }