@@ -169,56 +169,89 @@ object NameOps {
169169 }
170170 }
171171
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 )
180206
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
182223 */
183- def isFunction : Boolean = (name eq tpnme.FunctionXXL ) || functionArity >= 0
224+ def isFunction : Boolean =
225+ (name eq tpnme.FunctionXXL ) || checkedFunArity(functionSuffixStart) >= 0
184226
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
186228 */
187229 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
190233
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
192235 */
193236 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
196240
197241 /** Is a synthetic function name, i.e. one of
198242 * - FunctionN for N > 22
199243 * - ContextFunctionN for N >= 0
200- * - ErasedFunctionN for N > 0
201- * - ErasedContextFunctionN for N > 0
244+ * - ErasedFunctionN for N >= 0
245+ * - ErasedContextFunctionN for N >= 0
202246 */
203247 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
207251
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
222255
223256 /** The name of the generic runtime operation corresponding to an array operation */
224257 def genericArrayOp : TermName = name match {
0 commit comments