@@ -1291,3 +1291,256 @@ let completionPathFromMaybeBuiltin path =
12911291      (*  Route Stdlib_X to Stdlib.X for proper completions without the Stdlib_ prefix *) 
12921292      Some  (String. split_on_char '_'  mainModule)
12931293    |  _  -> None )
1294+ 
1295+ module  ExpandType  =  struct 
1296+   type  expandTypeInput  =
1297+     | TypeExpr  of  {
1298+         typeExpr : Types .type_expr ; 
1299+         name : string  Location .loc  option ; 
1300+         env : QueryEnv .t ; 
1301+       }
1302+     | TypeDecl  of  {
1303+         typeDecl : Types .type_declaration ; 
1304+         name : string  Location .loc ; 
1305+         env : QueryEnv .t ; 
1306+       }
1307+ 
1308+   type  expandTypeReturn  = {
1309+     mainTypes : expandTypeInput  list ; 
1310+     relatedTypes : expandTypeInput  list ; 
1311+   }
1312+ 
1313+   module  TypeIdSet  =  Set. Make  (String )
1314+ 
1315+   let  expandTypes  (input  : expandTypeInput ) ~(full  : SharedTypes.full ) = 
1316+     let  rootEnv =  QueryEnv. fromFile full.file in 
1317+ 
1318+     let  expandTypeInputToKey  =  function 
1319+       |  TypeExpr  {name; env}  ->
1320+         typeId ~env 
1321+           ~name: 
1322+             (match  name with 
1323+             |  None  -> Location. mkloc " <unknown>" Location. none
1324+             |  Some  n  -> n)
1325+       |  TypeDecl  {name; env}  -> typeId ~env  ~name 
1326+     in 
1327+ 
1328+     let  deduplicateAndRemoveAlreadyPresent  mainTypes  relatedTypes  = 
1329+       let  mainIds =  ref  TypeIdSet. empty in 
1330+       let  dedupedMain = 
1331+         mainTypes
1332+         |>  List. fold_left
1333+              (fun  acc  item  ->
1334+                let  id =  expandTypeInputToKey item in 
1335+                if  TypeIdSet. mem id ! mainIds then  acc
1336+                else  (
1337+                  mainIds :=  TypeIdSet. add id ! mainIds;
1338+                  item :: acc))
1339+              [] 
1340+         |>  List. rev
1341+       in 
1342+ 
1343+       let  relatedIds =  ref  TypeIdSet. empty in 
1344+       let  dedupedRelated = 
1345+         relatedTypes
1346+         |>  List. fold_left
1347+              (fun  acc  item  ->
1348+                let  id =  expandTypeInputToKey item in 
1349+                if  TypeIdSet. mem id ! mainIds ||  TypeIdSet. mem id ! relatedIds then 
1350+                  acc
1351+                else  (
1352+                  relatedIds :=  TypeIdSet. add id ! relatedIds;
1353+                  item :: acc))
1354+              [] 
1355+         |>  List. rev
1356+       in 
1357+ 
1358+       (dedupedMain, dedupedRelated)
1359+     in 
1360+ 
1361+     let  rec  followTypeAliases  acc  (typeExpr  : Types.type_expr ) = 
1362+       match  typeExpr.desc with 
1363+       |  Tlink  t1  |  Tsubst  t1  |  Tpoly  (t1 , [] ) -> followTypeAliases acc t1
1364+       |  Tconstr  (path , typeArgs , _ ) -> (
1365+         match 
1366+           References. digConstructor ~env: rootEnv ~package: full.package path
1367+         with 
1368+         |  Some 
1369+             ( env,
1370+               {
1371+                 name;
1372+                 item =  {decl =  {type_manifest =  Some  t1; type_params} as  decl};
1373+               } ) ->
1374+           let  instantiated = 
1375+             instantiateType ~type Params:type_params ~type Args t1
1376+           in 
1377+           let  currentAlias =  TypeDecl  {typeDecl =  decl; name; env} in 
1378+           followTypeAliases (currentAlias :: acc) instantiated
1379+         |  Some  (env , {name; item  = {decl} } ) ->
1380+           TypeDecl  {typeDecl =  decl; name; env} :: acc
1381+         |  None  -> acc)
1382+       |  _  -> acc
1383+     in 
1384+ 
1385+     let  rec  findFinalConcreteType  (typeExpr  : Types.type_expr ) = 
1386+       match  typeExpr.desc with 
1387+       |  Tlink  t1  |  Tsubst  t1  |  Tpoly  (t1 , [] ) -> findFinalConcreteType t1
1388+       |  Tconstr  (path , typeArgs , _ ) -> (
1389+         match 
1390+           References. digConstructor ~env: rootEnv ~package: full.package path
1391+         with 
1392+         |  Some  (_env, {item =  {decl =  {type_manifest =  Some  t1; type_params}}})
1393+           ->
1394+           let  instantiated = 
1395+             instantiateType ~type Params:type_params ~type Args t1
1396+           in 
1397+           findFinalConcreteType instantiated
1398+         |  _  -> typeExpr)
1399+       |  _  -> typeExpr
1400+     in 
1401+ 
1402+     let  rec  extractRelevantTypesFromTypeExpr  ?(depth  = 0 ) 
1403+         (typeExpr  : Types.type_expr ) = 
1404+       if  depth >  1  then  [] 
1405+       else 
1406+         match  typeExpr.desc with 
1407+         |  Tlink  t1  |  Tsubst  t1  |  Tpoly  (t1 , [] ) ->
1408+           extractRelevantTypesFromTypeExpr ~depth  t1
1409+         |  Tconstr  (path , typeArgs , _ ) ->
1410+           let  constructorTypes = 
1411+             match 
1412+               References. digConstructor ~env: rootEnv ~package: full.package path
1413+             with 
1414+             |  Some  (env , {name; item  = {kind  = Record  fields ; decl} } ) ->
1415+               TypeDecl  {typeDecl =  decl; name; env}
1416+               ::
1417+               (if  depth =  0  then 
1418+                  fields
1419+                  |>  List. fold_left
1420+                       (fun  acc  field  ->
1421+                         acc
1422+                         @  extractRelevantTypesFromTypeExpr ~depth: (depth +  1 )
1423+                             field.typ)
1424+                       [] 
1425+                else  [] )
1426+             |  Some  (env , {name; item  = {kind  = Variant  constructors ; decl} } ) ->
1427+               TypeDecl  {typeDecl =  decl; name; env}
1428+               ::
1429+               (if  depth =  0  then 
1430+                  constructors
1431+                  |>  List. fold_left
1432+                       (fun  acc  (constructor  : Constructor.t ) ->
1433+                         match  constructor.args with 
1434+                         |  Args  args  ->
1435+                           args
1436+                           |>  List. fold_left
1437+                                (fun  acc  (argType , _ ) ->
1438+                                  acc
1439+                                  @  extractRelevantTypesFromTypeExpr
1440+                                      ~depth: (depth +  1 ) argType)
1441+                                acc
1442+                         |  InlineRecord  fields  ->
1443+                           fields
1444+                           |>  List. fold_left
1445+                                (fun  acc  field  ->
1446+                                  acc
1447+                                  @  extractRelevantTypesFromTypeExpr
1448+                                      ~depth: (depth +  1 ) field.typ)
1449+                                acc)
1450+                       [] 
1451+                else  [] )
1452+             |  Some  (_env , {item  = {decl  = {type_manifest  = Some  t1 } } } ) ->
1453+               extractRelevantTypesFromTypeExpr ~depth  t1
1454+             |  _  -> [] 
1455+           in 
1456+           let  typeArgTypes = 
1457+             typeArgs
1458+             |>  List. fold_left
1459+                  (fun  acc  typeArg  ->
1460+                    acc
1461+                    @  extractRelevantTypesFromTypeExpr ~depth: (depth +  1 ) typeArg)
1462+                  [] 
1463+           in 
1464+           constructorTypes @  typeArgTypes
1465+         |  Tvariant  {row_fields}  when  depth =  0  ->
1466+           row_fields
1467+           |>  List. fold_left
1468+                (fun  acc  (_label , field ) ->
1469+                  match  field with 
1470+                  |  Types. Rpresent  (Some typeExpr ) ->
1471+                    acc
1472+                    @  extractRelevantTypesFromTypeExpr ~depth: (depth +  1 )
1473+                        typeExpr
1474+                  |  Reither  (_ , typeExprs , _ , _ ) ->
1475+                    typeExprs
1476+                    |>  List. fold_left
1477+                         (fun  acc  typeExpr  ->
1478+                           acc
1479+                           @  extractRelevantTypesFromTypeExpr ~depth: (depth +  1 )
1480+                               typeExpr)
1481+                         acc
1482+                  |  _  -> acc)
1483+                [] 
1484+         |  _  -> [] 
1485+     in 
1486+ 
1487+     let  extractRelevantTypesFromTypeDecl  (typeDecl  : Types.type_declaration ) = 
1488+       match  typeDecl.type_manifest with 
1489+       |  Some  typeExpr  -> extractRelevantTypesFromTypeExpr typeExpr
1490+       |  None  -> (
1491+         match  typeDecl.type_kind with 
1492+         |  Type_record  (label_declarations , _ ) ->
1493+           label_declarations
1494+           |>  List. fold_left
1495+                (fun  acc  (label_decl  : Types.label_declaration ) ->
1496+                  acc
1497+                  @  extractRelevantTypesFromTypeExpr ~depth: 1  label_decl.ld_type)
1498+                [] 
1499+         |  Type_variant  constructor_declarations  ->
1500+           constructor_declarations
1501+           |>  List. fold_left
1502+                (fun  acc  (constructor_decl  : Types.constructor_declaration ) ->
1503+                  match  constructor_decl.cd_args with 
1504+                  |  Cstr_tuple  type_exprs  ->
1505+                    type_exprs
1506+                    |>  List. fold_left
1507+                         (fun  acc  type_expr  ->
1508+                           acc
1509+                           @  extractRelevantTypesFromTypeExpr ~depth: 1  type_expr)
1510+                         acc
1511+                  |  Cstr_record  label_declarations  ->
1512+                    label_declarations
1513+                    |>  List. fold_left
1514+                         (fun  acc  (label_decl  : Types.label_declaration ) ->
1515+                           acc
1516+                           @  extractRelevantTypesFromTypeExpr ~depth: 1 
1517+                               label_decl.ld_type)
1518+                         acc)
1519+                [] 
1520+         |  Type_abstract  |  Type_open  -> [] )
1521+     in 
1522+ 
1523+     match  input with 
1524+     |  TypeExpr  {typeExpr; name; env}  ->
1525+       let  aliases =  followTypeAliases []  typeExpr in 
1526+       let  mainTypesRaw =  TypeExpr  {typeExpr; name; env} :: aliases in 
1527+ 
1528+       (*  Extract related types from the final concrete type *) 
1529+       let  finalConcreteType =  findFinalConcreteType typeExpr in 
1530+       let  relatedTypesRaw = 
1531+         extractRelevantTypesFromTypeExpr finalConcreteType
1532+       in 
1533+ 
1534+       let  mainTypes, relatedTypes = 
1535+         deduplicateAndRemoveAlreadyPresent mainTypesRaw relatedTypesRaw
1536+       in 
1537+       {mainTypes; relatedTypes}
1538+     |  TypeDecl  {typeDecl}  ->
1539+       let  mainTypes =  [input] in 
1540+       let  relatedTypesRaw =  extractRelevantTypesFromTypeDecl typeDecl in 
1541+ 
1542+       let  _, relatedTypes = 
1543+         deduplicateAndRemoveAlreadyPresent mainTypes relatedTypesRaw
1544+       in 
1545+       {mainTypes; relatedTypes}
1546+ end 
0 commit comments