|
| 1 | +open SharedTypes |
| 2 | + |
| 3 | +module StringSet = Set.Make (String) |
| 4 | + |
| 5 | +module Utils = struct |
| 6 | + let wrapInTag content ~tag = Printf.sprintf "<%s>\n%s\n</%s>" tag content tag |
| 7 | + let wrapInTagOpt content ~tag = |
| 8 | + match content with |
| 9 | + | None -> None |
| 10 | + | Some content -> Some (wrapInTag content ~tag) |
| 11 | +end |
| 12 | + |
| 13 | +module LocInfo = struct |
| 14 | + let showModule = Hover.showModule |
| 15 | + |
| 16 | + (* LocInfo thoughts: |
| 17 | + - Check for long variants and/or records, and do not expand them automatically. DomProps being one example. *) |
| 18 | + |
| 19 | + let locInfo ~path ~pos = |
| 20 | + let debug = false in |
| 21 | + let result = |
| 22 | + match Cmt.loadFullCmtFromPath ~path with |
| 23 | + | None -> None |
| 24 | + | Some full -> ( |
| 25 | + match References.getLocItem ~full ~pos ~debug with |
| 26 | + | None -> None |
| 27 | + | Some locItem -> ( |
| 28 | + let isModule = |
| 29 | + match locItem.locType with |
| 30 | + | LModule _ | TopLevelModule _ -> true |
| 31 | + | TypeDefinition _ | Typed _ | Constant _ -> false |
| 32 | + in |
| 33 | + let uriLocOpt = References.definitionForLocItem ~full locItem in |
| 34 | + let skipZero = |
| 35 | + match uriLocOpt with |
| 36 | + | None -> false |
| 37 | + | Some (_, loc) -> |
| 38 | + let isInterface = full.file.uri |> Uri.isInterface in |
| 39 | + let posIsZero {Lexing.pos_lnum; pos_bol; pos_cnum} = |
| 40 | + (not isInterface) && pos_lnum = 1 && pos_cnum - pos_bol = 0 |
| 41 | + in |
| 42 | + (* Skip if range is all zero, unless it's a module *) |
| 43 | + (not isModule) && posIsZero loc.loc_start && posIsZero loc.loc_end |
| 44 | + in |
| 45 | + if skipZero then None |
| 46 | + else |
| 47 | + let file = full.file in |
| 48 | + let package = full.package in |
| 49 | + match locItem.locType with |
| 50 | + | TypeDefinition |
| 51 | + (name, ({type_manifest = Some tmanifest} as decl), _stamp) -> |
| 52 | + Some |
| 53 | + (Shared.declToString name decl |
| 54 | + ^ "\n\n" |
| 55 | + ^ Shared.typeToString tmanifest) |
| 56 | + | TypeDefinition (name, decl, _stamp) -> |
| 57 | + Some (Shared.declToString name decl) |
| 58 | + | LModule (Definition (stamp, _tip)) |
| 59 | + | LModule (LocalReference (stamp, _tip)) -> ( |
| 60 | + match Stamps.findModule file.stamps stamp with |
| 61 | + | None -> None |
| 62 | + | Some md -> ( |
| 63 | + match References.resolveModuleReference ~file ~package md with |
| 64 | + | None -> None |
| 65 | + | Some (file, declared) -> |
| 66 | + let name, docstring = |
| 67 | + match declared with |
| 68 | + | Some d -> (d.name.txt, d.docstring) |
| 69 | + | None -> (file.moduleName, file.structure.docstring) |
| 70 | + in |
| 71 | + showModule ~docstring ~name ~file declared ~package)) |
| 72 | + | LModule (GlobalReference (moduleName, path, tip)) -> ( |
| 73 | + match ProcessCmt.fileForModule ~package moduleName with |
| 74 | + | None -> None |
| 75 | + | Some file -> ( |
| 76 | + let env = QueryEnv.fromFile file in |
| 77 | + match References.exportedForTip ~env ~path ~package ~tip with |
| 78 | + | None -> None |
| 79 | + | Some (_env, _name, stamp) -> ( |
| 80 | + match Stamps.findModule file.stamps stamp with |
| 81 | + | None -> None |
| 82 | + | Some md -> ( |
| 83 | + match |
| 84 | + References.resolveModuleReference ~file ~package md |
| 85 | + with |
| 86 | + | None -> None |
| 87 | + | Some (file, declared) -> |
| 88 | + let name, docstring = |
| 89 | + match declared with |
| 90 | + | Some d -> (d.name.txt, d.docstring) |
| 91 | + | None -> (file.moduleName, file.structure.docstring) |
| 92 | + in |
| 93 | + showModule ~docstring ~name ~file ~package declared)))) |
| 94 | + | LModule NotFound -> None |
| 95 | + | TopLevelModule name -> ( |
| 96 | + match ProcessCmt.fileForModule ~package name with |
| 97 | + | None -> None |
| 98 | + | Some file -> |
| 99 | + showModule ~docstring:file.structure.docstring |
| 100 | + ~name:file.moduleName ~file ~package None) |
| 101 | + | Typed (name, t, _) -> |
| 102 | + let {TypeUtils.ExpandType.mainTypes; relatedTypes} = |
| 103 | + TypeUtils.ExpandType.expandTypes |
| 104 | + (TypeUtils.ExpandType.TypeExpr |
| 105 | + { |
| 106 | + typeExpr = t; |
| 107 | + name = Some (Location.mkloc name locItem.loc); |
| 108 | + env = QueryEnv.fromFile full.file; |
| 109 | + }) |
| 110 | + ~full |
| 111 | + in |
| 112 | + Some |
| 113 | + (Printf.sprintf |
| 114 | + "<main_types>\n\ |
| 115 | + %s\n\ |
| 116 | + </main_types>\n\n\ |
| 117 | + <related_types>\n\ |
| 118 | + %s\n\ |
| 119 | + </related_types>" |
| 120 | + (mainTypes |
| 121 | + |> List.map |
| 122 | + (fun (input : TypeUtils.ExpandType.expandTypeInput) -> |
| 123 | + match input with |
| 124 | + | TypeUtils.ExpandType.TypeExpr {typeExpr} -> |
| 125 | + Shared.typeToString typeExpr |
| 126 | + | TypeUtils.ExpandType.TypeDecl {name; typeDecl} -> |
| 127 | + Shared.declToString name.txt typeDecl) |
| 128 | + |> String.concat "\n\n") |
| 129 | + (relatedTypes |
| 130 | + |> List.map |
| 131 | + (fun (input : TypeUtils.ExpandType.expandTypeInput) -> |
| 132 | + match input with |
| 133 | + | TypeUtils.ExpandType.TypeExpr {typeExpr} -> |
| 134 | + Shared.typeToString typeExpr |
| 135 | + | TypeUtils.ExpandType.TypeDecl {name; typeDecl} -> |
| 136 | + Shared.declToString name.txt typeDecl) |
| 137 | + |> String.concat "\n\n")) |
| 138 | + | Constant t -> |
| 139 | + Some |
| 140 | + (match t with |
| 141 | + | Const_int _ -> "int" |
| 142 | + | Const_char _ -> "char" |
| 143 | + | Const_string _ -> "string" |
| 144 | + | Const_float _ -> "float" |
| 145 | + | Const_int32 _ -> "int32" |
| 146 | + | Const_int64 _ -> "int64" |
| 147 | + | Const_bigint _ -> "bigint"))) |
| 148 | + in |
| 149 | + match result with |
| 150 | + | None -> "No result." |
| 151 | + | Some s -> s |
| 152 | +end |
0 commit comments