File: CustomCharClass.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (145 lines) | stat: -rw-r--r-- 3,810 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2021-2022 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
//
//===----------------------------------------------------------------------===//


extension AST {
  public struct CustomCharacterClass: Hashable {
    public var start: Located<Start>
    public var members: [Member]

    public let location: SourceLocation

    public init(
      _ start: Located<Start>,
      _ members: [Member],
      _ sr: SourceLocation
    ) {
      self.start = start
      self.members = members
      self.location = sr
    }

    public enum Member: Hashable {
      /// A nested custom character class `[[ab][cd]]`
      case custom(CustomCharacterClass)

      /// A character range `a-z`
      case range(Range)

      /// A single character or escape
      case atom(Atom)

      /// A quoted sequence. Inside a custom character class this just means
      /// the contents should be interpreted literally.
      case quote(Quote)

      /// Trivia such as non-semantic whitespace.
      case trivia(Trivia)

      /// A binary operator applied to sets of members `abc&&def`
      case setOperation([Member], Located<SetOp>, [Member])
    }
    public struct Range: Hashable {
      public var lhs: Atom
      public var dashLoc: SourceLocation
      public var rhs: Atom
      public var trivia: [AST.Trivia]

      public init(
        _ lhs: Atom, _ dashLoc: SourceLocation, _ rhs: Atom,
        trivia: [AST.Trivia]
      ) {
        self.lhs = lhs
        self.dashLoc = dashLoc
        self.rhs = rhs
        self.trivia = trivia
      }

      public var location: SourceLocation {
        lhs.location.union(with: rhs.location)
      }
    }
    public enum SetOp: String, Hashable {
      case subtraction = "--"
      case intersection = "&&"
      case symmetricDifference = "~~"
    }
    public enum Start: String, Hashable {
      case normal = "["
      case inverted = "[^"
    }
  }
}

extension AST.CustomCharacterClass {
  public var isInverted: Bool { start.value == .inverted }
}

extension CustomCC.Member {
  private var _associatedValue: Any {
    switch self {
    case .custom(let c): return c
    case .range(let r): return r
    case .atom(let a): return a
    case .quote(let q): return q
    case .trivia(let t): return t
    case .setOperation(let lhs, let op, let rhs): return (lhs, op, rhs)
    }
  }

  func `as`<T>(_ t: T.Type = T.self) -> T? {
    _associatedValue as? T
  }

  public var isTrivia: Bool {
    if case .trivia = self { return true }
    return false
  }

  public var asTrivia: AST.Trivia? {
    guard case .trivia(let t) = self else { return nil }
    return t
  }

  public var isSemantic: Bool {
    !isTrivia
  }

  public var location: SourceLocation {
    switch self {
    case let .custom(c): return c.location
    case let .range(r):  return r.location
    case let .atom(a):   return a.location
    case let .quote(q):  return q.location
    case let .trivia(t): return t.location
    case let .setOperation(lhs, dash, rhs):
      var loc = dash.location
      if let lhs = lhs.first {
        loc = loc.union(with: lhs.location)
      }
      if let rhs = rhs.last {
        loc = loc.union(with: rhs.location)
      }
      return loc
    }
  }
}

extension AST.CustomCharacterClass {
  /// Strips trivia from the character class members.
  ///
  /// This method doesn't recurse into nested custom character classes.
  public var strippingTriviaShallow: Self {
    var copy = self
    copy.members = copy.members.filter(\.isSemantic)
    return copy
  }
}