123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- import {
- JSONArrayValue,
- JSONObjectMember,
- JSONObjectValue,
- JSONValue,
- } from "./jsonParse"
- type RootEntry =
- | {
- kind: "RootObject"
- astValue: JSONObjectValue
- }
- | {
- kind: "RootArray"
- astValue: JSONArrayValue
- }
- type ObjectMemberEntry = {
- kind: "ObjectMember"
- name: string
- astValue: JSONObjectMember
- astParent: JSONObjectValue
- }
- type ArrayMemberEntry = {
- kind: "ArrayMember"
- index: number
- astValue: JSONValue
- astParent: JSONArrayValue
- }
- type PathEntry = RootEntry | ObjectMemberEntry | ArrayMemberEntry
- export function getJSONOutlineAtPos(
- jsonRootAst: JSONObjectValue | JSONArrayValue,
- posIndex: number
- ): PathEntry[] | null {
- try {
- const rootObj = jsonRootAst
- if (posIndex > rootObj.end || posIndex < rootObj.start)
- throw new Error("Invalid position")
- let current: JSONValue = rootObj
- const path: PathEntry[] = []
- if (rootObj.kind === "Object") {
- path.push({
- kind: "RootObject",
- astValue: rootObj,
- })
- } else {
- path.push({
- kind: "RootArray",
- astValue: rootObj,
- })
- }
- while (current.kind === "Object" || current.kind === "Array") {
- if (current.kind === "Object") {
- const next: JSONObjectMember | undefined = current.members.find(
- (member) => member.start <= posIndex && member.end >= posIndex
- )
- if (!next) throw new Error("Couldn't find child")
- path.push({
- kind: "ObjectMember",
- name: next.key.value,
- astValue: next,
- astParent: current,
- })
- current = next.value
- } else {
- const nextIndex = current.values.findIndex(
- (value) => value.start <= posIndex && value.end >= posIndex
- )
- if (nextIndex < 0) throw new Error("Couldn't find child")
- const next: JSONValue = current.values[nextIndex]
- path.push({
- kind: "ArrayMember",
- index: nextIndex,
- astValue: next,
- astParent: current,
- })
- current = next
- }
- }
- return path
- } catch (e: any) {
- return null
- }
- }
|