Advertisement
Guest User

Untitled

a guest
Oct 16th, 2019
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.57 KB | None | 0 0
  1. import { zip } from 'fp-ts/lib/Array'
  2. import { fold, monoidSum } from 'fp-ts/lib/Monoid'
  3.  
  4. import { Type as TypeO, FunctionRecord } from 'ts-earch-types'
  5.  
  6. import { parseQuery, isName, FunctionType } from './parse'
  7.  
  8. const sum = fold(monoidSum)
  9.  
  10. const matchesNameType = (query: string) => (fn: FunctionRecord) =>
  11. Boolean(fn.name && fn.name.includes(query))
  12.  
  13. // should become a range when considering type checking
  14. // e.g. weighReturnType('string', 'string') => 2
  15. // weighReturnType('string', StringAlias) => 1.x ?
  16. // weighReturnType('string', 'string' | 'number') => 1
  17. // const weighReturnType = (query: string, returnType: string) =>
  18. // query === returnType ? 2 : 0
  19.  
  20. const weighParams = (query: TypeO[], params: TypeO[]) => {
  21. let paramsWeight = 0
  22.  
  23. // m -> matches
  24. // n -> # of params
  25. if (query.length === params.length) {
  26. paramsWeight =
  27. sum(zip(query, params).map(([q, p]) => weighParam(q)(p))) / query.length
  28.  
  29. // + 1 + m/n # only if some params match
  30. if (paramsWeight > 0) {
  31. paramsWeight += paramsWeight + 1
  32. }
  33. } else {
  34. // + m/n
  35. // TODO
  36. paramsWeight +=
  37. query.reduce((acc, type) => (params.includes(type) ? acc + 1 : acc), 0) /
  38. query.length
  39. }
  40.  
  41. return paramsWeight
  42. }
  43.  
  44. function weighParam(query: TypeO): (param: TypeO) => number {
  45. return TypeO.match({
  46. Any: () => 1,
  47. Unknown: () => 1,
  48. Undefined: () => (TypeO.isUndefined(query) ? 1 : 0),
  49. LiteralPrimitive: ({ text }) =>
  50. TypeO.isLiteralPrimitive(query) ? (query.text === text ? 1 : 0) : 0,
  51. Primitive: ({ typeName }) =>
  52. TypeO.isPrimitive(query) ? (query.typeName === typeName ? 1 : 0) : 0,
  53. Array: ({ elementsType }) =>
  54. TypeO.isArray(query)
  55. ? // TODO: `weighType` -> to be used for tuples, unions,
  56. // intersections, functions, etc
  57. weighParam(query.elementsType)(elementsType) === 1
  58. ? 1
  59. : // TODO: find proper weight when `elementsType` don't match
  60. 0.5
  61. : 0,
  62. Union: () => 1,
  63. Intersection: () => 1,
  64. Tuple: ({ types }) =>
  65. TypeO.isTuple(query)
  66. ? query.types.length === types.length
  67. ? sum(zip(query.types, types).map(([q, p]) => weighParam(q)(p))) /
  68. types.length
  69. : 0
  70. : 0,
  71. Function: () => 0,
  72. HigherOrder: p => {
  73. if (TypeO.isHigherOrder(query)) {
  74. // TODO: type name (`text` has the whole definition)
  75. const typeMatch = p.text.split('<')[0] === query.text.split('<')[0]
  76.  
  77. const args =
  78. sum(
  79. zip(query.arguments, p.arguments).map(([q, p]) => weighParam(q)(p)),
  80. ) / p.arguments.length
  81.  
  82. return typeMatch ? (args === 1 ? 1 : 0.5) : 0
  83. }
  84.  
  85. return 0
  86. },
  87. Other: ({ text }) =>
  88. TypeO.isOther(query) ? (text === query.text ? 1 : 0) : 0,
  89. })
  90. }
  91.  
  92. export const weighFunctionRecord = ({ signature }: FunctionType) => (
  93. fn: FunctionRecord,
  94. ): [FunctionRecord, number] => {
  95. const { returnType, parameters } = signature.signatures[0]
  96.  
  97. const weight =
  98. weighParams(
  99. fn.signature.parameters.map(({ type }) => type),
  100. parameters.map(({ type }) => type),
  101. ) +
  102. // TODO: `weighReturnType`
  103. weighParam(returnType)(fn.signature.returnType)
  104.  
  105. return [fn, weight]
  106. }
  107.  
  108. export const search = (types: FunctionRecord[]) => (query: string) => {
  109. const q = parseQuery(query)
  110.  
  111. return isName(q)
  112. ? types.filter(matchesNameType(q.value)).slice(0, 100)
  113. : types
  114. .map(weighFunctionRecord(q))
  115. .filter(([, weight]) => weight > 0)
  116. .sort(([, a], [, b]) => (a < b ? 1 : -1))
  117. .slice(0, 100)
  118. .map(([fn]) => fn)
  119. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement