-
-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 720a690
Showing
28 changed files
with
8,704 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
node_modules | ||
*.log* | ||
.nuxt | ||
.nitro | ||
.cache | ||
.output | ||
.env | ||
dist |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
shamefully-hoist = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"editor.formatOnSave": true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# AST Explorer |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<script setup lang="ts"> | ||
import { code } from '#imports' | ||
const language = computed(() => { | ||
if (typeof currentLanguage.value.language === 'string') { | ||
return currentLanguage.value.language | ||
} | ||
return currentLanguage.value.language(options.value) | ||
}) | ||
</script> | ||
|
||
<template> | ||
<main h-screen flex="~ col"> | ||
<NavBar mb-1 /> | ||
<div min-h-0 flex="~ gap3"> | ||
<CodeEditor | ||
v-model="code" | ||
:language="language" | ||
flex-1 | ||
max-w="50%" | ||
min-w="50%" | ||
/> | ||
<ASTViewer flex-1 /> | ||
</div> | ||
</main> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
<script setup lang="ts"> | ||
import { getHighlighter } from 'shikiji' | ||
import { hideEmptyKeys, hideLocationData } from '#imports' | ||
const Error = globalThis.Error | ||
let shiki = await getHighlighter({ | ||
themes: ['vitesse-dark', 'vitesse-light'], | ||
langs: ['json'], | ||
}) | ||
const html = computed(() => { | ||
return shiki.codeToHtml( | ||
JSON.stringify( | ||
ast.value, | ||
(key: string, value: unknown) => { | ||
if (hideEmptyKeys.value && value == null) return undefined | ||
if ( | ||
hideLocationData.value && | ||
['loc', 'start', 'end', ...hideKeys.value].includes(key) | ||
) | ||
return undefined | ||
if (typeof value === 'function') return `function ${value.name}(...)` | ||
return value | ||
}, | ||
2 | ||
), | ||
{ | ||
lang: 'json', | ||
theme: isDark.value ? 'vitesse-dark' : 'vitesse-light', | ||
} | ||
) | ||
}) | ||
const hideKeysValue = computed({ | ||
get() { | ||
return JSON.stringify(hideKeys.value) | ||
}, | ||
set(val) { | ||
hideKeys.value = JSON.parse(val) | ||
}, | ||
}) | ||
</script> | ||
|
||
<template> | ||
<div flex="~ col gap-2" min-w-0> | ||
<div flex="~ gap-2"> | ||
<label> | ||
<input type="checkbox" v-model="hideEmptyKeys" /> Hide empty keys | ||
</label> | ||
<label> | ||
<input type="checkbox" v-model="hideLocationData" /> Hide location data | ||
</label> | ||
<label> | ||
Hide keys: | ||
<input | ||
type="input" | ||
v-model="hideKeysValue" | ||
border="~ $c-border" | ||
px1 | ||
rounded | ||
/> | ||
</label> | ||
</div> | ||
<div v-if="error" text-red overflow-scroll> | ||
<pre v-text="error instanceof Error ? error.stack : error" /> | ||
</div> | ||
<div overflow-scroll v-else v-html="html" /> | ||
</div> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
<script setup lang="ts"> | ||
import * as monaco from 'monaco-editor' | ||
import { type MonacoEditor } from '#build/components' | ||
import { type MonacoLanguage } from '~/composables/language' | ||
defineProps<{ | ||
language: MonacoLanguage | ||
}>() | ||
const code = defineModel<string>() | ||
const editorRef = shallowRef<InstanceType<typeof MonacoEditor>>() | ||
const options = computed<monaco.editor.IStandaloneEditorConstructionOptions>( | ||
() => { | ||
return { | ||
automaticLayout: true, | ||
theme: isDark.value ? 'vs-dark' : 'vs', | ||
fontSize: 14, | ||
tabSize: 2, | ||
minimap: { | ||
enabled: false, | ||
}, | ||
} | ||
} | ||
) | ||
</script> | ||
|
||
<template> | ||
<MonacoEditor | ||
v-model="code" | ||
ref="editorRef" | ||
h-full | ||
:lang="language" | ||
:options="options" | ||
> | ||
<div flex="~ col gap-2" w-full h-full items-center justify-center> | ||
<div i-ri:loader-2-line animate-spin text-4xl></div> | ||
<span text-lg>Loading...</span> | ||
</div> | ||
</MonacoEditor> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
<script setup lang="ts"> | ||
const dialog = ref<HTMLDialogElement>() | ||
const value = ref( | ||
rawOptions.value || | ||
JSON.stringify(currentLanguage.value.options.defaultValue, null, 2) | ||
) | ||
function openDialog() { | ||
dialog.value?.showModal() | ||
} | ||
function handleDialogClick(evt: MouseEvent) { | ||
if (evt.target === evt.currentTarget) dialog.value?.close() | ||
} | ||
watchEffect(() => { | ||
rawOptions.value = value.value | ||
}) | ||
</script> | ||
|
||
<template> | ||
<div flex justify-center items-center> | ||
<button class="i-ri:settings-line" @click="openDialog" /> | ||
<dialog ref="dialog" rounded h-50vh p0 @click="handleDialogClick"> | ||
<div text-center text-lg py2 font-bold> | ||
Parser Options | ||
<button | ||
class="i-ri:close-line" | ||
p4 | ||
float-right | ||
@click="dialog?.close()" | ||
/> | ||
</div> | ||
<CodeEditor | ||
w-50vw | ||
v-model="value" | ||
:language="currentLanguage.options.language" | ||
/> | ||
</dialog> | ||
</div> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<script setup lang="ts"> | ||
import { type Language } from '~/composables/language' | ||
const changeLang = (language: Language) => { | ||
currentLanguageId.value = language | ||
} | ||
</script> | ||
|
||
<template> | ||
<VMenu :class="{ dark: isDark }" flex> | ||
<button flex="~ gap-1" items-center> | ||
<div :class="currentLanguage.icon" /> | ||
{{ currentLanguage.label }} | ||
</button> | ||
<template #popper> | ||
<CommonDropdownItem | ||
v-for="(lang, id) in LANGUAGES" | ||
:key="id" | ||
:icon="lang.icon" | ||
:text="lang.label" | ||
:checked="currentLanguageId === id" | ||
@click="changeLang(id)" | ||
/> | ||
</template> | ||
</VMenu> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<template> | ||
<div p2 flex justify-between items-center> | ||
<div flex="~ gap4"> | ||
<h1 font-bold text-lg>AST Viewer</h1> | ||
<LanguageSelect /> | ||
<LanguageOptions v-if="currentLanguage.options.configurable" /> | ||
</div> | ||
|
||
<button @click="toggleDark()"> | ||
<div i-ri:sun-line dark:i-ri:moon-line /> | ||
</button> | ||
</div> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<script setup lang="ts"> | ||
import { dropdownContextKey } from './ctx' | ||
defineProps<{ | ||
placement?: string | ||
}>() | ||
const dropdown = ref<any>() | ||
provide(dropdownContextKey, { | ||
hide: () => dropdown.value.hide(), | ||
}) | ||
</script> | ||
|
||
<template> | ||
<VDropdown | ||
v-bind="$attrs" | ||
ref="dropdown" | ||
:class="{ dark: isDark }" | ||
:placement="placement || 'auto'" | ||
> | ||
<slot /> | ||
<template #popper="scope"> | ||
<slot name="popper" v-bind="scope" /> | ||
</template> | ||
</VDropdown> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<script setup lang="ts"> | ||
import { dropdownContextKey } from './ctx' | ||
defineProps<{ | ||
text?: string | ||
description?: string | ||
icon?: string | ||
checked?: boolean | ||
}>() | ||
const emit = defineEmits(['click']) | ||
const { hide } = inject(dropdownContextKey, undefined) || {} | ||
const el = ref<HTMLDivElement>() | ||
const handleClick = (evt: MouseEvent) => { | ||
hide?.() | ||
emit('click', evt) | ||
} | ||
</script> | ||
|
||
<template> | ||
<div | ||
v-bind="$attrs" | ||
ref="el" | ||
flex | ||
gap-2 | ||
items-center | ||
cursor-pointer | ||
px3 | ||
py2 | ||
hover-bg-active | ||
:aria-label="text" | ||
@click="handleClick" | ||
> | ||
<div v-if="icon" :class="icon" /> | ||
<slot> | ||
{{ text }} | ||
</slot> | ||
|
||
<div v-if="checked" i-ri:check-line /> | ||
</div> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import type { InjectionKey } from 'vue' | ||
|
||
export const dropdownContextKey: InjectionKey<{ | ||
hide: () => void | ||
}> = Symbol('dropdownContextKey') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export const isDark = useDark() | ||
export const toggleDark = useToggle(isDark) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import json5 from 'json5' | ||
import * as monaco from 'monaco-editor' | ||
import { javascript } from './javascript' | ||
import { vue } from './vue' | ||
|
||
export type MonacoLanguage = 'javascript' | 'typescript' | 'json' | 'vue' | ||
export interface LanguageOption { | ||
label: string | ||
icon: string | ||
language: MonacoLanguage | ((options: any) => MonacoLanguage) | ||
options: { | ||
configurable: boolean | ||
defaultValue: any | ||
language: MonacoLanguage | ||
} | ||
parse(code: string, options: any): any | ||
} | ||
|
||
export const LANGUAGES = { | ||
javascript, | ||
vue, | ||
} | ||
export type Language = keyof typeof LANGUAGES | ||
|
||
export const currentLanguage = computed( | ||
() => LANGUAGES[currentLanguageId.value] || LANGUAGES.javascript | ||
) | ||
|
||
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({ | ||
allowComments: true, | ||
enableSchemaRequest: true, | ||
trailingCommas: 'ignore', | ||
}) | ||
|
||
watchEffect(async () => { | ||
try { | ||
ast.value = currentLanguage.value.parse( | ||
code.value, | ||
json5.parse(rawOptions.value) | ||
) | ||
error.value = null | ||
} catch (err) { | ||
error.value = err | ||
} | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { ParserOptions } from '@babel/parser' | ||
import { parse } from '@babel/parser' | ||
import { LanguageOption } from '../language' | ||
|
||
// @unocss-include | ||
export const javascript: LanguageOption = { | ||
label: 'JavaScript', | ||
icon: 'i-vscode-icons:file-type-js-official', | ||
language(options: ParserOptions | null | undefined) { | ||
const normalizedPlugins = (options?.plugins || []).map((item) => | ||
Array.isArray(item) ? item[0] : item | ||
) | ||
if (normalizedPlugins.includes('typescript')) return 'typescript' | ||
return 'javascript' | ||
}, | ||
options: { | ||
configurable: true, | ||
defaultValue: {}, | ||
language: 'json', | ||
}, | ||
parse(code, options: ParserOptions | null | undefined) { | ||
return parse(code, { | ||
sourceType: 'module', | ||
...options, | ||
}) | ||
}, | ||
} |
Oops, something went wrong.