@@ -169,56 +169,89 @@ object NameOps {
169
169
}
170
170
}
171
171
172
- def functionArity : Int =
173
- functionArityFor(str.Function ) max
174
- functionArityFor(str.ContextFunction ) max {
175
- val n =
176
- functionArityFor(str.ErasedFunction ) max
177
- functionArityFor(str.ErasedContextFunction )
178
- if (n == 0 ) - 1 else n
179
- }
172
+ private def functionSuffixStart : Int =
173
+ val first = name.firstPart
174
+ var idx = first.length - 1
175
+ if idx >= 8 && first(idx).isDigit then
176
+ while
177
+ idx = idx - 1
178
+ idx >= 8 && first(idx).isDigit
179
+ do ()
180
+ if first(idx - 7 ) == 'F'
181
+ && first(idx - 6 ) == 'u'
182
+ && first(idx - 5 ) == 'n'
183
+ && first(idx - 4 ) == 'c'
184
+ && first(idx - 3 ) == 't'
185
+ && first(idx - 2 ) == 'i'
186
+ && first(idx - 1 ) == 'o'
187
+ && first(idx) == 'n'
188
+ then idx - 7
189
+ else - 1
190
+ else - 1
191
+
192
+ /** The arity of a name ending in the suffix `Function{\d}`, but -1
193
+ * if the number is larger than Int.MaxValue / 10.
194
+ * @param suffixStart The index of the suffix
195
+ */
196
+ private def funArity (suffixStart : Int ): Int =
197
+ inline val MaxSafeInt = MaxValue / 10
198
+ val first = name.firstPart
199
+ def collectDigits (acc : Int , idx : Int ): Int =
200
+ if idx == first.length then acc
201
+ else
202
+ val d = digit2int(first(idx), 10 )
203
+ if d < 0 || acc > MaxSafeInt then - 1
204
+ else collectDigits(acc * 10 + d, idx + 1 )
205
+ collectDigits(0 , suffixStart + 8 )
180
206
181
- /** Is a function name, i.e one of FunctionXXL, FunctionN, ContextFunctionN for N >= 0 or ErasedFunctionN, ErasedContextFunctionN for N > 0
207
+ /** name[0..suffixStart) == `str` */
208
+ private def isPreceded (str : String , suffixStart : Int ) =
209
+ str.length == suffixStart && name.firstPart.startsWith(str)
210
+
211
+ /** Same as `funArity`, except that it returns -1 if the prefix
212
+ * is not one of "", "Context", "Erased", "ErasedContext"
213
+ */
214
+ private def checkedFunArity (suffixStart : Int ) =
215
+ if suffixStart == 0
216
+ || isPreceded(" Context" , suffixStart)
217
+ || isPreceded(" Erased" , suffixStart)
218
+ || isPreceded(" ErasedContext" , suffixStart)
219
+ then funArity(suffixStart)
220
+ else - 1
221
+
222
+ /** Is a function name, i.e one of FunctionXXL, FunctionN, ContextFunctionN, ErasedFunctionN, ErasedContextFunctionN for N >= 0
182
223
*/
183
- def isFunction : Boolean = (name eq tpnme.FunctionXXL ) || functionArity >= 0
224
+ def isFunction : Boolean =
225
+ (name eq tpnme.FunctionXXL ) || checkedFunArity(functionSuffixStart) >= 0
184
226
185
- /** Is an context function name, i.e one of ContextFunctionN for N >= 0 or ErasedContextFunctionN for N > 0
227
+ /** Is an context function name, i.e one of ContextFunctionN or ErasedContextFunctionN for N >= 0
186
228
*/
187
229
def isContextFunction : Boolean =
188
- functionArityFor(str.ContextFunction ) >= 0 ||
189
- functionArityFor(str.ErasedContextFunction ) > 0
230
+ val suffixStart = functionSuffixStart
231
+ (isPreceded(" Context" , suffixStart) || isPreceded(" ErasedContext" , suffixStart))
232
+ && funArity(suffixStart) >= 0
190
233
191
- /** Is an erased function name, i.e. one of ErasedFunctionN, ErasedContextFunctionN for N > 0
234
+ /** Is an erased function name, i.e. one of ErasedFunctionN, ErasedContextFunctionN for N >= 0
192
235
*/
193
236
def isErasedFunction : Boolean =
194
- functionArityFor(str.ErasedFunction ) > 0 ||
195
- functionArityFor(str.ErasedContextFunction ) > 0
237
+ val suffixStart = functionSuffixStart
238
+ (isPreceded(" Erased" , suffixStart) || isPreceded(" ErasedContext" , suffixStart))
239
+ && funArity(suffixStart) >= 0
196
240
197
241
/** Is a synthetic function name, i.e. one of
198
242
* - FunctionN for N > 22
199
243
* - ContextFunctionN for N >= 0
200
- * - ErasedFunctionN for N > 0
201
- * - ErasedContextFunctionN for N > 0
244
+ * - ErasedFunctionN for N >= 0
245
+ * - ErasedContextFunctionN for N >= 0
202
246
*/
203
247
def isSyntheticFunction : Boolean =
204
- functionArityFor(str. Function ) > MaxImplementedFunctionArity ||
205
- functionArityFor(str. ContextFunction ) >= 0 ||
206
- isErasedFunction
248
+ val suffixStart = functionSuffixStart
249
+ if suffixStart == 0 then funArity(suffixStart) > MaxImplementedFunctionArity
250
+ else checkedFunArity(suffixStart) >= 0
207
251
208
- /** Parsed function arity for function with some specific prefix */
209
- private def functionArityFor (prefix : String ): Int =
210
- inline val MaxSafeInt = MaxValue / 10
211
- val first = name.firstPart
212
- def collectDigits (acc : Int , idx : Int ): Int =
213
- if idx == first.length then acc
214
- else
215
- val d = digit2int(first(idx), 10 )
216
- if d < 0 || acc > MaxSafeInt then - 1
217
- else collectDigits(acc * 10 + d, idx + 1 )
218
- if first.startsWith(prefix) && prefix.length < first.length then
219
- collectDigits(0 , prefix.length)
220
- else
221
- - 1
252
+ def functionArity : Int =
253
+ val suffixStart = functionSuffixStart
254
+ if suffixStart >= 0 then checkedFunArity(suffixStart) else - 1
222
255
223
256
/** The name of the generic runtime operation corresponding to an array operation */
224
257
def genericArrayOp : TermName = name match {
0 commit comments