Copy disabled (too large)
Download .txt
Showing preview only (12,185K chars total). Download the full file to get everything.
Repository: kishikawakatsumi/swift-ast-explorer
Branch: master
Commit: 4900091e62de
Files: 375
Total size: 11.4 MB
Directory structure:
gitextract_tk66xfku/
├── .dockerignore
├── .github/
│ ├── FUNDING.yml
│ ├── renovate.json
│ └── workflows/
│ ├── spm.yml
│ └── test.yml
├── .gitignore
├── .swiftpm/
│ └── xcode/
│ └── package.xcworkspace/
│ └── contents.xcworkspacedata
├── .vscode/
│ ├── launch.json
│ └── settings.json
├── CODE_OF_CONDUCT.md
├── DEPLOYMENT.md
├── Dockerfile
├── LICENSE
├── Package.resolved
├── Package.swift
├── Public/
│ ├── css/
│ │ ├── balloon.css
│ │ ├── common.css
│ │ ├── editor.css
│ │ ├── lookup.css
│ │ ├── popover.css
│ │ ├── table.css
│ │ ├── tree_view.css
│ │ └── trivia.css
│ ├── error.html
│ ├── favicons/
│ │ ├── browserconfig.xml
│ │ └── site.webmanifest
│ ├── index.html
│ ├── index.js
│ ├── js/
│ │ ├── app.js
│ │ ├── balloon.js
│ │ ├── debounce.js
│ │ ├── editor.js
│ │ ├── icon.js
│ │ ├── lookup_view.js
│ │ ├── popover.js
│ │ ├── statistics_view.js
│ │ ├── structure_view.js
│ │ ├── tree_view.js
│ │ ├── trivia_view.js
│ │ └── websocket.js
│ ├── robots.txt
│ └── scss/
│ └── default.scss
├── README.md
├── Resources/
│ └── parsers/
│ ├── 50800/
│ │ ├── .swiftpm/
│ │ │ └── xcode/
│ │ │ └── package.xcworkspace/
│ │ │ └── contents.xcworkspacedata
│ │ ├── Package.resolved
│ │ ├── Package.swift
│ │ ├── Sources/
│ │ │ └── parser/
│ │ │ ├── Main.swift
│ │ │ ├── SyntaxParser.swift
│ │ │ ├── SyntaxResponse.swift
│ │ │ ├── TokenVisitor.swift
│ │ │ ├── TreeNode.swift
│ │ │ └── Version.swift
│ │ └── Tests/
│ │ └── Tests/
│ │ ├── Fixtures/
│ │ │ ├── test-1-1.html
│ │ │ ├── test-1-1.json
│ │ │ ├── test-1-2.html
│ │ │ ├── test-1-2.json
│ │ │ ├── test-1-3.html
│ │ │ ├── test-1-3.json
│ │ │ ├── test-1-4.html
│ │ │ ├── test-1-4.json
│ │ │ ├── test-1-5.html
│ │ │ ├── test-1-5.json
│ │ │ ├── test-1-6.html
│ │ │ ├── test-1-6.json
│ │ │ ├── test-2-1.html
│ │ │ ├── test-2-1.json
│ │ │ ├── test-2-2.html
│ │ │ ├── test-2-2.json
│ │ │ ├── test-2-3.html
│ │ │ ├── test-2-3.json
│ │ │ ├── test-2-4.html
│ │ │ ├── test-2-4.json
│ │ │ ├── test-2-5.html
│ │ │ ├── test-2-5.json
│ │ │ ├── test-2-6.html
│ │ │ └── test-2-6.json
│ │ └── Tests.swift
│ ├── 50900/
│ │ ├── .swiftpm/
│ │ │ └── xcode/
│ │ │ └── package.xcworkspace/
│ │ │ └── contents.xcworkspacedata
│ │ ├── Package.resolved
│ │ ├── Package.swift
│ │ ├── Sources/
│ │ │ └── parser/
│ │ │ ├── SyntaxParser.swift
│ │ │ ├── TokenVisitor.swift
│ │ │ └── Version.swift
│ │ └── Tests/
│ │ └── Tests/
│ │ └── Fixtures/
│ │ ├── test-1-1.html
│ │ ├── test-1-1.json
│ │ ├── test-1-2.html
│ │ ├── test-1-2.json
│ │ ├── test-1-3.html
│ │ ├── test-1-3.json
│ │ ├── test-1-4.html
│ │ ├── test-1-4.json
│ │ ├── test-1-5.html
│ │ ├── test-1-5.json
│ │ ├── test-1-6.html
│ │ ├── test-1-6.json
│ │ ├── test-2-1.html
│ │ ├── test-2-1.json
│ │ ├── test-2-2.html
│ │ ├── test-2-2.json
│ │ ├── test-2-3.html
│ │ ├── test-2-3.json
│ │ ├── test-2-4.html
│ │ ├── test-2-4.json
│ │ ├── test-2-5.html
│ │ ├── test-2-5.json
│ │ ├── test-2-6.html
│ │ └── test-2-6.json
│ ├── 51000/
│ │ ├── .swiftpm/
│ │ │ └── xcode/
│ │ │ └── package.xcworkspace/
│ │ │ └── contents.xcworkspacedata
│ │ ├── Package.resolved
│ │ ├── Package.swift
│ │ ├── Sources/
│ │ │ └── parser/
│ │ │ └── Version.swift
│ │ └── Tests/
│ │ └── Tests/
│ │ └── Fixtures/
│ │ ├── test-1-1.html
│ │ ├── test-1-1.json
│ │ ├── test-1-2.html
│ │ ├── test-1-2.json
│ │ ├── test-1-3.html
│ │ ├── test-1-3.json
│ │ ├── test-1-4.html
│ │ ├── test-1-4.json
│ │ ├── test-1-5.html
│ │ ├── test-1-5.json
│ │ ├── test-1-6.html
│ │ ├── test-1-6.json
│ │ ├── test-2-1.html
│ │ ├── test-2-1.json
│ │ ├── test-2-2.html
│ │ ├── test-2-2.json
│ │ ├── test-2-3.html
│ │ ├── test-2-3.json
│ │ ├── test-2-4.html
│ │ ├── test-2-4.json
│ │ ├── test-2-5.html
│ │ ├── test-2-5.json
│ │ ├── test-2-6.html
│ │ └── test-2-6.json
│ ├── 60000/
│ │ ├── Package.resolved
│ │ ├── Package.swift
│ │ ├── Sources/
│ │ │ └── parser/
│ │ │ └── Version.swift
│ │ └── Tests/
│ │ └── Tests/
│ │ └── Fixtures/
│ │ ├── test-1-1.html
│ │ ├── test-1-1.json
│ │ ├── test-1-2.html
│ │ ├── test-1-2.json
│ │ ├── test-1-3.html
│ │ ├── test-1-3.json
│ │ ├── test-1-4.html
│ │ ├── test-1-4.json
│ │ ├── test-1-5.html
│ │ ├── test-1-5.json
│ │ ├── test-1-6.html
│ │ ├── test-1-6.json
│ │ ├── test-2-1.html
│ │ ├── test-2-1.json
│ │ ├── test-2-2.html
│ │ ├── test-2-2.json
│ │ ├── test-2-3.html
│ │ ├── test-2-3.json
│ │ ├── test-2-4.html
│ │ ├── test-2-4.json
│ │ ├── test-2-5.html
│ │ ├── test-2-5.json
│ │ ├── test-2-6.html
│ │ └── test-2-6.json
│ ├── 60100/
│ │ ├── .swiftpm/
│ │ │ └── xcode/
│ │ │ └── package.xcworkspace/
│ │ │ └── contents.xcworkspacedata
│ │ ├── Package.resolved
│ │ ├── Package.swift
│ │ ├── Sources/
│ │ │ └── parser/
│ │ │ └── Version.swift
│ │ └── Tests/
│ │ └── Tests/
│ │ └── Fixtures/
│ │ ├── test-1-1.html
│ │ ├── test-1-1.json
│ │ ├── test-1-2.html
│ │ ├── test-1-2.json
│ │ ├── test-1-3.html
│ │ ├── test-1-3.json
│ │ ├── test-1-4.html
│ │ ├── test-1-4.json
│ │ ├── test-1-5.html
│ │ ├── test-1-5.json
│ │ ├── test-1-6.html
│ │ ├── test-1-6.json
│ │ ├── test-2-1.html
│ │ ├── test-2-1.json
│ │ ├── test-2-2.html
│ │ ├── test-2-2.json
│ │ ├── test-2-3.html
│ │ ├── test-2-3.json
│ │ ├── test-2-4.html
│ │ ├── test-2-4.json
│ │ ├── test-2-5.html
│ │ ├── test-2-5.json
│ │ ├── test-2-6.html
│ │ └── test-2-6.json
│ ├── 60200/
│ │ ├── .swiftpm/
│ │ │ └── xcode/
│ │ │ └── package.xcworkspace/
│ │ │ └── contents.xcworkspacedata
│ │ ├── Package.resolved
│ │ ├── Package.swift
│ │ ├── Sources/
│ │ │ └── parser/
│ │ │ └── Version.swift
│ │ └── Tests/
│ │ └── Tests/
│ │ └── Fixtures/
│ │ ├── test-1-1.html
│ │ ├── test-1-1.json
│ │ ├── test-1-2.html
│ │ ├── test-1-2.json
│ │ ├── test-1-3.html
│ │ ├── test-1-3.json
│ │ ├── test-1-4.html
│ │ ├── test-1-4.json
│ │ ├── test-1-5.html
│ │ ├── test-1-5.json
│ │ ├── test-1-6.html
│ │ ├── test-1-6.json
│ │ ├── test-2-1.html
│ │ ├── test-2-1.json
│ │ ├── test-2-2.html
│ │ ├── test-2-2.json
│ │ ├── test-2-3.html
│ │ ├── test-2-3.json
│ │ ├── test-2-4.html
│ │ ├── test-2-4.json
│ │ ├── test-2-5.html
│ │ ├── test-2-5.json
│ │ ├── test-2-6.html
│ │ └── test-2-6.json
│ ├── 60300/
│ │ ├── .swiftpm/
│ │ │ └── xcode/
│ │ │ └── package.xcworkspace/
│ │ │ └── contents.xcworkspacedata
│ │ ├── Package.resolved
│ │ ├── Package.swift
│ │ ├── Sources/
│ │ │ └── parser/
│ │ │ └── Version.swift
│ │ └── Tests/
│ │ └── Tests/
│ │ └── Fixtures/
│ │ ├── test-1-1.html
│ │ ├── test-1-1.json
│ │ ├── test-1-2.html
│ │ ├── test-1-2.json
│ │ ├── test-1-3.html
│ │ ├── test-1-3.json
│ │ ├── test-1-4.html
│ │ ├── test-1-4.json
│ │ ├── test-1-5.html
│ │ ├── test-1-5.json
│ │ ├── test-1-6.html
│ │ ├── test-1-6.json
│ │ ├── test-2-1.html
│ │ ├── test-2-1.json
│ │ ├── test-2-2.html
│ │ ├── test-2-2.json
│ │ ├── test-2-3.html
│ │ ├── test-2-3.json
│ │ ├── test-2-4.html
│ │ ├── test-2-4.json
│ │ ├── test-2-5.html
│ │ ├── test-2-5.json
│ │ ├── test-2-6.html
│ │ └── test-2-6.json
│ └── trunk/
│ ├── .swiftpm/
│ │ └── xcode/
│ │ └── package.xcworkspace/
│ │ └── contents.xcworkspacedata
│ ├── Package.resolved
│ ├── Package.swift
│ ├── Sources/
│ │ └── parser/
│ │ └── Version.swift
│ └── Tests/
│ └── Tests/
│ └── Fixtures/
│ ├── test-1-1.html
│ ├── test-1-1.json
│ ├── test-1-2.html
│ ├── test-1-2.json
│ ├── test-1-3.html
│ ├── test-1-3.json
│ ├── test-1-4.html
│ ├── test-1-4.json
│ ├── test-1-5.html
│ ├── test-1-5.json
│ ├── test-1-6.html
│ ├── test-1-6.json
│ ├── test-2-1.html
│ ├── test-2-1.json
│ ├── test-2-2.html
│ ├── test-2-2.json
│ ├── test-2-3.html
│ ├── test-2-3.json
│ ├── test-2-4.html
│ ├── test-2-4.json
│ ├── test-2-5.html
│ ├── test-2-5.json
│ ├── test-2-6.html
│ └── test-2-6.json
├── SECURITY.md
├── Sources/
│ └── App/
│ ├── Middlewares/
│ │ ├── CommonErrorMiddleware.swift
│ │ └── CustomHeaderMiddleware.swift
│ ├── configure.swift
│ ├── entrypoint.swift
│ └── routes.swift
├── Tests/
│ └── AppTests/
│ └── AppTests.swift
├── build_pasers.sh
├── deploy/
│ └── Dockerfile
├── dev/
│ ├── .gitignore
│ ├── index.js
│ ├── package.json
│ └── xml-formatter/
│ ├── .eslintignore
│ ├── .eslintrc.json
│ ├── .gitignore
│ ├── .npmignore
│ ├── LICENSE
│ ├── README.md
│ ├── package.json
│ ├── publish.sh
│ ├── src/
│ │ ├── index.d.ts
│ │ └── index.ts
│ ├── test/
│ │ ├── .eslintrc.json
│ │ ├── browser/
│ │ │ ├── README.md
│ │ │ └── index.html
│ │ ├── data1/
│ │ │ ├── xml1-input.xml
│ │ │ ├── xml1-output.xml
│ │ │ ├── xml2-input.xml
│ │ │ ├── xml2-output.xml
│ │ │ ├── xml3-input.xml
│ │ │ ├── xml3-output.xml
│ │ │ ├── xml4-input.xml
│ │ │ └── xml4-output.xml
│ │ ├── data10/
│ │ │ ├── xml1-input.xml
│ │ │ └── xml1-output.xml
│ │ ├── data11/
│ │ │ ├── xml1-input.xml
│ │ │ ├── xml1-output.xml
│ │ │ ├── xml2-input.xml
│ │ │ └── xml2-output.xml
│ │ ├── data12/
│ │ │ ├── xml1-input.xml
│ │ │ └── xml1-output.xml
│ │ ├── data13/
│ │ │ ├── xml1-input.xml
│ │ │ └── xml1-output.xml
│ │ ├── data14/
│ │ │ ├── xml1-input.xml
│ │ │ └── xml1-output.xml
│ │ ├── data2/
│ │ │ ├── xml1-input.xml
│ │ │ ├── xml1-output.xml
│ │ │ ├── xml2-input.xml
│ │ │ ├── xml2-output.xml
│ │ │ ├── xml3-input.xml
│ │ │ ├── xml3-output.xml
│ │ │ ├── xml4-input.xml
│ │ │ └── xml4-output.xml
│ │ ├── data3/
│ │ │ ├── xml1-input.xml
│ │ │ ├── xml1-output.xml
│ │ │ ├── xml2-input.xml
│ │ │ ├── xml2-output.xml
│ │ │ ├── xml3-input.xml
│ │ │ ├── xml3-output.xml
│ │ │ ├── xml4-input.xml
│ │ │ ├── xml4-output.xml
│ │ │ ├── xml5-input.xml
│ │ │ ├── xml5-output.xml
│ │ │ ├── xml6-input.xml
│ │ │ ├── xml6-output.xml
│ │ │ ├── xml7-input.xml
│ │ │ └── xml7-output.xml
│ │ ├── data4/
│ │ │ ├── xml1-input.xml
│ │ │ ├── xml1-output.xml
│ │ │ ├── xml2-input.xml
│ │ │ ├── xml2-output.xml
│ │ │ ├── xml3-input.xml
│ │ │ ├── xml3-output.xml
│ │ │ ├── xml4-input.xml
│ │ │ ├── xml4-output.xml
│ │ │ ├── xml5-input.xml
│ │ │ └── xml5-output.xml
│ │ ├── data5/
│ │ │ ├── xml1-input.xml
│ │ │ └── xml1-output.xml
│ │ ├── data6/
│ │ │ ├── xml1-input.xml
│ │ │ ├── xml1-output.xml
│ │ │ ├── xml2-input.xml
│ │ │ └── xml2-output.xml
│ │ ├── data7/
│ │ │ ├── xml1-input.xml
│ │ │ └── xml1-output.xml
│ │ ├── data8/
│ │ │ ├── xml1-input.xml
│ │ │ └── xml1-output.xml
│ │ ├── data9/
│ │ │ ├── xml1-input.xml
│ │ │ ├── xml1-output.xml
│ │ │ ├── xml2-input.xml
│ │ │ ├── xml2-output.xml
│ │ │ ├── xml3-input.xml
│ │ │ ├── xml3-output.xml
│ │ │ ├── xml4-input.xml
│ │ │ └── xml4-output.xml
│ │ └── index.ts
│ └── tsconfig.json
├── package.json
├── webpack.common.js
├── webpack.dev.js
└── webpack.prod.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .dockerignore
================================================
.build/
.swiftpm/
================================================
FILE: .github/FUNDING.yml
================================================
github: kishikawakatsumi
================================================
FILE: .github/renovate.json
================================================
{
"extends": [
"config:recommended"
],
"packageRules": [
{
"matchUpdateTypes": [
"minor",
"patch",
"pin",
"digest"
],
"automerge": true
}
]
}
================================================
FILE: .github/workflows/spm.yml
================================================
name: Update Swift Package
on:
schedule:
- cron: "30 22 * * *"
workflow_dispatch:
jobs:
update:
runs-on: ubuntu-24.04
steps:
- name: Checkout to the branch
uses: actions/checkout@v6
- name: Update Swift Package
run: |
set -ex
export TOOLCHAINS=swift
swift package update --package-path ./
swift package update --package-path Resources/parsers/50800
swift package update --package-path Resources/parsers/50900
swift package update --package-path Resources/parsers/51000
swift package update --package-path Resources/parsers/60000
swift package update --package-path Resources/parsers/trunk
- name: Create Pull Request
id: cpr
uses: peter-evans/create-pull-request@v8
with:
token: ${{ secrets.GH_PAT }}
base: "master"
commit-message: "Update Swift Packages"
title: "Update Swift Packages"
add-paths: |
Package.resolved
**/Package.resolved
- name: Enable Pull Request Automerge
if: ${{ steps.cpr.outputs.pull-request-url }}
run: gh pr merge --merge --auto ${{ steps.cpr.outputs.pull-request-url }}
env:
GH_TOKEN: ${{ secrets.GH_PAT }}
================================================
FILE: .github/workflows/test.yml
================================================
name: Test
on:
pull_request:
branches: [master]
workflow_dispatch:
env:
FONTAWESOME_TOKEN: ${{ secrets.FONTAWESOME_TOKEN }}
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Free Disk Space (Ubuntu)
uses: jlumbroso/free-disk-space@main
- name: Test
run: |
set -ex
swift test
(cd Resources/parsers/50800 && swift test)
(cd Resources/parsers/50900 && swift test)
(cd Resources/parsers/51000 && swift test)
(cd Resources/parsers/60000 && swift test)
(cd Resources/parsers/60100 && swift test)
(cd Resources/parsers/60200 && swift test)
(cd Resources/parsers/trunk && swift test)
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Login to Docker Hub
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
run: |
set -ex
IMAGE_TAG=swiftfiddle/swift-ast-explorer.com:latest
docker build --rm --no-cache --build-arg FONTAWESOME_TOKEN=${{ env.FONTAWESOME_TOKEN }} --tag ${IMAGE_TAG} .
docker push ${IMAGE_TAG}
================================================
FILE: .gitignore
================================================
### https://raw.github.com/github/gitignore/991e760c1c6d50fdda246e0178b9c58b06770b90/Global/macOS.gitignore
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### https://raw.github.com/github/gitignore/991e760c1c6d50fdda246e0178b9c58b06770b90/Swift.gitignore
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
## User settings
xcuserdata/
## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
*.xcscmblueprint
*.xccheckout
## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
build/
DerivedData/
*.moved-aside
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
## Obj-C/Swift specific
*.hmap
## App packaging
*.ipa
*.dSYM.zip
*.dSYM
## Playgrounds
timeline.xctimeline
playground.xcworkspace
# Swift Package Manager
#
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
# Packages/
# Package.pins
# Package.resolved
# *.xcodeproj
#
# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
# hence it is not needed unless you have added a package configuration file to your project
# .swiftpm
.build/
# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
# Pods/
#
# Add this line if you want to avoid checking in source code from the Xcode workspace
# *.xcworkspace
# Carthage
#
# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts
Carthage/Build/
# Accio dependency management
Dependencies/
.accio/
# fastlane
#
# It is recommended to not store the screenshots in the git repo.
# Instead, use fastlane to re-generate the screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/#source-control
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots/**/*.png
fastlane/test_output
# Code Injection
#
# After new code Injection tools there's a generated folder /iOSInjectionProject
# https://github.com/johnno1962/injectionforxcode
iOSInjectionProject/
### https://raw.github.com/github/gitignore/991e760c1c6d50fdda246e0178b9c58b06770b90/Node.gitignore
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
.env.production
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
================================================
FILE: .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
================================================
FILE: .vscode/launch.json
================================================
{
"configurations": [
{
"type": "swift",
"request": "launch",
"sourceLanguages": ["swift"],
"name": "Debug App",
"program": "${workspaceFolder:swift-ast-explorer}/.build/debug/App",
"args": [],
"cwd": "${workspaceFolder:swift-ast-explorer}",
"preLaunchTask": "swift: Build Debug App"
},
{
"type": "swift",
"request": "launch",
"sourceLanguages": ["swift"],
"name": "Release App",
"program": "${workspaceFolder:swift-ast-explorer}/.build/release/App",
"args": [],
"cwd": "${workspaceFolder:swift-ast-explorer}",
"preLaunchTask": "swift: Build Release App"
}
]
}
================================================
FILE: .vscode/settings.json
================================================
{
"lldb.library": "/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/LLDB",
"lldb.launch.expressions": "native"
}
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
- Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
- The use of sexualized language or imagery, and sexual attention or
advances of any kind
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email
address, without their explicit permission
- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
[@kishikawakatsumi](https://github.com/kishikawakatsumi).
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.
================================================
FILE: DEPLOYMENT.md
================================================
# Deployment Instructions
## Prerequisites
Before deploying, make sure you have the following software installed on your machine:
- Node.js (v14 or newer)
- Docker (v20.10 or newer)
The following environment variables are used for deployment:
- `FONTAWESOME_TOKEN`: This token is used for authentication with the FontAwesome service. You need to obtain a valid token from your FontAwesome account and use it here. Please make sure not to expose this token publicly.
## Local Deployment
### Steps:
1. Install the dependencies:
```bash
npm install
```
2. Run Webpack to build the project:
```bash
npm run prod
```
3. Run the application:
```bash
swift run
```
You should now be able to see the application running at `localhost:8080`.
## Production Deployment
For deploying to production, we recommend using [Railway](https://railway.app/). Railway is a platform that allows you to deploy your application to the cloud with ease. It also provides a free tier that is sufficient for deploying this application.
================================================
FILE: Dockerfile
================================================
FROM node:lts-slim as node
WORKDIR /build
ARG FONTAWESOME_TOKEN
COPY package*.json ./
RUN echo "@fortawesome:registry=https://npm.fontawesome.com/\n//npm.fontawesome.com/:_authToken=${FONTAWESOME_TOKEN}" > ./.npmrc \
&& npm ci \
&& rm -f ./.npmrc
COPY webpack.*.js ./
COPY Public ./Public/
RUN npx webpack --config webpack.prod.js
FROM swift:6.3-jammy as swift
RUN export DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true \
&& apt-get -q update \
&& apt-get -q dist-upgrade -y\
&& rm -rf /var/lib/apt/lists/*
WORKDIR /build
COPY --from=node /build /build
COPY ./Package.* ./
RUN swift package resolve
COPY . .
RUN swift build -c release --static-swift-stdlib
RUN swift build -c release --static-swift-stdlib --package-path Resources/parsers/50800
RUN swift build -c release --static-swift-stdlib --package-path Resources/parsers/50900
RUN swift build -c release --static-swift-stdlib --package-path Resources/parsers/51000
RUN swift build -c release --static-swift-stdlib --package-path Resources/parsers/60000
RUN swift build -c release --static-swift-stdlib --package-path Resources/parsers/60100
RUN swift build -c release --static-swift-stdlib --package-path Resources/parsers/60200
RUN swift build -c release --static-swift-stdlib --package-path Resources/parsers/60300
RUN swift build -c release --static-swift-stdlib --package-path Resources/parsers/trunk
WORKDIR /staging
RUN cp "$(swift build --package-path /build -c release --show-bin-path)/App" ./
RUN find -L "$(swift build --package-path /build -c release --show-bin-path)/" -regex '.*\.resources$' -exec cp -Ra {} ./ \;
RUN [ -d /build/Public ] && { mv /build/Public ./Public && chmod -R a-w ./Public; } || true
RUN [ -d /build/Resources ] && { mv /build/Resources ./Resources && chmod -R a-w ./Resources; } || true
FROM ubuntu:noble
RUN export DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true \
&& apt-get -q update \
&& apt-get -q dist-upgrade -y \
&& apt-get -q install -y \
ca-certificates \
tzdata \
&& rm -r /var/lib/apt/lists/*
RUN useradd --user-group --create-home --system --skel /dev/null --home-dir /app vapor
WORKDIR /app
COPY --from=swift --chown=vapor:vapor /staging /app
USER vapor:vapor
EXPOSE $PORT
ENTRYPOINT ["./App"]
CMD ["serve", "--env", "production", "--hostname", "0.0.0.0"]
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: Package.resolved
================================================
{
"pins" : [
{
"identity" : "async-http-client",
"kind" : "remoteSourceControl",
"location" : "https://github.com/swift-server/async-http-client.git",
"state" : {
"revision" : "3a5b74a58782c3b4c1f0bc75e9b67b10c2494e8f",
"version" : "1.33.1"
}
},
{
"identity" : "async-kit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/vapor/async-kit.git",
"state" : {
"revision" : "6bbb83cbf9d886623a967a965c8fb1b73e6566f9",
"version" : "1.22.0"
}
},
{
"identity" : "console-kit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/vapor/console-kit.git",
"state" : {
"revision" : "32ad16dfc7677b927b225595ed18f3debb32f577",
"version" : "4.16.0"
}
},
{
"identity" : "leaf",
"kind" : "remoteSourceControl",
"location" : "https://github.com/vapor/leaf.git",
"state" : {
"revision" : "b70a6108e4917f338f6b8848407bf655aa7e405f",
"version" : "4.5.1"
}
},
{
"identity" : "leaf-kit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/vapor/leaf-kit.git",
"state" : {
"revision" : "6044b844caa858a0c5f2505ac166f5a057c990dc",
"version" : "1.14.2"
}
},
{
"identity" : "multipart-kit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/vapor/multipart-kit.git",
"state" : {
"revision" : "3498e60218e6003894ff95192d756e238c01f44e",
"version" : "4.7.1"
}
},
{
"identity" : "routing-kit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/vapor/routing-kit.git",
"state" : {
"revision" : "1a10ccea61e4248effd23b6e814999ce7bdf0ee0",
"version" : "4.9.3"
}
},
{
"identity" : "swift-algorithms",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-algorithms.git",
"state" : {
"revision" : "87e50f483c54e6efd60e885f7f5aa946cee68023",
"version" : "1.2.1"
}
},
{
"identity" : "swift-asn1",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-asn1.git",
"state" : {
"revision" : "eb50cbd14606a9161cbc5d452f18797c90ef0bab",
"version" : "1.7.0"
}
},
{
"identity" : "swift-async-algorithms",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-async-algorithms.git",
"state" : {
"revision" : "9d349bcc328ac3c31ce40e746b5882742a0d1272",
"version" : "1.1.3"
}
},
{
"identity" : "swift-atomics",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-atomics.git",
"state" : {
"revision" : "b601256eab081c0f92f059e12818ac1d4f178ff7",
"version" : "1.3.0"
}
},
{
"identity" : "swift-certificates",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-certificates.git",
"state" : {
"revision" : "bde8ca32a096825dfce37467137c903418c1893d",
"version" : "1.19.1"
}
},
{
"identity" : "swift-collections",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-collections.git",
"state" : {
"revision" : "6675bc0ff86e61436e615df6fc5174e043e57924",
"version" : "1.4.1"
}
},
{
"identity" : "swift-configuration",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-configuration.git",
"state" : {
"revision" : "be76c4ad929eb6c4bcaf3351799f2adf9e6848a9",
"version" : "1.2.0"
}
},
{
"identity" : "swift-crypto",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-crypto.git",
"state" : {
"revision" : "1b6b2e274e85105bfa155183145a1dcfd63331f1",
"version" : "4.5.0"
}
},
{
"identity" : "swift-distributed-tracing",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-distributed-tracing.git",
"state" : {
"revision" : "dc4030184203ffafbb2ec614352487235d747fe0",
"version" : "1.4.1"
}
},
{
"identity" : "swift-http-structured-headers",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-http-structured-headers.git",
"state" : {
"revision" : "933538faa42c432d385f02e07df0ace7c5ecfc47",
"version" : "1.7.0"
}
},
{
"identity" : "swift-http-types",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-http-types.git",
"state" : {
"revision" : "45eb0224913ea070ec4fba17291b9e7ecf4749ca",
"version" : "1.5.1"
}
},
{
"identity" : "swift-log",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-log.git",
"state" : {
"revision" : "5073617dac96330a486245e4c0179cb0a6fd2256",
"version" : "1.12.0"
}
},
{
"identity" : "swift-metrics",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-metrics.git",
"state" : {
"revision" : "d51c8d13fa366eec807eedb4e37daa60ff5bfdd5",
"version" : "2.10.1"
}
},
{
"identity" : "swift-nio",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio.git",
"state" : {
"revision" : "f71c8d2a5e74a2c6d11a0fbe324774b5d6084237",
"version" : "2.99.0"
}
},
{
"identity" : "swift-nio-extras",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-extras.git",
"state" : {
"revision" : "5a48717e29f62cb8326d6d42e46b562ca93847a6",
"version" : "1.34.0"
}
},
{
"identity" : "swift-nio-http2",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-http2.git",
"state" : {
"revision" : "81cc18264f92cd307ff98430f89372711d4f6fe9",
"version" : "1.43.0"
}
},
{
"identity" : "swift-nio-ssl",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-ssl.git",
"state" : {
"revision" : "3f337058ccd7243c4cac7911477d8ad4c598d4da",
"version" : "2.37.0"
}
},
{
"identity" : "swift-nio-transport-services",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-transport-services.git",
"state" : {
"revision" : "67787bb645a5e67d2edcdfbe48a216cc549222d5",
"version" : "1.28.0"
}
},
{
"identity" : "swift-numerics",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-numerics.git",
"state" : {
"revision" : "0c0290ff6b24942dadb83a929ffaaa1481df04a2",
"version" : "1.1.1"
}
},
{
"identity" : "swift-service-context",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-service-context.git",
"state" : {
"revision" : "d0997351b0c7779017f88e7a93bc30a1878d7f29",
"version" : "1.3.0"
}
},
{
"identity" : "swift-service-lifecycle",
"kind" : "remoteSourceControl",
"location" : "https://github.com/swift-server/swift-service-lifecycle.git",
"state" : {
"revision" : "9829955b385e5bb88128b73f1b8389e9b9c3191a",
"version" : "2.11.0"
}
},
{
"identity" : "swift-system",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-system.git",
"state" : {
"revision" : "7c6ad0fc39d0763e0b699210e4124afd5041c5df",
"version" : "1.6.4"
}
},
{
"identity" : "swift-tools-support-core",
"kind" : "remoteSourceControl",
"location" : "https://github.com/swiftlang/swift-tools-support-core",
"state" : {
"revision" : "e8fbc8b05a155f311b862178d92d043afb216fe3",
"version" : "0.7.3"
}
},
{
"identity" : "vapor",
"kind" : "remoteSourceControl",
"location" : "https://github.com/vapor/vapor.git",
"state" : {
"revision" : "cfd8f434843ac7850e2d97f46c1aa5ddb906cf1c",
"version" : "4.121.4"
}
},
{
"identity" : "websocket-kit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/vapor/websocket-kit.git",
"state" : {
"revision" : "90bbbdab3ede12c803cfbe91646f291c092517a3",
"version" : "2.16.2"
}
}
],
"version" : 2
}
================================================
FILE: Package.swift
================================================
// swift-tools-version:5.8
import PackageDescription
let package = Package(
name: "swift-ast-explorer",
platforms: [
.macOS(.v13)
],
dependencies: [
.package(url: "https://github.com/vapor/vapor.git", from: "4.121.4"),
.package(url: "https://github.com/vapor/leaf.git", from: "4.5.1"),
.package(url: "https://github.com/swiftlang/swift-tools-support-core", from: "0.7.3"),
],
targets: [
.executableTarget(
name: "App",
dependencies: [
.product(name: "Vapor", package: "vapor"),
.product(name: "Leaf", package: "leaf"),
.product(name: "TSCBasic", package: "swift-tools-support-core"),
],
swiftSettings: [
.unsafeFlags(["-cross-module-optimization"], .when(configuration: .release))
]
),
.testTarget(
name: "AppTests",
dependencies: [
.target(name: "App"),
.product(name: "XCTVapor", package: "vapor"),
]
)
]
)
================================================
FILE: Public/css/balloon.css
================================================
.balloon {
font-size: 80%;
white-space: nowrap;
border-radius: 4px;
background-color: rgba(85, 85, 85, 0.9);
color: #fff;
padding: 2px 10px;
position: absolute;
z-index: 1080;
}
.balloon.top::after {
content: " ";
position: absolute;
top: 100%;
left: 24%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
border-color: rgba(85, 85, 85, 0.9) transparent transparent transparent;
}
.balloon.bottom::after {
content: " ";
position: absolute;
bottom: 100%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
border-color: transparent transparent rgba(85, 85, 85, 0.9) transparent;
}
.balloon.right::after {
content: " ";
position: absolute;
top: 50%;
right: 100%;
margin-top: -5px;
border-width: 5px;
border-style: solid;
border-color: transparent rgba(85, 85, 85, 0.9) transparent transparent;
}
.balloon.left::after {
content: " ";
position: absolute;
top: 50%;
left: 100%;
margin-top: -5px;
border-width: 5px;
border-style: solid;
border-color: transparent transparent transparent rgba(85, 85, 85, 0.9);
}
.balloon .title {
color: #fff;
font-weight: bolder;
display: inline-block;
}
.balloon .token-kind {
color: #fff;
font-weight: normal;
font-family: Menlo, Consolas, "DejaVu Sans Mono", "Ubuntu Mono", monospace;
max-width: 200px;
display: inline-block;
vertical-align: bottom;
}
.balloon .range {
color: #dcdcdc;
font-family: Menlo, Consolas, "DejaVu Sans Mono", "Ubuntu Mono", monospace;
}
================================================
FILE: Public/css/common.css
================================================
.svg-inline--fa.fa-fw {
width: 1em;
}
.nav-tabs {
border-bottom: none;
}
.dropdown-menu {
min-width: 260px;
line-height: 1.2;
font-feature-settings: "tnum";
}
.active-tick a::after {
display: block;
width: 14px;
height: 10px;
margin-top: 4px;
margin-bottom: 4px;
background-image: url("../images/check-solid.svg");
background-repeat: no-repeat;
content: "";
float: right;
}
.tab-pane {
overflow: auto;
}
#lookup-container {
font-family: Menlo, Consolas, "DejaVu Sans Mono", "Ubuntu Mono", monospace;
font-size: 11pt;
line-height: 1.4;
}
#trivia-container {
font-family: Menlo, Consolas, "DejaVu Sans Mono", "Ubuntu Mono", monospace;
font-size: 11pt;
line-height: 1.4;
}
.alert {
font-family: Menlo, Consolas, "DejaVu Sans Mono", "Ubuntu Mono", monospace;
font-size: 11pt;
}
================================================
FILE: Public/css/editor.css
================================================
.CodeMirror {
font-family: Menlo, Consolas, "DejaVu Sans Mono", "Ubuntu Mono", monospace;
font-size: 11pt;
line-height: 1.4;
}
.CodeMirror-selected {
background: #b4d5fe;
}
.editor-marker-start {
border-left: 1px solid rgb(81, 101, 255);
background-color: rgba(81, 101, 255, 0.25);
}
.editor-marker {
border-top: 1px solid rgb(81, 101, 255);
border-bottom: 1px solid rgb(81, 101, 255);
background-color: rgba(81, 101, 255, 0.25);
}
.editor-marker-end {
border-right: 1px solid rgb(81, 101, 255);
background-color: rgba(81, 101, 255, 0.25);
}
================================================
FILE: Public/css/lookup.css
================================================
.keyword,
.atSign {
color: #c800a4;
}
.importKeyword {
color: #1c00cf;
}
.stringLiteral {
color: #df0002;
}
.StringLiteralExpr {
color: #df0002;
}
.IntegerLiteralExpr,
.FloatLiteralExpr {
color: #3a00dc;
}
.integerLiteral,
.floatingLiteral {
color: #3a00dc;
}
.lineComment,
.blockComment,
.docLineComment,
.docBlockComment {
color: #008e00;
}
.unexpectedText,
.shebang {
color: #5d6c79;
}
.token.missing {
color: #a3a3a3;
}
================================================
FILE: Public/css/popover.css
================================================
.popover {
position: absolute;
z-index: 1070;
font-size: 10pt;
box-shadow: 0 8px 24px rgba(140, 149, 159, 0.2);
}
.popover-content {
margin: 0 0 0 0;
min-width: 400px;
max-width: 50vw;
background-clip: padding-box;
background-color: #fff;
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 4px;
}
.popover-content .title {
margin: 0 14px 0 14px;
padding-top: 8px;
font-weight: bolder;
font-size: larger;
}
.popover .arrow {
position: absolute;
z-index: 1070;
top: 50%;
left: calc(100% + -6px);
transform: translateY(-50%) rotate(-135deg);
width: 10px;
height: 10px;
content: "";
background-color: #fff;
border: 1px solid transparent;
border-left-color: rgba(0, 0, 0, 0.2);
border-bottom-color: rgba(0, 0, 0, 0.2);
box-shadow: 0 8px 24px rgba(140, 149, 159, 0.2);
pointer-events: none;
}
.popover-content dl {
margin-top: 0;
margin-bottom: 0;
padding: 10px 14px;
max-height: 100vh;
}
.popover-content dt {
padding: 0;
}
.popover-content dd {
margin-bottom: 2px;
margin-left: 0;
font-family: Menlo, Consolas, "DejaVu Sans Mono", "Ubuntu Mono", monospace;
word-break: break-all;
}
.popover-content .font-monospace {
font-family: Menlo, Consolas, "DejaVu Sans Mono", "Ubuntu Mono", monospace !important;
}
.popover-content .badge {
margin: 0 8px 0 8px;
color: #696969;
background-color: #f2f2f2;
}
.popover-content .badge.ref {
margin: 0 0 0 -0.65em;
color: #696969;
background-color: #f2f2f2;
font-size: 100%;
font-weight: normal;
}
.popover-content .badge.annotation {
width: 56px;
text-align: end;
font-size: 0.8rem;
margin: 0 8px 0 0;
padding: 0;
color: #696969;
background-color: transparent;
}
.popover-content .whitespace {
color: #cccccc;
}
.popover-content .newline {
color: #cccccc;
}
================================================
FILE: Public/css/table.css
================================================
table.dataTable {
margin-top: 0 !important;
}
th.statistics_count {
text-align: initial !important;
}
================================================
FILE: Public/css/tree_view.css
================================================
.tree-view {
font-family: Menlo, Consolas, "DejaVu Sans Mono", "Ubuntu Mono", monospace;
font-size: 11pt;
}
.tree-view ul {
margin: 0;
padding-left: 0;
}
.tree-view li {
position: relative;
list-style: none;
margin: 0;
padding: 5px 5px 0 25px;
cursor: pointer;
}
.tree-view li .collapsible {
position: relative;
}
.tree-view li div {
display: inline-block;
}
.tree-view li.hover {
background-color: rgb(100, 149, 237, 0.25);
}
.tree-view li.hover > div > div {
text-decoration: underline;
}
.tree-view li.opened .collapsible::before {
position: absolute;
left: -16px;
top: 50%;
transform: translateY(-50%);
padding-top: 2px;
padding-bottom: 2px;
width: 7px;
height: 4px;
display: inline-block;
content: "";
background-image: url("../images/caret-down-solid.svg");
background-repeat: no-repeat;
}
.tree-view li.collapsed .collapsible::before {
position: absolute;
left: -14.5px;
top: 50%;
transform: translateY(-50%);
padding-top: 2px;
padding-bottom: 2px;
width: 4px;
height: 7px;
display: inline-block;
content: "";
background-image: url("../images/caret-right-solid.svg");
background-repeat: no-repeat;
}
.tree-view .decl-syntax {
color: #007aff;
}
.tree-view .expr-syntax {
color: #ff8c00;
}
.tree-view .pattern-syntax {
color: #008b8b;
}
.tree-view .type-syntax {
color: #8b0000;
}
.tree-view .token {
font-weight: bold;
cursor: auto;
}
.tree-view .token .whitespace {
color: #cccccc;
}
.tree-view .token .newline {
color: #cccccc;
}
.tree-view .token .badge {
color: #696969;
background-color: #dcdcdc;
}
.tree-view .token.missing {
color: #a3a3a3;
}
.tree-view .token.missing::after {
content: "Missing";
color: #696969;
background-color: #dcdcdc;
display: inline-block;
padding: 0.35em 0.65em;
margin: 0 8px;
font-size: 0.75em;
font-weight: 700;
line-height: 1;
color: var(--bs-badge-color);
text-align: center;
white-space: nowrap;
vertical-align: baseline;
border-radius: 0.375rem;
vertical-align: middle;
}
================================================
FILE: Public/css/trivia.css
================================================
#trivia-container span.leading-trivia {
background-color: #c8e1c8;
}
#trivia-container span.trailing-trivia {
background-color: #ffd8a8;
}
#trivia-container .br {
color: #a3a3a3;
}
================================================
FILE: Public/error.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Simple HttpErrorPages | MIT License | https://github.com/AndiDittrich/HttpErrorPages -->
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="twitter:card" content="summary" />
<meta property="twitter:image" content="https://swift-ast-explorer.com/images/ogp_image.png" />
<meta property="og:image" content="https://swift-ast-explorer.com/images/ogp_image.png" />
<meta property="og:title" content="Swift AST Explorer">
<meta property="og:description"
content="Visualize Swift AST and select nodes within the editor, a great way to learn about the structure of Swift syntax trees." />
<meta name="description"
content="Visualize Swift AST and select nodes within the editor, a great way to learn about the structure of Swift syntax trees." />
<meta property="og:site_name" content="Swift AST Explorer - AST visualizer for Swift source code" />
<link rel="apple-touch-icon" sizes="180x180" href="/favicons/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicons/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicons/favicon-16x16.png">
<link rel="manifest" href="/favicons/site.webmanifest">
<link rel="mask-icon" href="/favicons/safari-pinned-tab.svg" color="#5bbad5">
<link rel="shortcut icon" href="/favicons/favicon.ico">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="msapplication-config" content="/favicons/browserconfig.xml">
<meta name="theme-color" content="#ffffff">
<title>#(title) | #(status) - #(error)</title>
<style type="text/css">
/*! normalize.css v5.0.0 | MIT License | github.com/necolas/normalize.css */
html {
font-family: sans-serif;
line-height: 1.15;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%
}
body {
margin: 0
}
article,
aside,
footer,
header,
nav,
section {
display: block
}
h1 {
font-size: 2em;
margin: .67em 0
}
figcaption,
figure,
main {
display: block
}
figure {
margin: 1em 40px
}
hr {
box-sizing: content-box;
height: 0;
overflow: visible
}
pre {
font-family: monospace, monospace;
font-size: 1em
}
a {
background-color: transparent;
-webkit-text-decoration-skip: objects
}
a:active,
a:hover {
outline-width: 0
}
abbr[title] {
border-bottom: none;
text-decoration: underline;
text-decoration: underline dotted
}
b,
strong {
font-weight: inherit
}
b,
strong {
font-weight: bolder
}
code,
kbd,
samp {
font-family: monospace, monospace;
font-size: 1em
}
dfn {
font-style: italic
}
mark {
background-color: #ff0;
color: #000
}
small {
font-size: 80%
}
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline
}
sub {
bottom: -.25em
}
sup {
top: -.5em
}
audio,
video {
display: inline-block
}
audio:not([controls]) {
display: none;
height: 0
}
img {
border-style: none
}
svg:not(:root) {
overflow: hidden
}
button,
input,
optgroup,
select,
textarea {
font-family: sans-serif;
font-size: 100%;
line-height: 1.15;
margin: 0
}
button,
input {
overflow: visible
}
button,
select {
text-transform: none
}
[type=reset],
[type=submit],
button,
html [type=button] {
-webkit-appearance: button
}
[type=button]::-moz-focus-inner,
[type=reset]::-moz-focus-inner,
[type=submit]::-moz-focus-inner,
button::-moz-focus-inner {
border-style: none;
padding: 0
}
[type=button]:-moz-focusring,
[type=reset]:-moz-focusring,
[type=submit]:-moz-focusring,
button:-moz-focusring {
outline: 1px dotted ButtonText
}
fieldset {
border: 1px solid silver;
margin: 0 2px;
padding: .35em .625em .75em
}
legend {
box-sizing: border-box;
color: inherit;
display: table;
max-width: 100%;
padding: 0;
white-space: normal
}
progress {
display: inline-block;
vertical-align: baseline
}
textarea {
overflow: auto
}
[type=checkbox],
[type=radio] {
box-sizing: border-box;
padding: 0
}
[type=number]::-webkit-inner-spin-button,
[type=number]::-webkit-outer-spin-button {
height: auto
}
[type=search] {
-webkit-appearance: textfield;
outline-offset: -2px
}
[type=search]::-webkit-search-cancel-button,
[type=search]::-webkit-search-decoration {
-webkit-appearance: none
}
::-webkit-file-upload-button {
-webkit-appearance: button;
font: inherit
}
details,
menu {
display: block
}
summary {
display: list-item
}
canvas {
display: inline-block
}
template {
display: none
}
[hidden] {
display: none
}
/*! Simple HttpErrorPages | MIT X11 License | https://github.com/AndiDittrich/HttpErrorPages */
body,
html {
width: 100%;
height: 100%;
background-color: white
}
body {
color: black;
text-align: center;
padding: 0;
min-height: 100%;
display: table;
font-family: "Open Sans", Arial, sans-serif
}
h1 {
font-family: inherit;
font-weight: 500;
line-height: 1.1;
color: inherit;
font-size: 36px
}
h1 small {
font-size: 68%;
font-weight: 400;
line-height: 1;
color: #777
}
a {
text-decoration: none;
color: #fff;
font-size: inherit;
border-bottom: dotted 1px #707070
}
.lead {
color: silver;
font-size: 21px;
line-height: 1.4
}
.cover {
display: table-cell;
vertical-align: middle;
padding: 0 20px
}
footer {
position: fixed;
width: 100%;
height: 40px;
left: 0;
bottom: 0;
color: #a0a0a0;
font-size: 14px
}
</style>
</head>
<body>
<div class="cover">
<h1>#(error) <small>Error #(status)</small></h1>
<p class="lead">#(reason)</p>
</div>
</body>
</html>
================================================
FILE: Public/favicons/browserconfig.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<browserconfig>
<msapplication>
<tile>
<square150x150logo src="/favicons/mstile-150x150.png"/>
<TileColor>#da532c</TileColor>
</tile>
</msapplication>
</browserconfig>
================================================
FILE: Public/favicons/site.webmanifest
================================================
{
"name": "",
"short_name": "",
"icons": [
{
"src": "/favicons/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/favicons/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display": "standalone"
}
================================================
FILE: Public/index.html
================================================
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="twitter:card" content="summary" />
<meta property="twitter:image" content="https://swift-ast-explorer.com/images/ogp_image.png" />
<meta property="og:image" content="https://swift-ast-explorer.com/images/ogp_image.png" />
<meta property="og:title" content="Swift AST Explorer">
<meta property="og:description"
content="Visualize Swift AST and select nodes within the editor, a great way to learn about the structure of Swift syntax trees." />
<meta name="description"
content="Visualize Swift AST and select nodes within the editor, a great way to learn about the structure of Swift syntax trees." />
<meta property="og:site_name" content="Swift AST Explorer - AST visualizer for Swift source code" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="theme-color" content="#ffffff">
<style>
body {
height: 100vh;
height: 100svh;
}
.swift-logo {
width: 2rem;
height: 2rem;
}
.button-pill {
height: 2rem;
}
.button-circle {
width: 2rem;
height: 2rem;
}
.nav-tabs {
border-bottom: none !important;
}
.nav-item button {
width: 160px;
}
.nav-item.lined .nav-link {
border: none;
color: #868e96;
border-bottom: 3px solid transparent;
}
.nav-item.lined .nav-link:hover {
border: none;
color: #0d6efd;
border-bottom: 3px solid transparent;
}
.nav-item.lined .nav-link.active {
background: none;
color: #0d6efd;
border-color: #0d6efd;
}
</style>
<title>Swift AST Explorer</title>
</head>
<body>
<div class="container-fluid d-flex flex-column bg-light g-0 h-100">
<header class="row row-cols-2 g-0">
<div class="col">
<div class="d-inline-block mx-1">
<a class="text-decoration-none" href="/">
<span class="fa-brands fa-swift fa-2x text-primary d-inline-block align-middle p-1 swift-logo"></span><span
class="h4 text-dark d-inline-block align-middle m-0">Swift AST Explorer</span>
</a>
<button id="run-button" type="button"
class="btn btn-primary btn-sm rounded-pill button-pill px-3 m-1 disabled" aria-label="Update">
<span id="run-button-icon" class="fa-solid fa-play fa-fw"></span>
<div id="run-button-spinner" class="d-inline-block d-none">
<span class="fa-duotone fa-spinner-third fa-spin fa-fw"></span>
</div>
</button>
<div class="dropdown d-inline-block">
<button id="config-button" type="button"
class="btn btn-outline-primary btn-sm rounded-circle button-circle m-1 disabled" data-bs-toggle="dropdown"
data-bs-auto-close="outside" data-bs-offset="0,10" aria-label="Options" aria-expanded="false">
<span class="fa-solid fa-cog fa-fw"></span>
</button>
<ul class="dropdown-menu">
<li class="options-item checkbox parser-options active-tick" data-value="fold">
<a class="dropdown-item" data-target="#">
Fold Sequence Expressions
</a>
</li>
<li class="options-item checkbox parser-options" data-value="showmissing">
<a class="dropdown-item" data-target="#">
Show Missing Tokens
</a>
</li>
</ul>
</div>
<button id="format-button" type="button"
class="btn btn-outline-primary btn-sm rounded-circle button-circle m-1 disabled" data-bs-toggle="tooltip"
data-bs-placement="bottom" data-bs-container="#format-button" title="Format" aria-label="Format">
<span class="fa-solid fa-align-left fa-fw"></span>
</button>
<span data-bs-toggle="modal" data-bs-target="#help-modal">
<button id="help-button" type="button" class="btn btn-outline-primary btn-sm rounded-circle button-circle"
data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-container="#help-button" title="Help"
aria-label="Help">
<span class="fa-solid fa-question fa-fw"></span>
</button>
</span>
<div class="dropdown d-inline-block">
<button id="version-button" type="button"
class="btn btn-link btn-sm text-decoration-none dropdown-toggle m-1 disabled" data-bs-toggle="dropdown"
data-bs-auto-close="outside" aria-label="Options" aria-expanded="false">
<span class="fa-solid fa-code-branch"></span><span id="version-text" class="mx-1">603.0.0</span>
</button>
<ul class="dropdown-menu">
<li>
<h6 class="dropdown-header">Swift Syntax Version</h6>
</li>
<li class="options-item radio parser-version" data-value="50800" data-text="508.0.1">
<a class="dropdown-item" data-target="#">
508.0.1 (Swift 5.8)
</a>
</li>
<li class="options-item radio parser-version" data-value="50900" data-text="509.1.1">
<a class="dropdown-item" data-target="#">
509.1.1 (Swift 5.9)
</a>
</li>
<li class="options-item radio parser-version" data-value="51000" data-text="510.0.3">
<a class="dropdown-item" data-target="#">
510.0.3 (Swift 5.10)
</a>
</li>
<li class="options-item radio parser-version" data-value="60000" data-text="600.0.1">
<a class="dropdown-item" data-target="#">
600.0.1 (Swift 6.0)
</a>
</li>
<li class="options-item radio parser-version" data-value="60100" data-text="601.0.1">
<a class="dropdown-item" data-target="#">
601.0.1 (Swift 6.1)
</a>
</li>
<li class="options-item radio parser-version" data-value="60200" data-text="602.0.0">
<a class="dropdown-item" data-target="#">
602.0.0 (Swift 6.2)
</a>
</li>
<li class="options-item radio parser-version active-tick" data-value="60300" data-text="603.0.0">
<a class="dropdown-item" data-target="#">
603.0.0 (Swift 6.3)
</a>
</li>
<li class="options-item radio parser-version" data-value="trunk" data-text="main">
<a class="dropdown-item" data-target="#">
main branch
</a>
</li>
</ul>
</div>
</div>
</div>
<div class="col">
<nav>
<ul class="nav nav-tabs" role="tablist">
<li class="nav-item lined" role="presentation">
<button type="button" class="nav-link active" data-bs-toggle="tab" data-bs-target="#structure-tab-pane"
role="tab" aria-controls="structure-tab-pane" aria-selected="true"><span
class="fa-regular fa-list-tree"></span><span class="px-3">Structure</span>
</button>
</li>
<li class="nav-item lined" role="presentation">
<button type="button" class="nav-link" data-bs-toggle="tab" data-bs-target="#lookup-tab-pane" role="tab"
aria-controls="lookup-tab-pane" aria-selected="false"><span class="fa-light fa-file-code"></span><span
class="px-3">Lookup</span>
</button>
</li>
<li class="nav-item lined" role="presentation">
<button type="button" class="nav-link" data-bs-toggle="tab" data-bs-target="#trivia-tab-pane" role="tab"
aria-controls="trivia-tab-pane" aria-selected="false"><span
class="fa-solid fa-slash-forward"></span><span class="px-3">Trivia</span>
</button>
</li>
<li class="nav-item lined" role="presentation">
<button type="button" class="nav-link" data-bs-toggle="tab" data-bs-target="#statistics-tab-pane"
role="tab" aria-controls="statistics-tab-pane" aria-selected="false"><span
class="fa-regular fa-table"></span><span class="px-3">Statistics</span>
</button>
</li>
</ul>
</nav>
</div>
</header>
<main class="flex-grow-1 row row-cols-2 g-0 h-100">
<div class="col">
<textarea id="editor-container" class="h-100 d-none">#(code)</textarea>
</div>
<div class="col">
<div class="tab-content">
<div id="structure-tab-pane" class="tab-pane active" role="tabpanel" aria-labelledby="home-tab" tabindex="0">
<div id="structure-container" role="document"></div>
</div>
<div id="lookup-tab-pane" class="tab-pane" role="tabpanel" aria-labelledby="lookup-tab" tabindex="0">
<div id="lookup-container" role="document"></div>
</div>
<div id="trivia-tab-pane" class="tab-pane" role="tabpanel" aria-labelledby="trivia-tab" tabindex="0">
<div id="trivia-container" role="document"></div>
</div>
<div id="statistics-tab-pane" class="tab-pane" role="tabpanel" aria-labelledby="statistics-tab" tabindex="0">
<div id="statistics-container" role="document"></div>
</div>
</div>
</div>
</main>
<footer class="row row-cols-1 g-0">
<div class="col p-1 text-center">
<div class="d-inline-block mx-2">
<a class="text-reset text-decoration-none small" href="https://status.swift-ast-explorer.com/" target="_blank"
rel="nofollow noopener noreferrer"><span class="fa-light fa-monitor-heart-rate"></span><span
class="mx-2">System
Status</span></a>
</div>
<div class="d-inline-block mx-2">
<a class="text-reset text-decoration-none small"
href="https://github.com/swiftfiddle/swift-ast-explorer/issues/new" target="_blank"
rel="nofollow noopener noreferrer"><span class="fa-regular fa-message-smile"></span><span
class="mx-2">Feedback</span></a>
</div>
<div class="d-inline-block mx-2">
<a class="text-reset text-decoration-none small" href="https://github.com/swiftfiddle/swift-ast-explorer"
target="_blank" rel="nofollow noopener noreferrer"><span class="fa-brands fa-github"></span><span
class="mx-2">Source Code</span></a>
</div>
<div class="d-inline-block mx-2">
<a class="text-reset text-decoration-none small" href="https://hachyderm.io/@kishikawakatsumi" target="_blank"
rel="nofollow noopener noreferrer"><span class="fa-regular fa-at"></span><span
class="mx-2">Creator</span></a>
</div>
<div class="d-inline-block mx-2">
<a class="text-reset text-decoration-none small" href="https://github.com/sponsors/kishikawakatsumi"
target="_blank" rel="nofollow noopener noreferrer">
<span class="fa-solid fa-heart" style="color: #bf3989;"></span></span><span class="mx-2">Donate</span></a>
</div>
</div>
</footer>
</div>
<div id="help-modal" class="modal fade" tabindex="-1" aria-labelledby="help-modal-label" aria-hidden="true">
<div class="modal-dialog modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="help-modal-label"><span class="fa-regular fa-question-circle"></span><span
class="mx-2">Help</span>
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<dl>
<dt class="bg-light rounded"><span class="fa-solid fa-code-branch fa-fw"></span><span class="mx-2">Default
Swift
Version</span></dt>
</dl>
<dd>
<pre><code>#(swiftVersion)</code></pre>
</dd>
<dl>
<dt class="bg-light rounded"><span class="fa-solid fa-cog fa-fw"></span><span class="mx-2">Parser
Options</span></dt>
<dd class="my-2">
<dl>
<dt>Fold Sequence Expressions</dt>
<dd>Use <a
href="https://github.com/apple/swift-syntax/blob/main/Sources/SwiftOperators/SwiftOperators.docc/SwiftOperators.md"
target="_blank" rel="nofollow noopener noreferrer">SwiftOperators</a>
to 'fold' the syntax tree and rebuild the tree structure according to operator
precedence. This option is enabled by default.</dd>
</dl>
</dd>
<dd>
<dl>
<dt>Show Missing Tokens</dt>
<dd>The Swift parser often automatically inserts tokens that are not present in the source code to
recover from syntax errors. This option makes the missing tokens automatically inserted by the parser
visible.</dd>
</dl>
</dd>
</dl>
<dl>
<dt class="bg-light rounded"><span class="fa-regular fa-file-import fa-fw"></span><span
class="mx-2">Import</span></dt>
<dd>There are a few different ways to import code into the code editor:</dd>
</dl>
<ul>
<li>Drop a file onto the editor</li>
<li>Append a GitHub gist ID to the URL<br>(e.g. <code>swift-ast-explorer.com/<code
style="background-color: #F0F0F0; padding: 2px;"><gist_id_goes_here></code></code>)</li>
<li>Or just start typing!</li>
</ul>
<dl>
<dt class="bg-light rounded pt-2"><span class="fa-regular fa-message-smile fa-fw"></span><span
class="mx-2">Feedback / Bug Report</span>
</dt>
<dd>
<a href="https://github.com/swiftfiddle/swift-ast-explorer/issues/new" target="_blank"
rel="nofollow noopener noreferrer">github.com/swiftfiddle/swift-ast-explorer
</a>
</dd>
</dl>
</div>
</div>
</div>
</div>
</body>
</html>
================================================
FILE: Public/index.js
================================================
"use strict";
import "./scss/default.scss";
import "./css/common.css";
import "./js/icon.js";
import { App } from "./js/app.js";
new App();
================================================
FILE: Public/js/app.js
================================================
"use strict";
import { Tooltip } from "bootstrap";
import { Editor } from "./editor.js";
import { Balloon } from "./balloon.js";
import { StructureView } from "./structure_view.js";
import { LookupView } from "./lookup_view.js";
import { TriviaView } from "./trivia_view.js";
import { StatisticsView } from "./statistics_view.js";
import { WebSocketClient } from "./websocket.js";
import { debounce } from "./debounce.js";
export class App {
get contentViewHeight() {
const headerHeight = document.querySelector("header").clientHeight;
const footerHeight = document.querySelector("footer").clientHeight;
const viewport = CSS.supports("height", "100svh") ? "100svh" : "100vh";
return `calc(${viewport} - ${headerHeight}px - ${footerHeight}px)`;
}
constructor() {
this.editor = new Editor(document.getElementById("editor-container"));
this.balloon = new Balloon();
this.structureView = new StructureView(
document.getElementById("structure-container")
);
this.lookupView = new LookupView(
document.getElementById("lookup-container")
);
this.triviaView = new TriviaView(
document.getElementById("trivia-container")
);
this.statisticsView = new StatisticsView(
document.getElementById("statistics-container")
);
this.init();
}
init() {
[].slice
.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
.map((trigger) => {
return new Tooltip(trigger);
});
const updateOnTextChange = debounce(() => {
this.update();
}, 400);
this.editor.on("change", () => {
updateOnTextChange();
});
document.getElementById("run-button").addEventListener("click", (event) => {
event.preventDefault();
this.update();
});
document.getElementById("config-button").classList.remove("disabled");
document.getElementById("version-button").classList.remove("disabled");
document.querySelectorAll(".options-item.checkbox").forEach((listItem) => {
listItem.addEventListener("click", (event) => {
event.preventDefault();
listItem.classList.toggle("active-tick");
this.update();
});
});
document.querySelectorAll(".options-item.radio").forEach((listItem) => {
listItem.addEventListener("click", (event) => {
event.preventDefault();
document.querySelectorAll(".options-item.radio").forEach((listItem) => {
listItem.classList.remove("active-tick");
});
listItem.classList.toggle("active-tick");
document.getElementById("version-text").textContent =
listItem.dataset.text;
this.update();
});
});
const formatter = new WebSocketClient("wss://swift-format.com/api/ws");
formatter.onresponse = (response) => {
if (!response) {
return;
}
if (response.output) {
this.editor.setValue(response.output);
}
};
const formatButton = document.getElementById("format-button");
formatButton.classList.remove("disabled");
formatButton.addEventListener("click", (event) => {
event.preventDefault();
formatter.send({ code: this.editor.getValue() });
});
const onresize = debounce(() => {
this.onresize();
}, 200);
new ResizeObserver(() => {
onresize();
}).observe(document.body);
setTimeout(() => {
this.update();
}, 100);
}
update() {
showLoading();
const branch = branchOptions();
const options = parserOptions();
const code = this.editor.getValue();
const json = {
code,
options,
branch,
};
fetch("/update", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(json),
})
.then((response) => response.json())
.then((response) => {
this.response = response;
this.structureData = JSON.parse(response.syntaxJSON);
this.updateStructure();
this.updateLookup();
this.updateTrivia();
this.updateStatistics();
this.onresize();
})
.catch((error) => {
this.structureView.error = error;
this.lookupView.error = error;
this.statisticsView.error = error;
})
.finally(() => {
hideLoading();
this.editor.focus();
});
}
updateStructure() {
if (this.structureData === undefined) {
return;
}
const data = this.structureData;
this.structureView.update(data);
this.structureView.onmouseover = (_event, _target, data) => {
const title = data.token
? `Token <span class="token-kind text-truncate" style="max-width: 300px;">${data.token.kind}</span>`
: `${data.text}`;
const range = data.range;
this.editor.setSelection(range);
const formatted = formatRange(range);
this.balloon.setContent(
`<div class="title">${title}</div><div class="range">${formatted}</div>`
);
const pageCoords = this.editor.charCoords(range, "page");
const localCoords = this.editor.charCoords(range, "local");
const rect = {
left: localCoords.left,
top: pageCoords.top,
width: pageCoords.right - pageCoords.left,
height: pageCoords.bottom - pageCoords.top,
};
this.balloon.show(rect, {
placement: "top",
offset: { x: 0, y: -6 },
});
};
this.structureView.onmouseout = (_event, _target, _data) => {
this.balloon.hide();
};
}
updateLookup() {
if (this.response === undefined || this.response.syntaxHTML === undefined) {
return;
}
const data = this.response.syntaxHTML;
this.lookupView.update(data);
}
updateTrivia() {
if (this.response === undefined || this.response.syntaxHTML === undefined) {
return;
}
const data = this.response.syntaxHTML;
this.triviaView.update(data);
}
updateStatistics() {
if (this.structureData === undefined) {
return;
}
const data = this.structureData;
const statistics = data
.filter((node) => node.token === undefined)
.reduce((acc, item) => {
const existingItem = acc.find((a) => a.text === item.text);
if (existingItem) {
existingItem.ranges.push(item.range);
} else {
acc.push({ text: item.text, ranges: [item.range] });
}
return acc;
}, []);
this.statisticsView.update(statistics);
this.statisticsView.onmouseover = (_event, target, ranges) => {
const content = ranges
.map((range) => {
return {
startRow: range.startRow
.toString()
.padStart(2, " ")
.replace(" ", " "),
startColumn: range.startColumn
.toString()
.padEnd(2, " ")
.replace(" ", " "),
endRow: range.endRow
.toString()
.padStart(2, " ")
.replace(" ", " "),
endColumn: range.endColumn
.toString()
.padEnd(2, " ")
.replace(" ", " "),
};
})
.map((range) => {
return `<div class="range">${formatRange(range)}</div>`;
})
.join("");
this.balloon.setContent(content);
const tabContainer = document.querySelector(".tab-content");
const rect = target.getBoundingClientRect();
this.balloon.show(rect, {
placement: "top",
offset: { x: 10, y: -6 },
containerRect: {
left: tabContainer.offsetLeft,
top: tabContainer.offsetTop,
width: tabContainer.clientWidth,
height: tabContainer.clientHeight,
},
});
for (const range of ranges) {
this.editor.markText(range);
}
};
this.statisticsView.onmouseout = (_event, _target) => {
this.balloon.hide();
this.editor.clearMarks();
};
}
onresize() {
document.querySelector(".CodeMirror").style.height = this.contentViewHeight;
this.editor.refresh();
document.getElementById("structure-container").style.height =
this.contentViewHeight;
document.getElementById("lookup-container").style.height =
this.contentViewHeight;
document.getElementById("trivia-container").style.height =
this.contentViewHeight;
document.getElementById("statistics-container").style.height =
this.contentViewHeight;
}
}
function branchOptions() {
let branch = "60300";
document
.querySelectorAll(".options-item.radio.parser-version")
.forEach((listItem) => {
if (listItem.classList.contains("active-tick")) {
branch = listItem.dataset.value;
}
});
return branch;
}
function parserOptions() {
const options = [];
document
.querySelectorAll(".options-item.checkbox.checkbox")
.forEach((listItem) => {
if (listItem.classList.contains("active-tick")) {
options.push(listItem.dataset.value);
}
});
return options;
}
function showLoading() {
document.getElementById("run-button").classList.add("disabled");
document.getElementById("run-button-icon").classList.add("d-none");
document.getElementById("run-button-spinner").classList.remove("d-none");
}
function hideLoading() {
document.getElementById("run-button").classList.remove("disabled");
document.getElementById("run-button-icon").classList.remove("d-none");
document.getElementById("run-button-spinner").classList.add("d-none");
}
function formatRange(range) {
return `${range.startRow}:${range.startColumn} ... ${range.endRow}:${range.endColumn}`;
}
================================================
FILE: Public/js/balloon.js
================================================
"use strict";
import "../css/balloon.css";
export class Balloon {
constructor() {
this.balloon = document.createElement("div");
this.init();
}
init() {
this.balloon.classList.add("d-none", "balloon");
document.body.appendChild(this.balloon);
}
setContent(content) {
this.content = content;
this.balloon.innerHTML = content;
}
show(rect, options = {}) {
let placement = options.placement || "top";
const containerRect = options.containerRect || {
left: 0,
top: 0,
width: 0,
height: 0,
};
this.balloon.classList.remove("d-none");
const width = this.balloon.clientWidth;
const height = this.balloon.clientHeight;
const top = containerRect.top;
const bottom = containerRect.top + containerRect.height;
let fallbackOcurred = 1;
switch (placement) {
case "top":
if (rect.top - height < top) {
placement = "bottom";
fallbackOcurred = -1;
}
break;
case "bottom":
if (rect.top + height > bottom) {
placement = "top";
fallbackOcurred = -1;
}
break;
case "left":
if (rect.left - width < containerRect.left) {
placement = "right";
fallbackOcurred = -1;
}
break;
case "right":
if (rect.left + width > containerRect.left + containerRect.width) {
placement = "left";
fallbackOcurred = -1;
}
break;
default:
break;
}
this.balloon.classList.remove("top", "bottom", "left", "right");
this.balloon.classList.add(placement);
const offset = (() => {
const offset = options.offset || { x: 0, y: 0 };
switch (placement) {
case "top":
return { x: offset.x, y: offset.y * fallbackOcurred - height };
case "bottom":
return { x: offset.x, y: offset.y * fallbackOcurred + rect.height };
case "left":
return { x: offset.x * fallbackOcurred - width, y: offset.y };
case "right":
return { x: offset.x * fallbackOcurred + rect.width, y: offset.y };
default:
return { x: offset.x, y: offset.y };
}
})();
this.balloon.style.left = `${rect.left + offset.x}px`;
this.balloon.style.top = `${rect.top + offset.y}px`;
}
hide() {
this.balloon.classList.add("d-none");
}
}
================================================
FILE: Public/js/debounce.js
================================================
"use strict";
export function debounce(cb, delay = 250) {
let timeout;
return (...args) => {
clearTimeout(timeout);
timeout = setTimeout(() => {
cb(...args);
}, delay);
};
}
================================================
FILE: Public/js/editor.js
================================================
"use strict";
import "codemirror/lib/codemirror.css";
import "../css/editor.css";
import CodeMirror from "codemirror";
import "codemirror/mode/swift/swift";
import "codemirror/addon/edit/matchbrackets";
import "codemirror/addon/edit/closebrackets";
export class Editor {
constructor(container) {
this.container = container;
this.init();
}
init() {
this.editor = CodeMirror.fromTextArea(this.container, {
autoCloseBrackets: true,
lineNumbers: true,
lineWrapping: true,
matchBrackets: true,
mode: "swift",
screenReaderLabel: "Source code editor",
tabSize: 2,
});
this.editor.setSize("100%", "100%");
this.editor.on("drop", (editor, event) => {
event.preventDefault();
event.stopPropagation();
const files = event.dataTransfer.files;
if (files.length === 0) {
return;
}
const reader = new FileReader();
reader.onload = (event) => {
this.editor.setValue(event.target.result);
};
reader.readAsText(files[0], "UTF-8");
});
}
getValue() {
return this.editor.getValue();
}
setValue(value) {
this.editor.setValue(value);
}
setSelection(range) {
this.editor.setSelection(
{ ch: range.graphemeStartColumn - 1, line: range.startRow - 1 },
{ ch: range.graphemeEndColumn - 1, line: range.endRow - 1 },
{ scroll: false }
);
}
markText(range) {
return this.editor.markText(
{ ch: range.graphemeStartColumn - 1, line: range.startRow - 1 },
{ ch: range.graphemeEndColumn - 1, line: range.endRow - 1 },
{
className: "editor-marker",
startStyle: "editor-marker-start",
endStyle: "editor-marker-end",
}
);
}
clearMarks() {
this.editor.getAllMarks().forEach((mark) => {
mark.clear();
});
}
charCoords(range, mode = "page") {
return this.editor.charCoords(
{ ch: range.startColumn - 1, line: range.startRow - 1 },
mode
);
}
focus() {
this.editor.focus();
}
refresh() {
this.editor.refresh();
}
on(event, callback) {
this.editor.on(event, callback);
}
}
================================================
FILE: Public/js/icon.js
================================================
"use strict";
import { library, dom } from "@fortawesome/fontawesome-svg-core";
import {
faPlay,
faEraser,
faAlignLeft,
faCog,
faQuestion,
faCodeBranch,
faCaretRight,
faCaretDown,
faSlashForward,
faHeart,
} from "@fortawesome/pro-solid-svg-icons";
import {
faCheck,
faListTree,
faTable,
faCircleInfo,
faQuestionCircle,
faFileImport,
faMessageSmile,
faAt,
} from "@fortawesome/pro-regular-svg-icons";
import {
faFileCode,
faMonitorHeartRate,
} from "@fortawesome/pro-light-svg-icons";
import { faSpinnerThird } from "@fortawesome/pro-duotone-svg-icons";
import { faSwift, faGithub } from "@fortawesome/free-brands-svg-icons";
library.add(
faPlay,
faEraser,
faAlignLeft,
faCog,
faQuestion,
faCodeBranch,
faCaretRight,
faCaretDown,
faSlashForward,
faHeart,
faCheck,
faListTree,
faTable,
faCircleInfo,
faQuestionCircle,
faFileImport,
faMessageSmile,
faAt,
faFileCode,
faMonitorHeartRate,
faSpinnerThird,
faSwift,
faGithub
);
dom.watch();
================================================
FILE: Public/js/lookup_view.js
================================================
"use strict";
import "../css/lookup.css";
import { Popover } from "./popover.js";
export class LookupView {
set error(error) {
this.container.innerHTML = `<div class="alert alert-danger m-3" role="alert">${error}</div>`;
}
constructor(container) {
this.container = container;
this.popover = new Popover();
}
update(syntaxHTML) {
this.container.innerHTML = "";
const contentView = document.createElement("div");
contentView.innerHTML = syntaxHTML;
this.container.appendChild(contentView);
const popover = this.popover;
const self = this;
$(this.container)
.find("span")
.each(function () {
$(this).mouseover(function (event) {
event.stopPropagation();
const contents = [];
$(this)
.parents("span")
.each(function (index, element) {
self.createDOMRectElement(element.getBoundingClientRect());
contents.push({
title: element.dataset.title,
content: element.dataset.content,
type: element.dataset.type,
range: element.dataset.range,
});
if (index > 0) {
return false;
}
});
let element = event.target;
element.style.backgroundColor = "rgba(81, 101, 255, 0.5)";
contents.reverse();
contents.push({
title: element.dataset.title,
content: element.dataset.content,
type: element.dataset.type,
range: element.dataset.range,
});
const list = contents
.filter(
(item, index, self) =>
index ===
self.findIndex(
(t) =>
t.title === item.title &&
t.content === item.content &&
t.range === item.range
)
)
.map((item) => {
const title = escapeHTML(item.title);
const type = escapeHTML(item.type);
const content = escapeHTML(item.content);
if (item.range) {
const range = JSON.parse(item.range);
const sourceRange = `${range.startRow}:${range.startColumn} ... ${range.endRow}:${range.endColumn}`;
return `<dt class="text-truncate" style="max-width: calc(40vw - 20px);">
<span class="badge annotation" style="width: auto; text-align: start;">Text</span><span class="font-monospace">${title}</span>
</dt>
<dd><div><span class="badge annotation">Range</span>${sourceRange}</div><div><span class="badge annotation">${type}</span>${content}</div></dd>`;
} else {
return `<dt class="text-truncate" style="max-width: calc(40vw - 20px);">
<span class="badge annotation" style="width: auto; text-align: start;">Text</span><span class="font-monospace">${title}</span>
</dt>
<dd><div><span class="badge annotation">${type}</span>${content}</div></dd>`;
}
})
.join("");
const dl = `<dl>${list}</dl>`;
popover.setContent(dl);
const tabContainer = document.querySelector(".tab-content");
const containerRect = tabContainer.getBoundingClientRect();
popover.show(element, {
containerRect: containerRect,
offset: { x: -16, y: -2 },
});
});
$(this).mouseout(function (event) {
event.stopPropagation();
let element = event.target;
element.style.backgroundColor = "";
self.removeDOMRectElement();
popover.hide();
});
});
}
createDOMRectElement(domRect) {
const className = "dom-rect";
let rectElements = this.container.getElementsByClassName(className);
for (let i = 0, l = rectElements.length; l > i; i++) {
rectElements[0].parentNode.removeChild(rectElements[0]);
}
let rectElement = document.createElement("div");
rectElement.className = className;
rectElement.style.left = domRect.x - 1 + "px";
rectElement.style.top = domRect.y - 1 + "px";
rectElement.style.width = domRect.width + 1 + "px";
rectElement.style.height = domRect.height + 1 + "px";
rectElement.style.pointerEvents = "none";
rectElement.style.position = "absolute";
rectElement.style.border = "1px solid rgb(81, 101, 255)";
rectElement.style.backgroundColor = "rgba(81, 101, 255, 0.25)";
this.container.appendChild(rectElement);
}
removeDOMRectElement() {
let rectElements = this.container.getElementsByClassName("dom-rect");
for (let i = 0, l = rectElements.length; l > i; i++) {
rectElements[0].parentNode.removeChild(rectElements[0]);
}
}
}
function escapeHTML(text) {
const div = document.createElement("div");
div.appendChild(document.createTextNode(text));
return div.innerHTML;
}
================================================
FILE: Public/js/popover.js
================================================
"use strict";
import "../css/popover.css";
export class Popover {
constructor() {
this.popover = document.createElement("div");
this.popoverContent = document.createElement("div");
this.arrow = document.createElement("div");
this.onmouseover = () => {};
this.onmouseout = () => {};
this.init();
}
init() {
this.popover.classList.add("popover", "d-none");
this.popoverContent.classList.add("popover-content");
this.arrow.classList.add("arrow");
this.popover.appendChild(this.popoverContent);
this.popover.appendChild(this.arrow);
document.body.appendChild(this.popover);
this.popover.addEventListener(
"mouseenter",
(event) => {
event.stopPropagation();
this.onmouseover(event);
},
{ capture: false, once: false, passive: true }
);
this.popover.addEventListener(
"mouseleave",
(event) => {
event.stopPropagation();
this.onmouseout(event);
},
{ capture: false, once: false, passive: true }
);
}
setContent(content) {
if (this.content === content) {
return;
}
this.content = content;
this.popoverContent.innerHTML = content;
}
show(target, options = {}) {
const targetRect = target.getBoundingClientRect();
const containerRect = options.containerRect || {
left: 0,
top: 0,
width: 0,
height: 0,
};
const offset = options.offset || { x: 0, y: 0 };
this.popover.classList.remove("d-none");
const popoverRect = this.popover.getBoundingClientRect();
const left = `${targetRect.left - popoverRect.width + offset.x}px`;
this.popover.style.left = left;
const bottom = containerRect.top + containerRect.height;
const top = targetRect.top - 6 + offset.y;
if (top + popoverRect.height > bottom) {
const popoverTop = bottom - popoverRect.height;
this.popover.style.top = `${popoverTop}px`;
this.arrow.style.top = `${targetRect.top - popoverTop + 10 + offset.y}px`;
} else {
this.popover.style.top = `${top}px`;
this.arrow.style.top = "15px";
}
}
hide() {
this.popover.classList.add("d-none");
}
}
================================================
FILE: Public/js/statistics_view.js
================================================
"use strict";
import DataTable from "datatables.net";
import "datatables.net-bs5/css/dataTables.bootstrap5.min.css";
import "../css/table.css";
export class StatisticsView {
set error(error) {
this.container.innerHTML = `<div class="alert alert-danger m-3" role="alert">${error}</div>`;
}
constructor(container) {
this.container = container;
this.onmouseover = () => {};
this.onmouseout = () => {};
}
update(statistics) {
this.container.innerHTML = `<table class="table table-borderless table-striped table-hover table-sm">
<thead class="table-light">
<tr>
<th scope="col" style="width: 60%;">Syntax</th>
<th scope="col">Count</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
`;
const body = this.container.querySelector(":scope > table > tbody");
for (const row of statistics) {
const tr = document.createElement("tr");
tr.innerHTML = `<td style="font-family: Menlo, Consolas, 'DejaVu Sans Mono', 'Ubuntu Mono', monospace;">${row.text}</td><td><div>${row.ranges.length}</div></td>`;
body.appendChild(tr);
tr.addEventListener(
"mouseover",
(event) => {
event.stopPropagation();
this.onmouseover(event, tr, row.ranges);
},
{ capture: false, once: false, passive: true }
);
tr.addEventListener(
"mouseout",
(event) => {
event.stopPropagation();
this.onmouseout(event, tr);
},
{ capture: false, once: false, passive: true }
);
}
if (this.dataTable) {
this.dataTable.destroy();
}
this.dataTable = new DataTable(
this.container.querySelector(":scope > table"),
{
autoWidth: false,
info: false,
paging: false,
searching: false,
columnDefs: [{ className: "statistics_count", targets: [1] }],
}
);
}
}
================================================
FILE: Public/js/structure_view.js
================================================
"use strict";
import { TreeView } from "./tree_view.js";
import { Popover } from "./popover.js";
export class StructureView {
set error(error) {
this.container.innerHTML = `<div class="alert alert-danger m-3" role="alert">${error}</div>`;
}
constructor(container) {
this.container = container;
this.popover = new Popover();
this.onmouseover = () => {};
this.onmouseout = () => {};
this.init();
}
init() {
this.body = this.container.querySelector(":scope > table > tbody");
}
update(structureData) {
this.container.innerHTML = "";
const treeView = new TreeView(this.container, structureData);
treeView.onmouseover = (event, target, data) => {
this.onmouseover(event, target, data);
if (!data.structure.length && !data.token) {
return;
}
if (data.structure.length > 0) {
this.popover.setContent(makeSyntaxPopoverContent(data));
}
if (data.token) {
this.popover.setContent(makeTokenPopoverContent(data));
}
const tabContainer = document.querySelector(".tab-content");
const containerRect = tabContainer.getBoundingClientRect();
this.popover.show(target, {
containerRect: containerRect,
offset: { x: -10, y: 1 },
});
};
treeView.onmouseout = (event, target, data) => {
this.onmouseout(event, target, data);
if (!event.relatedTarget) {
return;
}
if (!event.relatedTarget.classList.contains("popover-content")) {
this.popover.hide();
}
};
this.popover.onmouseout = (event) => {
this.popover.hide();
};
}
}
function makeSyntaxPopoverContent(data) {
const container = document.createElement("div");
const title = document.createElement("div");
title.classList.add("title");
title.innerText = `${data.text}Syntax`;
title.appendChild(makeSyntaxTypeBadge(data.type));
container.appendChild(title);
const dl = document.createElement("dl");
makeSourceRangePopoverContent(data, dl);
for (const property of data.structure) {
makePropertyPopoverContent(property, dl);
}
container.appendChild(dl);
return container.innerHTML;
}
function makeTokenPopoverContent(data) {
const container = document.createElement("div");
const title = document.createElement("div");
title.classList.add("title");
title.innerText = "TokenSyntax";
container.appendChild(title);
const dl = document.createElement("dl");
makeSourceRangePopoverContent(data, dl);
makeDescriptionList("kind", data.token.kind, dl);
makeDescriptionList("leadingTrivia", data.token.leadingTrivia, dl);
makeDescriptionList("text", data.text, dl);
makeDescriptionList("trailingTrivia", data.token.trailingTrivia, dl);
container.appendChild(dl);
return container.innerHTML;
}
function makeSourceRangePopoverContent(data, list) {
const range = data.range;
const details = `${range.startRow}:${range.startColumn} ... ${range.endRow}:${range.endColumn}`;
makeDescriptionList("Source Range", details, list);
}
function makePropertyPopoverContent(property, list) {
const details = (() => {
const value = property.value;
if (property.ref) {
return `<span class="badge ref">${property.ref}</span>`;
} else if (value && value.text && value.kind) {
const text = value.text;
const kind = value.kind;
return `${text}<span class="badge rounded-pill">${kind}</span>`;
} else if (value && value.text) {
return value.text;
}
})();
makeDescriptionList(property.name, details, list);
}
function makeDescriptionList(term, details, list) {
const dt = document.createElement("dt");
dt.innerHTML = term;
const dd = document.createElement("dd");
dd.innerHTML = details;
list.appendChild(dt);
list.appendChild(dd);
}
function makeSyntaxTypeBadge(type) {
const badge = document.createElement("span");
badge.classList.add("badge", "text-bg-light");
switch (type) {
case "decl": {
badge.innerText = "DeclSyntax";
break;
}
case "expr": {
badge.innerText = "ExprSyntax";
break;
}
case "pattern": {
badge.innerText = "PatternSyntax";
break;
}
case "type": {
badge.innerText = "TypeSyntax";
break;
}
case "collection": {
badge.innerText = "SyntaxCollection";
break;
}
default:
break;
}
return badge;
}
================================================
FILE: Public/js/tree_view.js
================================================
"use strict";
import "../css/tree_view.css";
export class TreeView {
constructor(container, tree) {
this.container = container;
this.tree = tree;
this.treeView = document.createElement("div");
this.state = {};
this.onmouseover = () => {};
this.onmouseout = () => {};
this.init();
}
init() {
this.treeView.classList.add("tree-view");
const fragment = document.createDocumentFragment();
this.renderTree(fragment, this.tree);
this.treeView.appendChild(fragment);
this.container.appendChild(this.treeView);
}
renderTree(container, tree) {
tree
.filter(function (node) {
return node.parent === undefined;
})
.forEach((node) => {
container.appendChild(this.renderNode(node));
});
}
renderNode(node) {
const ul = document.createElement("ul");
const li = document.createElement("li");
const content = document.createElement("div");
if (!node.token) {
content.classList.add("collapsible");
content.addEventListener("click", (event) => {
this.onclick(event, node, li);
});
const div = document.createElement("div");
div.classList.add(`${node.type}-syntax`);
div.innerHTML = node.text;
content.appendChild(div);
li.appendChild(content);
const children = this.getChildren(node.id);
for (const child of children) {
li.classList.add("opened");
li.appendChild(this.renderNode(child));
}
} else {
content.classList.add("token");
if (node.class) {
content.classList.add(node.class);
}
content.innerHTML =
node.text.length === 0 ? `<span class="badge">Empty</span>` : node.text;
li.appendChild(content);
}
li.addEventListener(
"mouseover",
(event) => {
event.stopPropagation();
li.classList.add("hover");
this.onmouseover(event, content, node);
},
{ capture: false, once: false, passive: true }
);
li.addEventListener(
"mouseout",
(event) => {
event.stopPropagation();
li.classList.remove("hover");
this.onmouseout(event, content, node);
},
{ capture: false, once: false, passive: true }
);
ul.appendChild(li);
return ul;
}
hasChildren(id) {
return this.tree.some(function (node) {
return node.parent === id;
});
}
getChildren(id) {
return this.tree.filter(function (node) {
return node.parent === id;
});
}
open(node, li) {
li.classList.add("opened");
li.classList.remove("collapsed");
const children = this.state[node.id];
if (children) {
for (const child of children) {
li.appendChild(child);
}
} else {
const children = this.getChildren(node.id);
for (const child of children) {
li.classList.add("opened");
li.appendChild(this.renderNode(child));
}
}
}
collapse(node, li) {
li.classList.add("collapsed");
li.classList.remove("opened");
const children = li.querySelectorAll(":scope > ul");
for (const child of children) {
li.removeChild(child);
}
this.state[node.id] = children;
}
onclick(event, node, li) {
event.preventDefault();
event.stopPropagation();
if (li.classList.contains("opened")) {
this.collapse(node, li);
} else {
this.open(node, li);
}
}
}
================================================
FILE: Public/js/trivia_view.js
================================================
"use strict";
import "../css/trivia.css";
import { Popover } from "./popover.js";
export class TriviaView {
set error(error) {
this.container.innerHTML = `<div class="alert alert-danger m-3" role="alert">${error}</div>`;
}
constructor(container) {
this.container = container;
this.popover = new Popover();
}
update(syntaxHTML) {
this.container.innerHTML = "";
const contentView = document.createElement("div");
contentView.innerHTML = syntaxHTML;
const newlines = contentView.querySelectorAll("br");
for (const newline of newlines) {
const span = document.createElement("span");
span.classList.add("br");
span.textContent = "↲";
span.appendChild(newline.cloneNode(true));
const parent = newline.parentElement;
parent.replaceChild(span, newline);
}
this.container.appendChild(contentView);
this.container.querySelectorAll(".token").forEach((token) => {
token.addEventListener("mouseover", (event) => {
event.stopPropagation();
this.createDOMRectElement(token.getBoundingClientRect());
const parent = token.parentElement;
let isLeadingTrivia = true;
const leadingTrivias = [];
const trailingTrivias = [];
for (const child of Array.from(parent.childNodes)) {
if (child === token) {
isLeadingTrivia = false;
continue;
}
if (child.nodeType === Node.TEXT_NODE) {
const span = document.createElement("span");
span.textContent = child.textContent;
parent.replaceChild(span, child);
if (isLeadingTrivia) {
span.classList.add("leading-trivia");
leadingTrivias.push(
span.textContent
.replace(/\s/g, `<span style="color: #a3a3a3;">␣</span>`)
.replace(/\n/g, `<span style="color: #a3a3a3;">↲</span>`)
);
} else {
span.classList.add("trailing-trivia");
trailingTrivias.push(
span.textContent
.replace(/\s/g, `<span style="color: #a3a3a3;">␣</span>`)
.replace(/\n/g, `<span style="color: #a3a3a3;">↲</span>`)
);
}
} else if (child.nodeType === Node.ELEMENT_NODE) {
if (isLeadingTrivia) {
child.classList.add("leading-trivia");
if (child.classList.contains("br")) {
leadingTrivias.push(`<span style="color: #a3a3a3;">↲</span>`);
} else {
leadingTrivias.push(
child.textContent
.replace(/\s/g, `<span style="color: #a3a3a3;">␣</span>`)
.replace(/\n/g, `<span style="color: #a3a3a3;">↲</span>`)
);
}
} else {
child.classList.add("trailing-trivia");
if (child.classList.contains("br")) {
trailingTrivias.push(`<span style="color: #a3a3a3;">↲</span>`);
} else {
trailingTrivias.push(
child.textContent
.replace(/\s/g, `<span style="color: #a3a3a3;">␣</span>`)
.replace(/\n/g, `<span style="color: #a3a3a3;">↲</span>`)
);
}
}
}
}
const tabContainer = document.querySelector(".tab-content");
const containerRect = tabContainer.getBoundingClientRect();
const elementRect = token.getBoundingClientRect();
const offset = {
x: containerRect.left - elementRect.left - 16,
y: -2,
};
const leadingTrivia = leadingTrivias.join("");
const trailingTrivia = trailingTrivias.join("");
this.popover.setContent(
`<dl>
<dt class="text-truncate" style="max-width: calc(40vw - 20px);"><span class="font-monospace">${token.dataset.title}</span></dt>
<dt class="text-truncate" style="max-width: calc(40vw - 20px);"><span class="font-monospace">${token.dataset.content}</span></dt>
<dt class="text-truncate" style="max-width: calc(40vw - 20px); margin-top: 8px;"><span class="badge annotation text-body" style="width: auto; text-align: start;"><svg width="12" height="10" xmlns="http://www.w3.org/2000/svg"><circle stroke="#c8e1c8" fill="#c8e1c8" cx="4" cy="4" r="3.5" fill-rule="evenodd"/></svg>Leading Trivia</span><div style="padding-left: 12px;"><span class="font-monospace">${leadingTrivia}</span></div></dt>
<dt class="text-truncate" style="max-width: calc(40vw - 20px); margin-top: 8px;"><span class="badge annotation text-body" style="width: auto; text-align: start;"><svg width="12" height="10" xmlns="http://www.w3.org/2000/svg"><circle stroke="#ffd8a8" fill="#ffd8a8" cx="4" cy="4" r="3.5" fill-rule="evenodd"/></svg>Trailing Trivia</span><div style="padding-left: 12px;"><span class="font-monospace">${trailingTrivia}</span></div></dt>
<dt class="text-truncate" style="max-width: calc(40vw - 20px); margin-top: 8px;"><span class="badge annotation" style="width: auto; text-align: start;"><span class="fa-regular fa-circle-info"></span><span class="mx-1">Trivia Attribution Rule</span></dt>
<dt style="max-width: calc(40vw - 20px);"><ol style="font-weight: normal; margin-bottom: 4px;"><li>A token owns all of its trailing trivia up to, but not including, the next newline character.</li><li>Looking backward in the text, a token owns all of the leading trivia up to and including the first contiguous sequence of newlines characters.</li></ol></dt>
</dl>`
);
this.popover.show(token, {
containerRect: containerRect,
offset: offset,
});
});
token.addEventListener("mouseout", (event) => {
event.stopPropagation();
this.removeDOMRectElement();
const parent = token.parentElement;
for (const child of Array.from(parent.childNodes)) {
if (child.nodeType === Node.ELEMENT_NODE) {
child.classList.remove("leading-trivia");
child.classList.remove("trailing-trivia");
}
}
this.popover.hide();
});
});
}
createDOMRectElement(domRect) {
const className = "dom-rect";
let rectElements = this.container.getElementsByClassName(className);
for (let i = 0, l = rectElements.length; l > i; i++) {
rectElements[0].parentNode.removeChild(rectElements[0]);
}
let rectElement = document.createElement("div");
rectElement.className = className;
rectElement.style.left = domRect.x + "px";
rectElement.style.top = domRect.y + "px";
rectElement.style.width = domRect.width + "px";
rectElement.style.height = domRect.height + "px";
rectElement.style.pointerEvents = "none";
rectElement.style.position = "absolute";
rectElement.style.border = "1px solid rgb(100, 149, 237)";
this.container.appendChild(rectElement);
}
removeDOMRectElement() {
let rectElements = this.container.getElementsByClassName("dom-rect");
for (let i = 0, l = rectElements.length; l > i; i++) {
rectElements[0].parentNode.removeChild(rectElements[0]);
}
}
}
================================================
FILE: Public/js/websocket.js
================================================
"use strict";
import ReconnectingWebSocket from "reconnecting-websocket";
export class WebSocketClient {
constructor(endpoint) {
this.connection = this.createConnection(endpoint);
this.onconnect = () => {};
this.onresponse = () => {};
}
get isReady() {
return this.connection.readyState === 1;
}
send(params) {
const encoder = new TextEncoder();
this.connection.send(encoder.encode(JSON.stringify(params)));
}
createConnection(endpoint) {
if (
this.connection &&
(this.connection.readyState === 0 || this.connection.readyState === 1)
) {
return this.connection;
}
const connection = new ReconnectingWebSocket(endpoint, [], {
maxReconnectionDelay: 10000,
minReconnectionDelay: 1000,
reconnectionDelayGrowFactor: 1.3,
connectionTimeout: 10000,
maxRetries: Infinity,
debug: false,
});
connection.bufferType = "arraybuffer";
connection.onopen = () => {
this.onconnect();
};
connection.onerror = (event) => {
connection.close();
};
connection.onmessage = (event) => {
try {
this.onresponse(JSON.parse(event.data));
} catch (error) {}
};
return connection;
}
}
================================================
FILE: Public/robots.txt
================================================
================================================
FILE: Public/scss/default.scss
================================================
@import "bootstrap/scss/functions";
@import "bootstrap/scss/variables";
@import "bootstrap/scss/variables-dark";
@import "bootstrap/scss/maps";
@import "bootstrap/scss/mixins";
@import "bootstrap/scss/utilities";
@import "bootstrap/scss/root";
@import "bootstrap/scss/reboot";
@import "bootstrap/scss/type";
@import "bootstrap/scss/containers";
@import "bootstrap/scss/grid";
@import "bootstrap/scss/tables";
@import "bootstrap/scss/buttons";
@import "bootstrap/scss/transitions";
@import "bootstrap/scss/dropdown";
@import "bootstrap/scss/nav";
@import "bootstrap/scss/badge";
@import "bootstrap/scss/alert";
@import "bootstrap/scss/close";
@import "bootstrap/scss/modal";
@import "bootstrap/scss/tooltip";
@import "bootstrap/scss/helpers";
@import "bootstrap/scss/utilities/api";
================================================
FILE: README.md
================================================
<p>
<img src="https://img.shields.io/badge/os-macOS/Linux-green.svg?style=flat" alt="macOS/Linux">
<a href="http://swift.org">
<img src="https://img.shields.io/badge/swift-5.8-orange.svg?style=flat" alt="Swift 5.8 Compatible">
</a>
<a href="https://github.com/kishikawakatsumi/swift-ast-explorer/blob/master/LICENSE">
<img src="https://img.shields.io/badge/license-Apache2-blue.svg?style=flat" alt="Apache 2">
</a>
</p>
# Swift AST Explorer
Swift AST Explorer is a tool for visualizing the Abstract Syntax Tree (AST) of Swift source code.
Check it out at https://swift-ast-explorer.com/
<a href="https://swift-ast-explorer.com/"><img width="1024" alt="Screen Shot" src="https://github.com/SwiftFiddle/swift-ast-explorer/assets/40610/d41c6f6f-4493-4673-99a6-8dc05fcab30b"></a>
## Features
### Presents Swift syntax in a tree structure
<img width="600" alt="Screen Shot" src="https://github.com/SwiftFiddle/swift-ast-explorer/assets/40610/4815c8e3-5e62-455d-8954-656a24d3461d.png">
### Maps each token in the source code to the corresponding syntax
<img width="600" alt="Screen Shot" src="https://github.com/SwiftFiddle/swift-ast-explorer/assets/40610/2632bb58-2315-4488-bbc6-a8d2c86ae3ff.png">
### Provides an overview and inspection of syntax usage
<img width="600" alt="Screen Shot" src="https://github.com/SwiftFiddle/swift-ast-explorer/assets/40610/c36e5705-1029-4590-8719-1b939c9ab209.png">
## Author
[Kishikawa Katsumi](https://github.com/kishikawakatsumi)
## Supporters & Sponsors
Open source projects thrive on the generosity and support of people like you. If you find this project valuable, please consider extending your support. Contributing to the project not only sustains its growth, but also helps drive innovation and improve its features.
To support this project, you can become a sponsor through [GitHub Sponsors](https://github.com/sponsors/kishikawakatsumi). Your contribution will be greatly appreciated and will help keep the project alive and thriving. Thanks for your consideration! :heart:
## License
The project is released under the [Apache License 2.0](https://github.com/kishikawakatsumi/swift-ast-explorer/blob/main/LICENSE)
================================================
FILE: Resources/parsers/50800/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
================================================
FILE: Resources/parsers/50800/Package.resolved
================================================
{
"pins" : [
{
"identity" : "swift-syntax",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-syntax",
"state" : {
"revision" : "2c49d66d34dfd6f8130afdba889de77504b58ec0",
"version" : "508.0.1"
}
}
],
"version" : 2
}
================================================
FILE: Resources/parsers/50800/Package.swift
================================================
// swift-tools-version:5.8
import PackageDescription
let package = Package(
name: "parser",
platforms: [
.macOS(.v13)
],
dependencies: [
.package(url: "https://github.com/apple/swift-syntax", from: "508.0.1"),
],
targets: [
.executableTarget(
name: "parser",
dependencies: [
.product(name: "SwiftSyntax", package: "swift-syntax"),
.product(name: "SwiftOperators", package: "swift-syntax"),
.product(name: "SwiftParser", package: "swift-syntax"),
],
swiftSettings: [
.unsafeFlags(["-cross-module-optimization"], .when(configuration: .release))
]
),
.testTarget(
name: "Tests",
dependencies: [
.target(name: "parser"),
],
resources: [.process("Fixtures")]
)
]
)
================================================
FILE: Resources/parsers/50800/Sources/parser/Main.swift
================================================
import Foundation
@main
struct Main {
static func main() throws {
do {
let code = String(decoding: FileHandle.standardInput.availableData, as: UTF8.self)
let options = Array(CommandLine.arguments.dropFirst(1))
let response = try SyntaxParser.parse(code: code, options: options)
let data = try JSONEncoder().encode(response)
print(String(decoding: data, as: UTF8.self))
} catch {
var standardError = FileHandle.standardError
print("\(error)", to:&standardError)
}
}
}
extension FileHandle: @retroactive TextOutputStream {
public func write(_ string: String) {
self.write(Data(string.utf8))
}
}
================================================
FILE: Resources/parsers/50800/Sources/parser/SyntaxParser.swift
================================================
import Foundation
import SwiftSyntax
import SwiftOperators
import SwiftParser
struct SyntaxParser {
static func parse(code: String, options: [String] = []) throws -> SyntaxResponse {
let sourceFile = Parser.parse(source: code)
let syntax: Syntax
if options.contains("fold") {
syntax = OperatorTable.standardOperators.foldAll(sourceFile, errorHandler: { _ in })
} else {
syntax = Syntax(sourceFile)
}
let visitor = TokenVisitor(
locationConverter: SourceLocationConverter(file: "", tree: sourceFile),
showMissingTokens: options.contains("showmissing")
)
_ = visitor.rewrite(syntax)
let html = "\(visitor.list.joined())"
let tree = visitor.tree
let encoder = JSONEncoder()
let json = String(decoding: try encoder.encode(tree), as: UTF8.self)
return SyntaxResponse(syntaxHTML: html, syntaxJSON: json, swiftVersion: version)
}
}
================================================
FILE: Resources/parsers/50800/Sources/parser/SyntaxResponse.swift
================================================
import Foundation
struct SyntaxResponse: Codable {
let syntaxHTML: String
let syntaxJSON: String
let swiftVersion: String
}
================================================
FILE: Resources/parsers/50800/Sources/parser/TokenVisitor.swift
================================================
import Foundation
import SwiftSyntax
final class TokenVisitor: SyntaxRewriter {
var list = [String]()
var tree = [TreeNode]()
private var current: TreeNode!
private var index = 0
private let locationConverter: SourceLocationConverter
private let showMissingTokens: Bool
init(locationConverter: SourceLocationConverter, showMissingTokens: Bool) {
self.locationConverter = locationConverter
self.showMissingTokens = showMissingTokens
}
func rewrite(_ node: Syntax) -> Syntax {
visit(node)
}
override func visitPre(_ node: Syntax) {
if let token = node.as(TokenSyntax.self), token.presence == .missing, !showMissingTokens {
return
}
let syntaxNodeType = node.syntaxNodeType
let className: String
if "\(syntaxNodeType)".hasSuffix("Syntax") {
className = String("\(syntaxNodeType)".dropLast(6))
} else {
className = "\(syntaxNodeType)"
}
let title: String
let content: String
let type: String
if let token = node.as(TokenSyntax.self) {
title = sourceAccurateText(token)
content = "\(token.tokenKind)"
type = "Token"
} else {
title = sourceAccurateText(node)
content = "\(syntaxNodeType)"
type = "Syntax"
}
let sourceRange = node.sourceRange(converter: locationConverter)
let start = sourceRange.start
let end = sourceRange.end
let startRow = start.line ?? 1
let startColumn = start.column ?? 1
let endRow = end.line ?? 1
let endColumn = end.column ?? 1
let graphemeStartColumn: Int
if let prefix = String(locationConverter.sourceLines[startRow - 1].utf8.prefix(startColumn - 1)) {
graphemeStartColumn = prefix.utf16.count + 1
} else {
graphemeStartColumn = startColumn
}
let graphemeEndColumn: Int
if let prefix = String(locationConverter.sourceLines[endRow - 1].utf8.prefix(endColumn - 1)) {
graphemeEndColumn = prefix.utf16.count + 1
} else {
graphemeEndColumn = endColumn
}
list.append(
"<span class='\(className)' " +
"data-title='\(title.escapeHTML().replaceInvisiblesWithSymbols())' " +
"data-content='\(content.escapeHTML().replaceInvisiblesWithHTML())' " +
"data-type='\(type.escapeHTML())' " +
#"data-range='{"startRow":\#(startRow),"startColumn":\#(startColumn),"endRow":\#(endRow),"endColumn":\#(endColumn)}'>"#
)
let syntaxType: SyntaxType
switch node {
case _ where node.is(DeclSyntax.self):
syntaxType = .decl
case _ where node.is(ExprSyntax.self):
syntaxType = .expr
case _ where node.is(PatternSyntax.self):
syntaxType = .pattern
case _ where node.is(TypeSyntax.self):
syntaxType = .type
default:
syntaxType = .other
}
let treeNode = TreeNode(
id: index,
text: className,
range: Range(
startRow: startRow,
startColumn: startColumn,
graphemeStartColumn: graphemeStartColumn,
endRow: endRow,
endColumn: endColumn,
graphemeEndColumn: graphemeEndColumn
),
type: syntaxType
)
tree.append(treeNode)
index += 1
switch node.syntaxNodeType.structure {
case .layout(let keyPaths):
if let syntaxNode = node.as(node.syntaxNodeType) {
for (index, keyPath) in keyPaths.enumerated() {
let mirror = Mirror(reflecting: syntaxNode)
if let label = mirror.children.map({ $0 })[index].label {
let key = label
switch syntaxNode[keyPath: keyPath] {
case let value as TokenSyntax:
treeNode.structure.append(
StructureProperty(
name: key,
value: StructureValue(
text: value.text,
kind: "\(value.tokenKind)"
)
)
)
case let value?:
if let value = value as? SyntaxProtocol {
let type = "\(value.syntaxNodeType)"
treeNode.structure.append(StructureProperty(name: key, value: StructureValue(text: "\(type)"), ref: "\(type)"))
} else {
treeNode.structure.append(StructureProperty(name: key, value: StructureValue(text: "\(value)")))
}
case .none:
treeNode.structure.append(StructureProperty(name: key))
}
}
}
}
case .collection(let syntax):
treeNode.type = .collection
treeNode.structure.append(StructureProperty(name: "Element", value: StructureValue(text: "\(syntax)")))
treeNode.structure.append(StructureProperty(name: "Count", value: StructureValue(text: "\(node.children(viewMode: .all).count)")))
break
case .choices:
break
}
if let current {
treeNode.parent = current.id
}
current = treeNode
}
override func visit(_ token: TokenSyntax) -> TokenSyntax {
if token.presence == .missing && !showMissingTokens {
return token
}
let text = sourceAccurateText(token)
current.text = text
.escapeHTML()
.replaceInvisiblesWithHTML()
.replaceHTMLWhitespacesWithSymbols()
if token.presence == .missing {
current.class = token.presence.rawValue.lowercased()
}
current.token = Token(kind: "\(token.tokenKind)", leadingTrivia: "", trailingTrivia: "")
token.leadingTrivia.forEach { (piece) in
let trivia = processTriviaPiece(piece)
list.append(trivia)
current.token?.leadingTrivia += trivia.replaceHTMLWhitespacesWithSymbols()
}
processToken(token)
token.trailingTrivia.forEach { (piece) in
let trivia = processTriviaPiece(piece)
list.append(trivia)
current.token?.trailingTrivia += trivia.replaceHTMLWhitespacesWithSymbols()
}
return token
}
override func visitPost(_ node: Syntax) {
if let token = node.as(TokenSyntax.self), token.presence == .missing, !showMissingTokens {
return
}
list.append("</span>")
if let parent = current.parent {
current = tree[parent]
} else {
current = nil
}
}
private func processToken(_ token: TokenSyntax) {
var kind = "\(token.tokenKind)"
if let index = kind.firstIndex(of: "(") {
kind = String(kind.prefix(upTo: index))
}
if kind.hasSuffix("Keyword") {
kind = "keyword"
}
let sourceRange = token.sourceRange(converter: locationConverter)
let start = sourceRange.start
let end = sourceRange.end
let startRow = start.line ?? 1
let startColumn = start.column ?? 1
let endRow = end.line ?? 1
let endColumn = end.column ?? 1
let text: String
switch token.presence {
case .present:
text = sourceAccurateText(token)
case .missing:
if showMissingTokens {
text = sourceAccurateText(token)
} else {
text = ""
}
}
list.append(
"<span class='token \(kind.escapeHTML()) \(token.presence.rawValue.lowercased())' " +
"data-title='\(token.text.escapeHTML().replaceInvisiblesWithSymbols())' " +
"data-content='\("\(token.tokenKind)".escapeHTML().replaceInvisiblesWithHTML())' " +
"data-type='Token' " +
#"data-range='{"startRow":\#(startRow),"startColumn":\#(startColumn),"endRow":\#(endRow),"endColumn":\#(endColumn)}'>"# +
"\(text.escapeHTML().replaceInvisiblesWithHTML())</span>"
)
}
private func processTriviaPiece(_ piece: TriviaPiece) -> String {
func wrapWithSpanTag(class c: String, text: String) -> String {
"<span class='\(c.escapeHTML())' " +
"data-title='\("\(piece)".escapeHTML().replaceInvisiblesWithSymbols())' " +
"data-content='\(c.escapeHTML().replaceInvisiblesWithHTML())' " +
"data-type='Trivia'>\(text.escapeHTML().replaceInvisiblesWithHTML())</span>"
}
var trivia = ""
switch piece {
case .spaces(let count):
trivia += String(repeating: " ", count: count)
case .tabs(let count):
trivia += String(repeating: " ", count: count * 2)
case .verticalTabs, .formfeeds:
break
case .newlines(let count), .carriageReturns(let count), .carriageReturnLineFeeds(let count):
trivia += String(repeating: "<br/>", count: count)
case .lineComment(let text):
trivia += wrapWithSpanTag(class: "lineComment", text: text)
case .blockComment(let text):
trivia += wrapWithSpanTag(class: "blockComment", text: text)
case .docLineComment(let text):
trivia += wrapWithSpanTag(class: "docLineComment", text: text)
case .docBlockComment(let text):
trivia += wrapWithSpanTag(class: "docBlockComment", text: text)
case .unexpectedText(let text):
trivia += wrapWithSpanTag(class: "unexpectedText", text: text)
case .shebang(let text):
trivia += wrapWithSpanTag(class: "shebang", text: text)
}
return trivia
}
}
private func sourceAccurateText(_ syntax: Syntax) -> String {
let text = "\(syntax.withoutTrivia())"
let utf8Length = syntax.contentLength.utf8Length
if text.utf8.count == utf8Length {
return text
} else {
return String(decoding: syntax.syntaxTextBytes.prefix(utf8Length), as: UTF8.self)
}
}
private func sourceAccurateText(_ token: TokenSyntax) -> String {
let text = token.text
let utf8Length = token.contentLength.utf8Length
if text.utf8.count == utf8Length {
return text
} else {
return String(decoding: token.syntaxTextBytes.prefix(utf8Length), as: UTF8.self)
}
}
private extension String {
func escapeHTML() -> String {
var string = self
let specialCharacters = [
("&", "&"),
("<", "<"),
(">", ">"),
("\"", """),
("'", "'"),
];
for (unescaped, escaped) in specialCharacters {
string = string.replacingOccurrences(of: unescaped, with: escaped, options: .literal, range: nil)
}
return string
}
func replaceInvisiblesWithHTML() -> String {
self
.replacingOccurrences(of: " ", with: " ")
.replacingOccurrences(of: "\n", with: "<br/>")
}
func replaceInvisiblesWithSymbols() -> String {
self
.replacingOccurrences(of: " ", with: "␣")
.replacingOccurrences(of: "\n", with: "↲")
}
func replaceHTMLWhitespacesWithSymbols() -> String {
self
.replacingOccurrences(of: " ", with: "<span class='whitespace'>␣</span>")
.replacingOccurrences(of: "<br/>", with: "<span class='newline'>↲</span><br/>")
}
}
================================================
FILE: Resources/parsers/50800/Sources/parser/TreeNode.swift
================================================
import Foundation
final class TreeNode: Codable {
let id: Int
var parent: Int?
var text: String
var range = Range(startRow: 0, startColumn: 0, graphemeStartColumn: 0, endRow: 0, endColumn: 0, graphemeEndColumn: 0)
var structure = [StructureProperty]()
var type: SyntaxType
var token: Token?
var `class`: String?
init(id: Int, text: String, range: Range, type: SyntaxType) {
self.id = id
self.text = text.escapeHTML()
self.range = range
self.type = type
}
}
extension TreeNode: Equatable {
static func == (lhs: TreeNode, rhs: TreeNode) -> Bool {
lhs.id == rhs.id &&
lhs.parent == rhs.parent &&
lhs.text == rhs.text &&
lhs.range == rhs.range &&
lhs.structure == rhs.structure &&
lhs.type == rhs.type &&
lhs.token == rhs.token
}
}
extension TreeNode: CustomStringConvertible {
var description: String {
"""
{
id: \(id)
parent: \(String(describing: parent))
text: \(text)
range: \(range)
structure: \(structure)
type: \(type)
token: \(String(describing: token))
}
"""
}
}
struct Range: Codable, Equatable {
let startRow: Int
let startColumn: Int
let graphemeStartColumn: Int
let endRow: Int
let endColumn: Int
let graphemeEndColumn: Int
}
extension Range: CustomStringConvertible {
var description: String {
"""
{
startRow: \(startRow)
startColumn: \(startColumn)
endRow: \(endRow)
endColumn: \(endColumn)
}
"""
}
}
struct StructureProperty: Codable, Equatable {
let name: String
let value: StructureValue?
let ref: String?
init(name: String, value: StructureValue? = nil, ref: String? = nil) {
self.name = name.escapeHTML()
self.value = value
self.ref = ref?.escapeHTML()
}
}
extension StructureProperty: CustomStringConvertible {
var description: String {
"""
{
name: \(name)
value: \(String(describing: value))
ref: \(String(describing: ref))
}
"""
}
}
struct StructureValue: Codable, Equatable {
let text: String
let kind: String?
init(text: String, kind: String? = nil) {
self.text = text.escapeHTML().replaceHTMLWhitespacesToSymbols()
self.kind = kind?.escapeHTML()
}
}
extension StructureValue: CustomStringConvertible {
var description: String {
"""
{
text: \(text)
kind: \(String(describing: kind))
}
"""
}
}
enum SyntaxType: String, Codable {
case decl
case expr
case pattern
case type
case collection
case other
}
struct Token: Codable, Equatable {
let kind: String
var leadingTrivia: String
var trailingTrivia: String
init(kind: String, leadingTrivia: String, trailingTrivia: String) {
self.kind = kind.escapeHTML()
self.leadingTrivia = leadingTrivia
self.trailingTrivia = trailingTrivia
}
}
extension Token: CustomStringConvertible {
var description: String {
"""
{
kind: \(kind)
leadingTrivia: \(leadingTrivia)
trailingTrivia: \(trailingTrivia)
}
"""
}
}
private extension String {
func escapeHTML() -> String {
var string = self
let specialCharacters = [
("&", "&"),
("<", "<"),
(">", ">"),
("\"", """),
("'", "'"),
];
for (unescaped, escaped) in specialCharacters {
string = string.replacingOccurrences(of: unescaped, with: escaped, options: .literal, range: nil)
}
return string
.replacingOccurrences(of: " ", with: " ")
.replacingOccurrences(of: "\n", with: "<br>")
}
func replaceHTMLWhitespacesToSymbols() -> String {
self
.replacingOccurrences(of: " ", with: "<span class='whitespace'>␣</span>")
.replacingOccurrences(of: "<br>", with: "<span class='newline'>↲</span>")
}
}
================================================
FILE: Resources/parsers/50800/Sources/parser/Version.swift
================================================
import Foundation
let version = "5.8.1"
================================================
FILE: Resources/parsers/50800/Tests/Tests/Fixtures/test-1-1.html
================================================
<span class='SourceFile' data-title='let␣number␣=␣0' data-content='SourceFileSyntax' data-type='Syntax' data-range='{"startRow":1,"startColumn":1,"endRow":1,"endColumn":15}'>
<span class='CodeBlockItemList' data-title='let␣number␣=␣0' data-content='CodeBlockItemListSyntax' data-type='Syntax' data-range='{"startRow":1,"startColumn":1,"endRow":1,"endColumn":15}'>
<span class='CodeBlockItem' data-title='let␣number␣=␣0' data-content='CodeBlockItemSyntax' data-type='Syntax' data-range='{"startRow":1,"startColumn":1,"endRow":1,"endColumn":15}'>
<span class='VariableDecl' data-title='let␣number␣=␣0' data-content='VariableDeclSyntax' data-type='Syntax' data-range='{"startRow":1,"startColumn":1,"endRow":1,"endColumn":15}'>
<span class='Token' data-title='let' data-content='letKeyword' data-type='Token' data-range='{"startRow":1,"startColumn":1,"endRow":1,"endColumn":4}'>
<span class='token keyword present' data-title='let' data-content='letKeyword' data-type='Token' data-range='{"startRow":1,"startColumn":1,"endRow":1,"endColumn":4}'>
let
</span>
</span>
<span class='PatternBindingList' data-title='number␣=␣0' data-content='PatternBindingListSyntax' data-type='Syntax' data-range='{"startRow":1,"startColumn":5,"endRow":1,"endColumn":15}'>
<span class='PatternBinding' data-title='number␣=␣0' data-content='PatternBindingSyntax' data-type='Syntax' data-range='{"startRow":1,"startColumn":5,"endRow":1,"endColumn":15}'>
<span class='IdentifierPattern' data-title='number' data-content='IdentifierPatternSyntax' data-type='Syntax' data-range='{"startRow":1,"startColumn":5,"endRow":1,"endColumn":11}'>
<span class='Token' data-title='number' data-content='identifier("number")' data-type='Token' data-range='{"startRow":1,"startColumn":5,"endRow":1,"endColumn":11}'>
<span class='token identifier present' data-title='number' data-content='identifier("number")' data-type='Token' data-range='{"startRow":1,"startColumn":5,"endRow":1,"endColumn":11}'>
number
</span>
</span>
</span>
<span class='InitializerClause' data-title='=␣0' data-content='InitializerClauseSyntax' data-type='Syntax' data-range='{"startRow":1,"startColumn":12,"endRow":1,"endColumn":15}'>
<span class='Token' data-title='=' data-content='equal' data-type='Token' data-range='{"startRow":1,"startColumn":12,"endRow":1,"endColumn":13}'>
<span class='token equal present' data-title='=' data-content='equal' data-type='Token' data-range='{"startRow":1,"startColumn":12,"endRow":1,"endColumn":13}'>
=
</span>
</span>
<span class='IntegerLiteralExpr' data-title='0' data-content='IntegerLiteralExprSyntax' data-type='Syntax' data-range='{"startRow":1,"startColumn":14,"endRow":1,"endColumn":15}'>
<span class='Token' data-title='0' data-content='integerLiteral("0")' data-type='Token' data-range='{"startRow":1,"startColumn":14,"endRow":1,"endColumn":15}'>
<span class='token integerLiteral present' data-title='0' data-content='integerLiteral("0")' data-type='Token' data-range='{"startRow":1,"startColumn":14,"endRow":1,"endColumn":15}'>
0
</span>
</span>
</span>
</span>
</span>
</span>
</span>
</span>
</span>
<span class='Token' data-title='' data-content='eof' data-type='Token' data-range='{"startRow":1,"startColumn":15,"endRow":1,"endColumn":15}'>
<span class='token eof present' data-title='' data-content='eof' data-type='Token' data-range='{"startRow":1,"startColumn":15,"endRow":1,"endColumn":15}'></span>
</span>
</span>
================================================
FILE: Resources/parsers/50800/Tests/Tests/Fixtures/test-1-1.json
================================================
[
{
"id": 0,
"range": {
"endColumn": 15,
"endRow": 1,
"graphemeEndColumn": 15,
"graphemeStartColumn": 1,
"startColumn": 1,
"startRow": 1
},
"structure": [
{
"name": "unexpectedBeforeStatements",
"value": {
"text": "nil"
}
},
{
"name": "statements",
"ref": "CodeBlockItemListSyntax",
"value": {
"text": "CodeBlockItemListSyntax"
}
},
{
"name": "unexpectedBetweenStatementsAndEOFToken",
"value": {
"text": "nil"
}
},
{
"name": "eofToken",
"value": {
"kind": "eof",
"text": ""
}
},
{
"name": "unexpectedAfterEOFToken",
"value": {
"text": "nil"
}
}
],
"text": "SourceFile",
"type": "other"
},
{
"id": 1,
"parent": 0,
"range": {
"endColumn": 15,
"endRow": 1,
"graphemeEndColumn": 15,
"graphemeStartColumn": 1,
"startColumn": 1,
"startRow": 1
},
"structure": [
{
"name": "Element",
"value": {
"text": "CodeBlockItemSyntax"
}
},
{
"name": "Count",
"value": {
"text": "1"
}
}
],
"text": "CodeBlockItemList",
"type": "collection"
},
{
"id": 2,
"parent": 1,
"range": {
"endColumn": 15,
"endRow": 1,
"graphemeEndColumn": 15,
"graphemeStartColumn": 1,
"startColumn": 1,
"startRow": 1
},
"structure": [
{
"name": "unexpectedBeforeItem",
"value": {
"text": "nil"
}
},
{
"name": "item",
"ref": "VariableDeclSyntax",
"value": {
"text": "VariableDeclSyntax"
}
},
{
"name": "unexpectedBetweenItemAndSemicolon",
"value": {
"text": "nil"
}
},
{
"name": "semicolon",
"value": {
"text": "nil"
}
},
{
"name": "unexpectedBetweenSemicolonAndErrorTokens",
"value": {
"text": "nil"
}
},
{
"name": "errorTokens",
"value": {
"text": "nil"
}
},
{
"name": "unexpectedAfterErrorTokens",
"value": {
"text": "nil"
}
}
],
"text": "CodeBlockItem",
"type": "other"
},
{
"id": 3,
"parent": 2,
"range": {
"endColumn": 15,
"endRow": 1,
"graphemeEndColumn": 15,
"graphemeStartColumn": 1,
"startColumn": 1,
"startRow": 1
},
"structure": [
{
"name": "unexpectedBeforeAttributes",
"value": {
"text": "nil"
}
},
{
"name": "attributes",
"value": {
"text": "nil"
}
},
{
"name": "unexpectedBetweenAttributesAndModifiers",
"value": {
"text": "nil"
}
},
{
"name": "modifiers",
"value": {
"text": "nil"
}
},
{
"name": "unexpectedBetweenModifiersAndLetOrVarKeyword",
"value": {
"text": "nil"
}
},
{
"name": "letOrVarKeyword",
"value": {
"kind": "letKeyword",
"text": "let"
}
},
{
"name": "unexpectedBetweenLetOrVarKeywordAndBindings",
"value": {
"text": "nil"
}
},
{
"name": "bindings",
"ref": "PatternBindingListSyntax",
"value": {
"text": "PatternBindingListSyntax"
}
},
{
"name": "unexpectedAfterBindings",
"value": {
"text": "nil"
}
}
],
"text": "VariableDecl",
"type": "decl"
},
{
"id": 4,
"parent": 3,
"range": {
"endColumn": 4,
"endRow": 1,
"graphemeEndColumn": 4,
"graphemeStartColumn": 1,
"startColumn": 1,
"startRow": 1
},
"structure": [],
"text": "let",
"token": {
"kind": "letKeyword",
"leadingTrivia": "",
"trailingTrivia": "<span class='whitespace'>␣</span>"
},
"type": "other"
},
{
"id": 5,
"parent": 3,
"range": {
"endColumn": 15,
"endRow": 1,
"graphemeEndColumn": 15,
"graphemeStartColumn": 5,
"startColumn": 5,
"startRow": 1
},
"structure": [
{
"name": "Element",
"value": {
"text": "PatternBindingSyntax"
}
},
{
"name": "Count",
"value": {
"text": "1"
}
}
],
"text": "PatternBindingList",
"type": "collection"
},
{
"id": 6,
"parent": 5,
"range": {
"endColumn": 15,
"endRow": 1,
"graphemeEndColumn": 15,
"graphemeStartColumn": 5,
"startColumn": 5,
"startRow": 1
},
"structure": [
{
"name": "unexpectedBeforePattern",
"value": {
"text": "nil"
}
},
{
"name": "pattern",
"ref": "IdentifierPatternSyntax",
"value": {
"text": "IdentifierPatternSyntax"
}
},
{
"name": "unexpectedBetweenPatternAndTypeAnnotation",
"value": {
"text": "nil"
}
},
{
"name": "typeAnnotation",
"value": {
"text": "nil"
}
},
{
"name": "unexpectedBetweenTypeAnnotationAndInitializer",
"value": {
"text": "nil"
}
},
{
"name": "initializer",
"ref": "InitializerClauseSyntax",
"value": {
"text": "InitializerClauseSyntax"
}
},
{
"name": "unexpectedBetweenInitializerAndAccessor",
"value": {
"text": "nil"
}
},
{
"name": "accessor",
"value": {
"text": "nil"
}
},
{
"name": "unexpectedBetweenAccessorAndTrailingComma",
"value": {
"text": "nil"
}
},
{
"name": "trailingComma",
"value": {
"text": "nil"
}
},
{
"name": "unexpectedAfterTrailingComma",
"value": {
"text": "nil"
}
}
],
"text": "PatternBinding",
"type": "other"
},
{
"id": 7,
"parent": 6,
"range": {
"endColumn": 11,
"endRow": 1,
"graphemeEndColumn": 11,
"graphemeStartColumn": 5,
"startColumn": 5,
"startRow": 1
},
"structure": [
{
"name": "unexpectedBeforeIdentifier",
"value": {
"text": "nil"
}
},
{
"name": "identifier",
"value": {
"kind": "identifier("number")",
"text": "number"
}
},
{
"name": "unexpectedAfterIdentifier",
"value": {
"text": "nil"
}
}
],
"text": "IdentifierPattern",
"type": "pattern"
},
{
"id": 8,
"parent": 7,
"range": {
"endColumn": 11,
"endRow": 1,
"graphemeEndColumn": 11,
"graphemeStartColumn": 5,
"startColumn": 5,
"startRow": 1
},
"structure": [],
"text": "number",
"token": {
"kind": "identifier("number")",
"leadingTrivia": "",
"trailingTrivia": "<span class='whitespace'>␣</span>"
},
"type": "other"
},
{
"id": 9,
"parent": 6,
"range": {
"endColumn": 15,
"endRow": 1,
"graphemeEndColumn": 15,
"graphemeStartColumn": 12,
"startColumn": 12,
"startRow": 1
},
"structure": [
{
"name": "unexpectedBeforeEqual",
"value": {
"text": "nil"
}
},
{
"name": "equal",
"value": {
"kind": "equal",
"text": "="
}
},
{
"name": "unexpectedBetweenEqualAndValue",
"value": {
"text": "nil"
}
},
{
"name": "value",
"ref": "IntegerLiteralExprSyntax",
"value": {
"text": "IntegerLiteralExprSyntax"
}
},
{
"name": "unexpectedAfterValue",
"value": {
"text": "nil"
}
}
],
"text": "InitializerClause",
"type": "other"
},
{
"id": 10,
"parent": 9,
"range": {
"endColumn": 13,
"endRow": 1,
"graphemeEndColumn": 13,
"graphemeStartColumn": 12,
"startColumn": 12,
"startRow": 1
},
"structure": [],
"text": "=",
"token": {
"kind": "equal",
"leadingTrivia": "",
"trailingTrivia": "<span class='whitespace'>␣</span>"
},
"type": "other"
},
{
"id": 11,
"parent": 9,
"range": {
"endColumn": 15,
"endRow": 1,
"graphemeEndColumn": 15,
"graphemeStartColumn": 14,
"startColumn": 14,
"startRow": 1
},
"structure": [
{
"name": "unexpectedBeforeDigits",
"value": {
"text": "nil"
}
},
{
"name": "digits",
"value": {
"kind": "integerLiteral("0")",
"text": "0"
}
},
{
"name": "unexpectedAfterDigits",
"value": {
"text": "nil"
}
}
],
"text": "IntegerLiteralExpr",
"type": "expr"
},
{
"id": 12,
"parent": 11,
"range": {
"endColumn": 15,
"endRow": 1,
"graphemeEndColumn": 15,
"graphemeStartColumn": 14,
"startColumn": 14,
"startRow": 1
},
"structure": [],
"text": "0",
"token": {
"kind": "integerLiteral("0")",
"leadingTrivia": "",
"trailingTrivia": ""
},
"type": "other"
},
{
"id": 13,
"parent": 0,
"range": {
"endColumn": 15,
"endRow": 1,
"graphemeEndColumn": 15,
"graphemeStartColumn": 15,
"startColumn": 15,
"startRow": 1
},
"structure": [],
"text": "",
"token": {
"kind": "eof",
"leadingTrivia": "",
"trailingTrivia": ""
},
"type": "other"
}
]
================================================
FILE: Resources/parsers/50800/Tests/Tests/Fixtures/test-1-2.html
================================================
<span class='SourceFile' data-title='var␣temperatureInFahrenheit␣=␣90↲↲if␣temperatureInFahrenheit␣<=␣32␣{↲␣␣print("It's␣very␣cold.␣Consider␣wearing␣a␣scarf.")↲}␣else␣if␣temperatureInFahrenheit␣>=␣86␣{↲␣␣print("It's␣really␣warm.␣Don't␣forget␣to␣wear␣sunscreen.")↲}␣else␣{↲␣␣print("It's␣not␣that␣cold.␣Wear␣a␣t-shirt.")↲}↲↲//␣Prints␣"It's␣really␣warm.␣Don't␣forget␣to␣wear␣sunscreen."' data-content='SourceFileSyntax' data-type='Syntax' data-range='{"startRow":1,"startColumn":1,"endRow":11,"endColumn":62}'>
<span class='CodeBlockItemList' data-title='var␣temperatureInFahrenheit␣=␣90↲↲if␣temperatureInFahrenheit␣<=␣32␣{↲␣␣print("It's␣very␣cold.␣Consider␣wearing␣a␣scarf.")↲}␣else␣if␣temperatureInFahrenheit␣>=␣86␣{↲␣␣print("It's␣really␣warm.␣Don't␣forget␣to␣wear␣sunscreen.")↲}␣else␣{↲␣␣print("It's␣not␣that␣cold.␣Wear␣a␣t-shirt.")↲}' data-content='CodeBlockItemListSyntax' data-type='Syntax' data-range='{"startRow":1,"startColumn":1,"endRow":9,"endColumn":2}'>
<span class='CodeBlockItem' data-title='var␣temperatureInFahrenheit␣=␣90' data-content='CodeBlockItemSyntax' data-type='Syntax' data-range='{"startRow":1,"startColumn":1,"endRow":1,"endColumn":33}'>
<span class='VariableDecl' data-title='var␣temperatureInFahrenheit␣=␣90' data-content='VariableDeclSyntax' data-type='Syntax' data-range='{"startRow":1,"startColumn":1,"endRow":1,"endColumn":33}'>
<span class='Token' data-title='var' data-content='varKeyword' data-type='Token' data-range='{"startRow":1,"startColumn":1,"endRow":1,"endColumn":4}'>
<span class='token keyword present' data-title='var' data-content='varKeyword' data-type='Token' data-range='{"startRow":1,"startColumn":1,"endRow":1,"endColumn":4}'>
var
</span>
</span>
<span class='PatternBindingList' data-title='temperatureInFahrenheit␣=␣90' data-content='PatternBindingListSyntax' data-type='Syntax' data-range='{"startRow":1,"startColumn":5,"endRow":1,"endColumn":33}'>
<span class='PatternBinding' data-title='temperatureInFahrenheit␣=␣90' data-content='PatternBindingSyntax' data-type='Syntax' data-range='{"startRow":1,"startColumn":5,"endRow":1,"endColumn":33}'>
<span class='IdentifierPattern' data-title='temperatureInFahrenheit' data-content='IdentifierPatternSyntax' data-type='Syntax' data-range='{"startRow":1,"startColumn":5,"endRow":1,"endColumn":28}'>
<span class='Token' data-title='temperatureInFahrenheit' data-content='identifier("temperatureInFahrenheit")' data-type='Token' data-range='{"startRow":1,"startColumn":5,"endRow":1,"endColumn":28}'>
<span class='token identifier present' data-title='temperatureInFahrenheit' data-content='identifier("temperatureInFahrenheit")' data-type='Token' data-range='{"startRow":1,"startColumn":5,"endRow":1,"endColumn":28}'>
temperatureInFahrenheit
</span>
</span>
</span>
<span class='InitializerClause' data-title='=␣90' data-content='InitializerClauseSyntax' data-type='Syntax' data-range='{"startRow":1,"startColumn":29,"endRow":1,"endColumn":33}'>
<span class='Token' data-title='=' data-content='equal' data-type='Token' data-range='{"startRow":1,"startColumn":29,"endRow":1,"endColumn":30}'>
<span class='token equal present' data-title='=' data-content='equal' data-type='Token' data-range='{"startRow":1,"startColumn":29,"endRow":1,"endColumn":30}'>
=
</span>
</span>
<span class='IntegerLiteralExpr' data-title='90' data-content='IntegerLiteralExprSyntax' data-type='Syntax' data-range='{"startRow":1,"startColumn":31,"endRow":1,"endColumn":33}'>
<span class='Token' data-title='90' data-content='integerLiteral("90")' data-type='Token' data-range='{"startRow":1,"startColumn":31,"endRow":1,"endColumn":33}'>
<span class='token integerLiteral present' data-title='90' data-content='integerLiteral("90")' data-type='Token' data-range='{"startRow":1,"startColumn":31,"endRow":1,"endColumn":33}'>
90
</span>
</span>
</span>
</span>
</span>
</span>
</span>
</span>
<span class='CodeBlockItem' data-title='if␣temperatureInFahrenheit␣<=␣32␣{↲␣␣print("It's␣very␣cold.␣Consider␣wearing␣a␣scarf.")↲}␣else␣if␣temperatureInFahrenheit␣>=␣86␣{↲␣␣print("It's␣really␣warm.␣Don't␣forget␣to␣wear␣sunscreen.")↲}␣else␣{↲␣␣print("It's␣not␣that␣cold.␣Wear␣a␣t-shirt.")↲}' data-content='CodeBlockItemSyntax' data-type='Syntax' data-range='{"startRow":3,"startColumn":1,"endRow":9,"endColumn":2}'>
<span class='IfStmt' data-title='if␣temperatureInFahrenheit␣<=␣32␣{↲␣␣print("It's␣very␣cold.␣Consider␣wearing␣a␣scarf.")↲}␣else␣if␣temperatureInFahrenheit␣>=␣86␣{↲␣␣print("It's␣really␣warm.␣Don't␣forget␣to␣wear␣sunscreen.")↲}␣else␣{↲␣␣print("It's␣not␣that␣cold.␣Wear␣a␣t-shirt.")↲}' data-content='IfStmtSyntax' data-type='Syntax' data-range='{"startRow":3,"startColumn":1,"endRow":9,"endColumn":2}'>
<span class='Token' data-title='if' data-content='ifKeyword' data-type='Token' data-range='{"startRow":3,"startColumn":1,"endRow":3,"endColumn":3}'>
<br/>
<br/>
<span class='token keyword present' data-title='if' data-content='ifKeyword' data-type='Token' data-range='{"startRow":3,"startColumn":1,"endRow":3,"endColumn":3}'>
if
</span>
</span>
<span class='ConditionElementList' data-title='temperatureInFahrenheit␣<=␣32' data-content='ConditionElementListSyntax' data-type='Syntax' data-range='{"startRow":3,"startColumn":4,"endRow":3,"endColumn":33}'>
<span class='ConditionElement' data-title='temperatureInFahrenheit␣<=␣32' data-content='ConditionElementSyntax' data-type='Syntax' data-range='{"startRow":3,"startColumn":4,"endRow":3,"endColumn":33}'>
<span class='SequenceExpr' data-title='temperatureInFahrenheit␣<=␣32' data-content='SequenceExprSyntax' data-type='Syntax' data-range='{"startRow":3,"startColumn":4,"endRow":3,"endColumn":33}'>
<span class='ExprList' data-title='temperatureInFahrenheit␣<=␣32' data-content='ExprListSyntax' data-type='Syntax' data-range='{"startRow":3,"startColumn":4,"endRow":3,"endColumn":33}'>
<span class='IdentifierExpr' data-title='temperatureInFahrenheit' data-content='IdentifierExprSyntax' data-type='Syntax' data-range='{"startRow":3,"startColumn":4,"endRow":3,"endColumn":27}'>
<span class='Token' data-title='temperatureInFahrenheit' data-content='identifier("temperatureInFahrenheit")' data-type='Token' data-range='{"startRow":3,"startColumn":4,"endRow":3,"endColumn":27}'>
<span class='token identifier present' data-title='temperatureInFahrenheit' data-content='identifier("temperatureInFahrenheit")' data-type='Token' data-range='{"startRow":3,"startColumn":4,"endRow":3,"endColumn":27}'>
temperatureInFahrenheit
</span>
</span>
</span>
<span class='BinaryOperatorExpr' data-title='<=' data-content='BinaryOperatorExprSyntax' data-type='Syntax' data-range='{"startRow":3,"startColumn":28,"endRow":3,"endColumn":30}'>
<span class='Token' data-title='<=' data-content='spacedBinaryOperator("<=")' data-type='Token' data-range='{"startRow":3,"startColumn":28,"endRow":3,"endColumn":30}'>
<span class='token spacedBinaryOperator present' data-title='<=' data-content='spacedBinaryOperator("<=")' data-type='Token' data-range='{"startRow":3,"startColumn":28,"endRow":3,"endColumn":30}'>
<=
</span>
</span>
</span>
<span class='IntegerLiteralExpr' data-title='32' data-content='IntegerLiteralExprSyntax' data-type='Syntax' data-range='{"startRow":3,"startColumn":31,"endRow":3,"endColumn":33}'>
<span class='Token' data-title='32' data-content='integerLiteral("32")' data-type='Token' data-range='{"startRow":3,"startColumn":31,"endRow":3,"endColumn":33}'>
<span class='token integerLiteral present' data-title='32' data-content='integerLiteral("32")' data-type='Token' data-range='{"startRow":3,"startColumn":31,"endRow":3,"endColumn":33}'>
32
</span>
</span>
</span>
</span>
</span>
</span>
</span>
<span class='CodeBlock' data-title='{↲␣␣print("It's␣very␣cold.␣Consider␣wearing␣a␣scarf.")↲}' data-content='CodeBlockSyntax' data-type='Syntax' data-range='{"startRow":3,"startColumn":34,"endRow":5,"endColumn":2}'>
<span class='Token' data-title='{' data-content='leftBrace' data-type='Token' data-range='{"startRow":3,"startColumn":34,"endRow":3,"endColumn":35}'>
<span class='token leftBrace present' data-title='{' data-content='leftBrace' data-type='Token' data-range='{"startRow":3,"startColumn":34,"endRow":3,"endColumn":35}'>
{
</span>
</span>
<span class='CodeBlockItemList' data-title='print("It's␣very␣cold.␣Consider␣wearing␣a␣scarf.")' data-content='CodeBlockItemListSyntax' data-type='Syntax' data-range='{"startRow":4,"startColumn":3,"endRow":4,"endColumn":53}'>
<span class='CodeBlockItem' data-title='print("It's␣very␣cold.␣Consider␣wearing␣a␣scarf.")' data-content='CodeBlockItemSyntax' data-type='Syntax' data-range='{"startRow":4,"startColumn":3,"endRow":4,"endColumn":53}'>
<span class='FunctionCallExpr' data-title='print("It's␣very␣cold.␣Consider␣wearing␣a␣scarf.")' data-content='FunctionCallExprSyntax' data-type='Syntax' data-range='{"startRow":4,"startColumn":3,"endRow":4,"endColumn":53}'>
<span class='IdentifierExpr' data-title='print' data-content='IdentifierExprSyntax' data-type='Syntax' data-range='{"startRow":4,"startColumn":3,"endRow":4,"endColumn":8}'>
<span class='Token' data-title='print' data-content='identifier("print")' data-type='Token' data-range='{"startRow":4,"startColumn":3,"endRow":4,"endColumn":8}'>
<br/>
<span class='token identifier present' data-title='print' data-content='identifier("print")' data-type='Token' data-range='{"startRow":4,"startColumn":3,"endRow":4,"endColumn":8}'>
print
</span>
</span>
</span>
<span class='Token' data-title='(' data-content='leftParen' data-type='Token' data-range='{"startRow":4,"startColumn":8,"endRow":4,"endColumn":9}'>
<span class='token leftParen present' data-title='(' data-content='leftParen' data-type='Token' data-range='{"startRow":4,"startColumn":8,"endRow":4,"endColumn":9}'>
(
</span>
</span>
<span class='TupleExprElementList' data-title='"It's␣very␣cold.␣Consider␣wearing␣a␣scarf."' data-content='TupleExprElementListSyntax' data-type='Syntax' data-range='{"startRow":4,"startColumn":9,"endRow":4,"endColumn":52}'>
<span class='TupleExprElement' data-title='"It's␣very␣cold.␣Consider␣wearing␣a␣scarf."' data-content='TupleExprElementSyntax' data-type='Syntax' data-range='{"startRow":4,"startColumn":9,"endRow":4,"endColumn":52}'>
<span class='StringLiteralExpr' data-title='"It's␣very␣cold.␣Consider␣wearing␣a␣scarf."' data-content='StringLiteralExprSyntax' data-type='Syntax' data-range='{"startRow":4,"startColumn":9,"endRow":4,"endColumn":52}'>
<span class='Token' data-title='"' data-content='stringQuote' data-type='Token' data-range='{"startRow":4,"startColumn":9,"endRow":4,"endColumn":10}'>
<span class='token stringQuote present' data-title='"' data-content='stringQuote' data-type='Token' data-range='{"startRow":4,"startColumn":9,"endRow":4,"endColumn":10}'>
"
</span>
</span>
<span class='StringLiteralSegments' data-title='It's␣very␣cold.␣Consider␣wearing␣a␣scarf.' data-content='StringLiteralSegmentsSyntax' data-type='Syntax' data-range='{"startRow":4,"startColumn":10,"endRow":4,"endColumn":51}'>
<span class='StringSegment' data-title='It's␣very␣cold.␣Consider␣wearing␣a␣scarf.' data-content='StringSegmentSyntax' data-type='Syntax' data-range='{"startRow":4,"startColumn":10,"endRow":4,"endColumn":51}'>
<span class='Token' data-title='It's␣very␣cold.␣Consider␣wearing␣a␣scarf.' data-content='stringSegment("It\'s very cold. Consider wearing a scarf.")' data-type='Token' data-range='{"startRow":4,"startColumn":10,"endRow":4,"endColumn":51}'>
<span class='token stringSegment present' data-title='It's␣very␣cold.␣Consider␣wearing␣a␣scarf.' data-content='stringSegment("It\'s very cold. Consider wearing a scarf.")' data-type='Token' data-range='{"startRow":4,"startColumn":10,"endRow":4,"endColumn":51}'>
It's very cold. Consider wearing a scarf.
</span>
</span>
</span>
</span>
<span class='Token' data-title='"' data-content='stringQuote' data-type='Token' data-range='{"startRow":4,"startColumn":51,"endRow":4,"endColumn":52}'>
<span class='token stringQuote present' data-title='"' data-content='stringQuote' data-type='Token' data-range='{"startRow":4,"startColumn":51,"endRow":4,"endColumn":52}'>
"
</span>
</span>
</span>
</span>
</span>
<span class='Token' data-title=')' data-content='rightParen' data-type='Token' data-range='{"startRow":4,"startColumn":52,"endRow":4,"endColumn":53}'>
<span class='token rightParen present' data-title=')' data-content='rightParen' data-type='Token' data-range='{"startRow":4,"startColumn":52,"endRow":4,"endColumn":53}'>
)
</span>
</span>
</span>
</span>
</span>
<span class='Token' data-title='}' data-content='rightBrace' data-type='Token' data-range='{"startRow":5,"startColumn":1,"endRow":5,"endColumn":2}'>
<br/>
<span class='token rightBrace present' data-title='}' data-content='rightBrace' data-type='Token' data-range='{"startRow":5,"startColumn":1,"endRow":5,"endColumn":2}'>
}
</span>
</span>
</span>
<span class='Token' data-title='else' data-content='elseKeyword' data-type='Token' data-range='{"startRow":5,"startColumn":3,"endRow":5,"endColumn":7}'>
<span class='token keyword present' data-title='else' data-content='elseKeyword' data-type='Token' data-range='{"startRow":5,"startColumn":3,"endRow":5,"endColumn":7}'>
else
</span>
</span>
<span class='IfStmt' data-title='if␣temperatureInFahrenheit␣>=␣86␣{↲␣␣print("It's␣really␣warm.␣Don't␣forget␣to␣wear␣sunscreen.")↲}␣else␣{↲␣␣print("It's␣not␣that␣cold.␣Wear␣a␣t-shirt.")↲}' data-content='IfStmtSyntax' data-type='Syntax' data-range='{"startRow":5,"startColumn":8,"endRow":9,"endColumn":2}'>
<span class='Token' data-title='if' data-content='ifKeyword' data-type='Token' data-range='{"startRow":5,"startColumn":8,"endRow":5,"endColumn":10}'>
<span class='token keyword present' data-title='if' data-content='ifKeyword' data-type='Token' data-range='{"startRow":5,"startColumn":8,"endRow":5,"endColumn":10}'>
if
</span>
</span>
<span class='ConditionElementList' data-title='temperatureInFahrenheit␣>=␣86' data-content='ConditionElementListSyntax' data-type='Syntax' data-range='{"startRow":5,"startColumn":11,"endRow":5,"endColumn":40}'>
<span class='ConditionElement' data-title='temperatureInFahrenheit␣>=␣86' data-content='ConditionElementSyntax' data-type='Syntax' data-range='{"startRow":5,"startColumn":11,"endRow":5,"endColumn":40}'>
<span class='SequenceExpr' data-title='temperatureInFahrenheit␣>=␣86' data-content='SequenceExprSyntax' data-type='Syntax' data-range='{"startRow":5,"startColumn":11,"endRow":5,"endColumn":40}'>
<span class='ExprList' data-title='temperatureInFahrenheit␣>=␣86' data-content='ExprListSyntax' data-type='Syntax' data-range='{"startRow":5,"startColumn":11,"endRow":5,"endColumn":40}'>
<span class='IdentifierExpr' data-title='temperatureInFahrenheit' data-content='IdentifierExprSyntax' data-type='Syntax' data-range='{"startRow":5,"startColumn":11,"endRow":5,"endColumn":34}'>
<span class='Token' data-title='temperatureInFahrenheit' data-content='identifier("temperatureInFahrenheit")' data-type='Token' data-range='{"startRow":5,"startColumn":11,"endRow":5,"endColumn":34}'>
<span class='token identifier present' data-title='temperatureInFahrenheit' data-content='identifier("temperatureInFahrenheit")' data-type='Token' data-range='{"startRow":5,"startColumn":11,"endRow":5,"endColumn":34}'>
temperatureInFahrenheit
</span>
</span>
</span>
<span class='BinaryOperatorExpr' data-title='>=' data-content='BinaryOperatorExprSyntax' data-type='Syntax' data-range='{"startRow":5,"startColumn":35,"endRow":5,"endColumn":37}'>
<span class='Token' data-title='>=' data-content='spacedBinaryOperator(">=")' data-type='Token' data-range='{"startRow":5,"startColumn":35,"endRow":5,"endColumn":37}'>
<span class='token spacedBinaryOperator present' data-title='>=' data-content='spacedBinaryOperator(">=")' data-type='Token' data-range='{"startRow":5,"startColumn":35,"endRow":5,"endColumn":37}'>
>=
</span>
</span>
</span>
<span class='IntegerLiteralExpr' data-title='86' data-content='IntegerLiteralExprSyntax' data-type='Syntax' data-range='{"startRow":5,"startColumn":38,"endRow":5,"endColumn":40}'>
<span class='Token' data-title='86' data-content='integerLiteral("86")' data-type='Token' data-range='{"startRow":5,"startColumn":38,"endRow":5,"endColumn":40}'>
<span class='token integerLiteral present' data-title='86' data-content='integerLiteral("86")' data-type='Token' data-range='{"startRow":5,"startColumn":38,"endRow":5,"endColumn":40}'>
86
</span>
</span>
</span>
</span>
</span>
</span>
</span>
<span class='CodeBlock' data-title='{↲␣␣print("It's␣really␣warm.␣Don't␣forget␣to␣wear␣sunscreen.")↲}' data-content='CodeBlockSyntax' data-type='Syntax' data-range='{"startRow":5,"startColumn":41,"endRow":7,"endColumn":2}'>
<span class='Token' data-title='{' data-content='leftBrace' data-type='Token' data-range='{"startRow":5,"startColumn":41,"endRow":5,"endColumn":42}'>
<span class='token leftBrace present' data-title='{' data-content='leftBrace' data-type='Token' data-range='{"startRow":5,"startColumn":41,"endRow":5,"endColumn":42}'>
{
</span>
</span>
<span class='CodeBlockItemList' data-title='print("It's␣really␣warm.␣Don't␣forget␣to␣wear␣sunscreen.")' data-content='CodeBlockItemListSyntax' data-type='Syntax' data-range='{"startRow":6,"startColumn":3,"endRow":6,"endColumn":61}'>
<span class='CodeBlockItem' data-title='print("It's␣really␣warm.␣Don't␣forget␣to␣wear␣sunscreen.")' data-content='CodeBlockItemSyntax' data-type='Syntax' data-range='{"startRow":6,"startColumn":3,"endRow":6,"endColumn":61}'>
<span class='FunctionCallExpr' data-title='print("It's␣really␣warm.␣Don't␣forget␣to␣wear␣sunscreen.")' data-content='FunctionCallExprSyntax' data-type='Syntax' data-range='{"startRow":6,"startColumn":3,"endRow":6,"endColumn":61}'>
<span class='IdentifierExpr' data-title='print' data-content='IdentifierExprSyntax' data-type='Syntax' data-range='{"startRow":6,"startColumn":3,"endRow":6,"endColumn":8}'>
<span class='Token' data-title='print' data-content='identifier("print")' data-type='Token' data-range='{"startRow":6,"startColumn":3,"endRow":6,"endColumn":8}'>
<br/>
<span class='token identifier present' data-title='print' data-content='identifier("print")' data-type='Token' data-range='{"startRow":6,"startColumn":3,"endRow":6,"endColumn":8}'>
print
</span>
</span>
</span>
<span class='Token' data-title='(' data-content='leftParen' data-type='Token' data-range='{"startRow":6,"startColumn":8,"endRow":6,"endColumn":9}'>
<span class='token leftParen present' data-title='(' data-content='leftParen' data-type='Token' data-range='{"startRow":6,"startColumn":8,"endRow":6,"endColumn":9}'>
(
</span>
</span>
<span class='TupleExprElementList' data-title='"It's␣really␣warm.␣Don't␣forget␣to␣wear␣sunscreen."' data-content='TupleExprElementListSyntax' data-type='Syntax' data-range='{"startRow":6,"startColumn":9,"endRow":6,"endColumn":60}'>
<span class='TupleExprElement' data-title='"It's␣really␣warm.␣Don't␣forget␣to␣wear␣sunscreen."' data-content='TupleExprElementSyntax' data-type='Syntax' data-range='{"startRow":6,"startColumn":9,"endRow":6,"endColumn":60}'>
<span class='StringLiteralExpr' data-title='"It's␣really␣warm.␣Don't␣forget␣to␣wear␣sunscreen."' data-content='StringLiteralExprSyntax' data-type='Syntax' data-range='{"startRow":6,"startColumn":9,"endRow":6,"endColumn":60}'>
<span class='Token' data-title='"' data-content='stringQuote' data-type='Token' data-range='{"startRow":6,"startColumn":9,"endRow":6,"endColumn":10}'>
<span class='token stringQuote present' data-title='"' data-content='stringQuote' data-type='Token' data-range='{"startRow":6,"startColumn":9,"endRow":6,"endColumn":10}'>
"
</span>
</span>
<span class='StringLiteralSegments' data-title='It's␣really␣warm.␣Don't␣forget␣to␣wear␣sunscreen.' data-content='StringLiteralSegmentsSyntax' data-type='Syntax' data-range='{"startRow":6,"startColumn":10,"endRow":6,"endColumn":59}'>
<span class='StringSegment' data-title='It's␣really␣warm.␣Don't␣forget␣to␣wear␣sunscreen.' data-content='StringSegmentSyntax' data-type='Syntax' data-range='{"startRow":6,"startColumn":10,"endRow":6,"endColumn":59}'>
<span class='Token' data-title='It's␣really␣warm.␣Don't␣forget␣to␣wear␣sunscreen.' data-content='stringSegment("It\'s really warm. Don\'t forget to wear sunscreen.")' data-type='Token' data-range='{"startRow":6,"startColumn":10,"endRow":6,"endColumn":59}'>
<span class='token stringSegment present' data-title='It's␣really␣warm.␣Don't␣forget␣to␣wear␣sunscreen.' data-content='stringSegment("It\'s really warm. Don\'t forget to wear sunscreen.")' data-type='Token' data-range='{"startRow":6,"startColumn":10,"endRow":6,"endColumn":59}'>
It's really warm. Don't forget to wear sunscreen.
</span>
</span>
</span>
</span>
<span class='Token' data-title='"' data-content='stringQuote' data-type='Token' data-range='{"startRow":6,"startColumn":59,"endRow":6,"endColumn":60}'>
<span class='token stringQuote present' data-title='"' data-content='stringQuote' data-type='Token' data-range='{"startRow":6,"startColumn":59,"endRow":6,"endColumn":60}'>
"
</span>
</span>
</span>
</span>
</span>
<span class='Token' data-title=')' data-content='rightParen' data-type='Token' data-range='{"startRow":6,"startColumn":60,"endRow":6,"endColumn":61}'>
<span class='token rightParen present' data-title=')' data-content='rightParen' data-type='Token' data-range='{"startRow":6,"startColumn":60,"endRow":6,"endColumn":61}'>
)
</span>
</span>
</span>
</span>
</span>
<span class='Token' data-title='}' data-content='rightBrace' data-type='Token' data-range='{"startRow":7,"startColumn":1,"endRow":7,"endColumn":2}'>
<br/>
<span class='token rightBrace present' data-title='}' data-content='rightBrace' data-type='Token' data-range='{"startRow":7,"startColumn":1,"endRow":7,"endColumn":2}'>
}
</span>
</span>
</span>
<span class='Token' data-title='else' data-content='elseKeyword' data-type='Token' data-range='{"startRow":7,"startColumn":3,"endRow":7,"endColumn":7}'>
<span class='token keyword present' data-title='else' data-content='elseKeyword' data-type='Token' data-range='{"startRow":7,"startColumn":3,"endRow":7,"endColumn":7}'>
else
</span>
</span>
<span class='CodeBlock' data-title='{↲␣␣print("It's␣not␣that␣cold.␣Wear␣a␣t-shirt.")↲}' data-content='CodeBlockSyntax' data-type='Syntax' data-range='{"startRow":7,"startColumn":8,"endRow":9,"endColumn":2}'>
<span class='Token' data-title='{' data-content='leftBrace' data-type='Token' data-range='{"startRow":7,"startColumn":8,"endRow":7,"endColumn":9}'>
<span class='token leftBrace present' data-title='{' data-content='leftBrace' data-type='Token' data-range='{"startRow":7,"startColumn":8,"endRow":7,"endColumn":9}'>
{
</span>
</span>
<span class='CodeBlockItemList' data-title='print("It's␣not␣that␣cold.␣Wear␣a␣t-shirt.")' data-content='CodeBlockItemListSyntax' data-type='Syntax' data-range='{"startRow":8,"startColumn":3,"endRow":8,"endColumn":47}'>
<span class='CodeBlockItem' data-title='print("It's␣not␣that␣cold.␣Wear␣a␣t-shirt.")' data-content='CodeBlockItemSyntax' data-type='Syntax' data-range='{"startRow":8,"startColumn":3,"endRow":8,"endColumn":47}'>
<span class='FunctionCallExpr' data-title='print("It's␣not␣that␣cold.␣Wear␣a␣t-shirt.")' data-content='FunctionCallExprSyntax' data-type='Syntax' data-range='{"startRow":8,"startColumn":3,"endRow":8,"endColumn":47}'>
<span class='IdentifierExpr' data-title='print' data-content='IdentifierExprSyntax' data-type='Syntax' data-range='{"startRow":8,"startColumn":3,"endRow":8,"endColumn":8}'>
<span class='Token' data-title='print' data-content='identifier("print")' data-type='Token' data-range='{"startRow":8,"startColumn":3,"endRow":8,"endColumn":8}'>
<br/>
<span class='token identifier present' data-title='print' data-content='identifier("print")' data-type='Token' data-range='{"startRow":8,"startColumn":3,"endRow":8,"endColumn":8}'>
print
</span>
</span>
</span>
<span class='Token' data-title='(' data-content='leftParen' data-type='Token' data-range='{"startRow":8,"startColumn":8,"endRow":8,"endColumn":9}'>
<span class='token leftParen present' data-title='(' data-content='leftParen' data-type='Token' data-range='{"startRow":8,"startColumn":8,"endRow":8,"endColumn":9}'>
(
</span>
</span>
<span class='TupleExprElementList' data-title='"It's␣not␣that␣cold.␣Wear␣a␣t-shirt."' data-content='TupleExprElementListSyntax' data-type='Syntax' data-range='{"startRow":8,"startColumn":9,"endRow":8,"endColumn":46}'>
<span class='TupleExprElement' data-title='"It's␣not␣that␣cold.␣Wear␣a␣t-shirt."' data-content='TupleExprElementSyntax' data-type='Syntax' data-range='{"startRow":8,"startColumn":9,"endRow":8,"endColumn":46}'>
<span class='StringLiteralExpr' data-title='"It's␣not␣that␣cold.␣Wear␣a␣t-shirt."' data-content='StringLiteralExprSyntax' data-type='Syntax' data-range='{"startRow":8,"startColumn":9,"endRow":8,"endColumn":46}'>
<span class='Token' data-title='"' data-content='stringQuote' data-type='Token' data-range='{"startRow":8,"startColumn":9,"endRow":8,"endColumn":10}'>
<span class='token stringQuote present' data-title='"' data-content='stringQuote' data-type='Token' data-range='{"startRow":8,"startColumn":9,"endRow":8,"endColumn":10}'>
"
</span>
</span>
<span class='StringLiteralSegments' data-title='It's␣not␣that␣cold.␣Wear␣a␣t-shirt.' data-content='StringLiteralSegmentsSyntax' data-type='Syntax' data-range='{"startRow":8,"startColumn":10,"endRow":8,"endColumn":45}'>
<span class='StringSegment' data-title='It's␣not␣that␣cold.␣Wear␣a␣t-shirt.' data-content='StringSegmentSyntax' data-type='Syntax' data-range='{"startRow":8,"startColumn":10,"endRow":8,"endColumn":45}'>
<span class='Token' data-title='It's␣not␣that␣cold.␣Wear␣a␣t-shirt.' data-content='stringSegment("It\'s not that cold. Wear a t-shirt.")' data-type='Token' data-range='{"startRow":8,"startColumn":10,"endRow":8,"endColumn":45}'>
<span class='token stringSegment present' data-title='It's␣not␣that␣cold.␣Wear␣a␣t-shirt.' data-content='stringSegment("It\'s not that cold. Wear a t-shirt.")' data-type='Token' data-range='{"startRow":8,"startColumn":10,"endRow":8,"endColumn":45}'>
It's not that cold. Wear a t-shirt.
</span>
</span>
</span>
</span>
<span class='Token' data-title='"' data-content='stringQuote' data-type='Token' data-range='{"startRow":8,"startColumn":45,"endRow":8,"endColumn":46}'>
<span class='token stringQuote present' data-title='"' data-content='stringQuote' data-type='Token' data-range='{"startRow":8,"startColumn":45,"endRow":8,"endColumn":46}'>
"
</span>
</span>
</span>
</span>
</span>
<span class='Token' data-title=')' data-content='rightParen' data-type='Token' data-range='{"startRow":8,"startColumn":46,"endRow":8,"endColumn":47}'>
<span class='token rightParen present' data-title=')' data-content='rightParen' data-type='Token' data-range='{"startRow":8,"startColumn":46,"endRow":8,"endColumn":47}'>
)
</span>
</span>
</span>
</span>
</span>
<span class='Token' data-title='}' data-content='rightBrace' data-type='Token' data-range='{"startRow":9,"startColumn":1,"endRow":9,"endColumn":2}'>
<br/>
<span class='token rightBrace present' data-title='}' data-content='rightBrace' data-type='Token' data-range='{"startRow":9,"startColumn":1,"endRow":9,"endColumn":2}'>
}
</span>
</span>
</span>
</span>
</span>
</span>
</span>
<span class='Token' data-title='' data-content='eof' data-type='Token' data-range='{"startRow":11,"startColumn":62,"endRow":11,"endColumn":62}'>
<br/>
<br/>
<span class='lineComment' data-title='//␣Prints␣"It's␣really␣warm.␣Don't␣forget␣to␣wear␣sunscreen."' data-content='lineComment' data-type='Trivia'>
// Prints "It's really warm. Don't forget to wear sunscreen."
</span>
<span class='token eof present' data-title='' data-content='eof' data-type='Token' data-range='{"startRow":11,"startColumn":62,"endRow":11,"endColumn":62}'></span>
</span>
</span>
================================================
FILE: Resources/parsers/50800/Tests/Tests/Fixtures/test-1-2.json
================================================
[
{
"id": 0,
"range": {
"endColumn": 62,
"endRow": 11,
"graphemeEndColumn": 62,
"graphemeStartColumn": 1,
"startColumn": 1,
"startRow": 1
},
"structure": [
{
"name": "unexpectedBeforeStatements",
"value": {
"text": "nil"
}
},
{
"name": "statements",
"ref": "CodeBlockItemListSyntax",
"value": {
"text": "CodeBlockItemListSyntax"
}
},
{
"name": "unexpectedBetweenStatementsAndEOFToken",
"value": {
"text": "nil"
}
},
{
"name": "eofToken",
"value": {
"kind": "eof",
"text": ""
}
},
{
"name": "unexpectedAfterEOFToken",
"value": {
"text": "nil"
}
}
],
"text": "SourceFile",
"type": "other"
},
{
"id": 1,
"parent": 0,
"range": {
"endColumn": 2,
"endRow": 9,
"graphemeEndColumn": 2,
"graphemeStartColumn": 1,
"startColumn": 1,
"startRow": 1
},
"structure": [
{
"name": "Element",
"value": {
"text": "CodeBlockItemSyntax"
}
},
{
"name": "Count",
"value": {
"text": "2"
}
}
],
"text": "CodeBlockItemList",
"type": "collection"
},
{
"id": 2,
"parent": 1,
"range": {
"endColumn": 33,
"endRow": 1,
"graphemeEndColumn": 33,
"graphemeStartColumn": 1,
"startColumn": 1,
"startRow": 1
},
"structure": [
{
"name": "unexpectedBeforeItem",
"value": {
"text": "nil"
}
},
{
"name": "item",
"ref": "VariableDeclSyntax",
"value": {
"text": "VariableDeclSyntax"
}
},
{
"name": "unexpectedBetweenItemAndSemicolon",
"value": {
"text": "nil"
}
},
{
"name": "semicolon",
"value": {
"text": "nil"
}
},
{
"name": "unexpectedBetweenSemicolonAndErrorTokens",
"value": {
"text": "nil"
}
},
{
"name": "errorTokens",
"value": {
"text": "nil"
}
},
{
"name": "unexpectedAfterErrorTokens",
"value": {
"text": "nil"
}
}
],
"text": "CodeBlockItem",
"type": "other"
},
{
"id": 3,
"parent": 2,
"range": {
"endColumn": 33,
"endRow": 1,
"graphemeEndColumn": 33,
"graphemeStartColumn": 1,
"startColumn": 1,
"startRow": 1
},
"structure": [
{
"name": "unexpectedBeforeAttributes",
"value": {
"text": "nil"
}
},
{
"name": "attributes",
"value": {
"text": "nil"
}
},
{
"name": "unexpectedBetweenAttributesAndModifiers",
"value": {
"text": "nil"
}
},
{
"name": "modifiers",
"value": {
"text": "nil"
}
},
{
"name": "unexpectedBetweenModifiersAndLetOrVarKeyword",
"value": {
"text": "nil"
}
},
{
"name": "letOrVarKeyword",
"value": {
"kind": "varKeyword",
"text": "var"
}
},
{
"name": "unexpectedBetweenLetOrVarKeywordAndBindings",
"value": {
"text": "nil"
}
},
{
"name": "bindings",
"ref": "PatternBindingListSyntax",
"value": {
"text": "PatternBindingListSyntax"
}
},
{
"name": "unexpectedAfterBindings",
"value": {
"text": "nil"
}
}
],
"text": "VariableDecl",
"type": "decl"
},
{
"id": 4,
"parent": 3,
"range": {
"endColumn": 4,
"endRow": 1,
"graphemeEndColumn": 4,
"graphemeStartColumn": 1,
"startColumn": 1,
"startRow": 1
},
"structure": [],
"text": "var",
"token": {
"kind": "varKeyword",
"leadingTrivia": "",
"trailingTrivia": "<span class='whitespace'>␣</span>"
},
"type": "other"
},
{
"id": 5,
"parent": 3,
"range": {
"endColumn": 33,
"endRow": 1,
"graphemeEndColumn": 33,
"graphemeStartColumn": 5,
"startColumn": 5,
"startRow": 1
},
"structure": [
{
"name": "Element",
"value": {
"text": "PatternBindingSyntax"
}
},
{
"name": "Count",
"value": {
"text": "1"
}
}
],
"text": "PatternBindingList",
"type": "collection"
},
{
"id": 6,
"parent": 5,
"range": {
"endColumn": 33,
"endRow": 1,
"graphemeEndColumn": 33,
"graphemeStartColumn": 5,
"startColumn": 5,
"startRow": 1
},
"structure": [
{
"name": "unexpectedBeforePattern",
"value": {
"text": "nil"
}
},
{
"name": "pattern",
"ref": "IdentifierPatternSyntax",
"value": {
"text": "IdentifierPatternSyntax"
}
},
{
"name": "unexpectedBetweenPatternAndTypeAnnotation",
"value": {
"text": "nil"
}
},
{
"name": "typeAnnotation",
"value": {
"text": "nil"
}
},
{
"name": "unexpectedBetweenTypeAnnotationAndInitializer",
"value": {
"text": "nil"
}
},
{
"name": "initializer",
"ref": "InitializerClauseSyntax",
"value": {
"text": "InitializerClauseSyntax"
}
},
{
"name": "unexpectedBetweenInitializerAndAccessor",
"value": {
"text": "nil"
}
},
{
"name": "accessor",
"value": {
"text": "nil"
}
},
{
"name": "unexpectedBetweenAccessorAndTrailingComma",
"value": {
"text": "nil"
}
},
{
"name": "trailingComma",
"value": {
"text": "nil"
}
},
{
"name": "unexpectedAfterTrailingComma",
"value": {
"text": "nil"
}
}
],
"text": "PatternBinding",
"type": "other"
},
{
"id": 7,
"parent": 6,
"range": {
"endColumn": 28,
"endRow": 1,
"graphemeEndColumn": 28,
"graphemeStartColumn": 5,
"startColumn": 5,
"startRow": 1
},
"structure": [
{
"name": "unexpectedBeforeIdentifier",
"value": {
"text": "nil"
}
},
{
"name": "identifier",
"value": {
"kind": "identifier("temperatureInFahrenheit")",
"text": "temperatureInFahrenheit"
}
},
{
"name": "unexpectedAfterIdentifier",
"value": {
"text": "nil"
}
}
],
"text": "IdentifierPattern",
"type": "pattern"
},
{
"id": 8,
"parent": 7,
"range": {
"endColumn": 28,
"endRow": 1,
"graphemeEndColumn": 28,
"graphemeStartColumn": 5,
"startColumn": 5,
"startRow": 1
},
"structure": [],
"text": "temperatureInFahrenheit",
"token": {
"kind": "identifier("temperatureInFahrenheit")",
"leadingTrivia": "",
"trailingTrivia": "<span class='whitespace'>␣</span>"
},
"type": "other"
},
{
"id": 9,
"parent": 6,
"range": {
"endColumn": 33,
"endRow": 1,
"graphemeEndColumn": 33,
"graphemeStartColumn": 29,
"startColumn": 29,
"startRow": 1
},
"structure": [
{
"name": "unexpectedBeforeEqual",
"value": {
"text": "nil"
}
},
{
"name": "equal",
"value": {
"kind": "equal",
"text": "="
}
},
{
"name": "unexpectedBetweenEqualAndValue",
"value": {
"text": "nil"
}
},
{
"name": "value",
"ref": "IntegerLiteralExprSyntax",
"value": {
"text": "IntegerLiteralExprSyntax"
}
},
{
"name": "unexpectedAfterValue",
"value": {
"text": "nil"
}
}
],
"text": "InitializerClause",
"type": "other"
},
{
"id": 10,
"parent": 9,
"range": {
"endColumn": 30,
"endRow": 1,
"graphemeEndColumn": 30,
"graphemeStartColumn": 29,
"startColumn": 29,
"startRow": 1
},
"structure": [],
"text": "=",
"token": {
"kind": "equal",
"leadingTrivia": "",
"trailingTrivia": "<span class='whitespace'>␣</span>"
},
"type": "other"
},
{
"id": 11,
"parent": 9,
"range": {
"endColumn": 33,
"endRow": 1,
"graphemeEndColumn": 33,
"graphemeStartColumn": 31,
"startColumn": 31,
"startRow": 1
},
"structure": [
{
"name": "unexpectedBeforeDigits",
"value": {
"text": "nil"
}
},
{
"name": "digits",
"value": {
"kind": "integerLiteral("90")",
"text": "90"
}
},
{
"name": "unexpectedAfterDigits",
"value": {
"text": "nil"
}
}
],
"text": "IntegerLiteralExpr",
"type": "expr"
},
{
"id": 12,
"parent": 11,
"range": {
"endColumn": 33,
"endRow": 1,
"graphemeEndColumn": 33,
"graphemeStartColumn": 31,
"startColumn": 31,
"startRow": 1
},
"structure": [],
"text": "90",
"token": {
"kind": "integerLiteral("90")",
"leadingTrivia": "",
"trailingTrivia": ""
},
"type": "other"
},
{
"id": 13,
"parent": 1,
"range": {
"endColumn": 2,
"endRow": 9,
"graphemeEndColumn": 2,
"graphemeStartColumn": 1,
"startColumn": 1,
"startRow": 3
},
"structure": [
{
"name": "unexpectedBeforeItem",
"value": {
"text": "nil"
}
},
{
"name": "item",
"ref": "IfStmtSyntax",
"value": {
"text": "IfStmtSyntax"
}
},
{
"name": "unexpectedBetweenItemAndSemicolon",
"value": {
"text": "nil"
}
},
{
"name": "semicolon",
"value": {
"text": "nil"
}
},
{
"name": "unexpectedBetweenSemicolonAndErrorTokens",
"value": {
"text": "nil"
}
},
{
"name": "errorTokens",
"value": {
"text": "nil"
}
},
{
"name": "unexpectedAfterErrorTokens",
"value": {
"text": "nil"
}
}
],
"text": "CodeBlockItem",
"type": "other"
},
{
"id": 14,
"parent": 13,
"range": {
"endColumn": 2,
"endRow": 9,
"graphemeEndColumn": 2,
"graphemeStartColumn": 1,
"startColumn": 1,
"startRow": 3
},
"structure": [
{
"name": "unexpectedBeforeIfKeyword",
"value": {
"text": "nil"
}
},
{
"name": "ifKeyword",
"value": {
"kind": "ifKeyword",
"text": "if"
}
},
{
"name": "unexpectedBetweenIfKeywordAndConditions",
"value": {
"text": "nil"
}
},
{
"name": "conditions",
"ref": "ConditionElementListSyntax",
"value": {
"text": "ConditionElementListSyntax"
}
},
{
"name": "unexpectedBetweenConditionsAndBody",
"value": {
"text": "nil"
}
},
{
"name": "body",
"ref": "CodeBlockSyntax",
"value": {
"text": "CodeBlockSyntax"
}
},
{
"name": "unexpectedBetweenBodyAndElseKeyword",
"value": {
"text": "nil"
}
},
{
"name": "elseKeyword",
"value": {
"kind": "elseKeyword",
"text": "else"
}
},
{
"name": "unexpectedBetweenElseKeywordAndElseBody",
"value": {
"text": "nil"
}
},
{
"name": "elseBody",
"ref": "IfStmtSyntax",
"value": {
"text": "IfStmtSyntax"
}
},
{
"name": "unexpectedAfterElseBody",
"value": {
"text": "nil"
}
}
],
"text": "IfStmt",
"type": "other"
},
{
"id": 15,
"parent": 14,
"range": {
"endColumn": 3,
"endRow": 3,
"graphemeEndColumn": 3,
"graphemeStartColumn": 1,
"startColumn": 1,
"startRow": 3
},
"structure": [],
"text": "if",
"token": {
"kind": "ifKeyword",
"leadingTrivia": "<span class='newline'>↲</span><br/><span class='newline'>↲</span><br/>",
"trailingTrivia": "<span class='whitespace'>␣</span>"
},
"type": "other"
},
{
"id": 16,
"parent": 14,
"range": {
"endColumn": 33,
"endRow": 3,
"graphemeEndColumn": 33,
"graphemeStartColumn": 4,
"startColumn": 4,
"startRow": 3
},
"structure": [
{
"name": "Element",
"value": {
"text": "ConditionElementSyntax"
}
},
{
"name": "Count",
"value": {
"text": "1"
}
}
],
"text": "ConditionElementList",
"type": "collection"
},
{
"id": 17,
"parent": 16,
"range": {
"endColumn": 33,
"endRow": 3,
"graphemeEndColumn": 33,
"graphemeStartColumn": 4,
"startColumn": 4,
"startRow": 3
},
"structure": [
{
"name": "unexpectedBeforeCondition",
"value": {
"text": "nil"
}
},
{
"name": "condition",
"ref": "SequenceExprSyntax",
"value": {
"text": "SequenceExprSyntax"
}
},
{
"name": "unexpectedBetweenConditionAndTrailingComma",
"value": {
"text": "nil"
}
},
{
"name": "trailingComma",
"value": {
"text": "nil"
}
},
{
"name": "unexpectedAfterTrailingComma",
"value": {
"text": "nil"
}
}
],
"text": "ConditionElement",
"type": "other"
},
{
"id": 18,
"parent": 17,
"range": {
"endColumn": 33,
"endRow": 3,
"graphemeEndColumn": 33,
"graphemeStartColumn": 4,
"startColumn": 4,
"startRow": 3
},
"structure": [
{
"name": "unexpectedBeforeElements",
"value": {
"text": "nil"
}
},
{
"name": "elements",
"ref": "ExprListSyntax",
"value": {
"text": "ExprListSyntax"
}
},
{
"name": "unexpectedAfterElements",
"value": {
"text": "nil"
}
}
],
"text": "SequenceExpr",
"type": "expr"
},
{
"id": 19,
"parent": 18,
"range": {
"endColumn": 33,
"endRow": 3,
"graphemeEndColumn": 33,
"graphemeStartColumn": 4,
"startColumn": 4,
"startRow": 3
},
"structure": [
{
"name": "Element",
"value": {
"text": "ExprSyntax"
}
},
{
"name": "Count",
"value": {
"text": "3"
}
}
],
"text": "ExprList",
"type": "collection"
},
{
"id": 20,
"parent": 19,
"range": {
"endColumn": 27,
"endRow": 3,
"graphemeEndColumn": 27,
"graphemeStartColumn": 4,
"startColumn": 4,
"startRow": 3
},
"structure": [
{
"name": "unexpectedBeforeIdentifier",
"value": {
"text": "nil"
}
},
{
"name": "identifier",
"value": {
"kind": "identifier("temperatureInFahrenheit")",
"text": "temperatureInFahrenheit"
}
},
{
"name": "unexpectedBetweenIdentifierAndDeclNameArguments",
"value": {
"text": "nil"
}
},
{
"name": "declNameArguments",
"value": {
"text": "nil"
}
},
{
"name": "unexpectedAfterDeclNameArguments",
"value": {
"text": "nil"
}
}
],
"text": "IdentifierExpr",
"type": "expr"
},
{
"id": 21,
"parent": 20,
"range": {
"endColumn": 27,
"endRow": 3,
"graphemeEndColumn": 27,
"graphemeStartColumn": 4,
"startColumn": 4,
"startRow": 3
},
"structure": [],
"text": "temperatureInFahrenheit",
"token": {
"kind": "identifier("temperatureInFahrenheit")",
"leadingTrivia": "",
"trailingTrivia": "<span class='whitespace'>␣</span>"
},
"type": "other"
},
{
"id": 22,
"parent": 19,
"range": {
"endColumn": 30,
"endRow": 3,
"graphemeEndColumn": 30,
"graphemeStartColumn": 28,
"startColumn": 28,
"startRow": 3
},
"structure": [
{
"name": "unexpectedBeforeOperatorToken",
"value": {
"text": "nil"
}
},
{
"name": "operatorToken",
"value": {
"kind": "spacedBinaryOperator("<=")",
"text": "<="
}
},
{
"name": "unexpectedAfterOperatorToken",
"value": {
"text": "nil"
}
}
],
"text": "BinaryOperatorExpr",
"type": "expr"
},
{
"id": 23,
"parent": 22,
"range": {
"endColumn": 30,
"endRow": 3,
"graphemeEndColumn": 30,
"graphemeStartColumn": 28,
"startColumn": 28,
"startRow": 3
},
"structure": [],
"text": "<=",
"token": {
"kind": "spacedBinaryOperator("<=")",
"leadingTrivia": "",
"trailingTrivia": "<span class='whitespace'>␣</span>"
},
"type": "other"
},
{
"id": 24,
"parent": 19,
"range": {
"endColumn": 33,
"endRow": 3,
"graphemeEndColumn": 33,
"graphemeStartColumn": 31,
"startColumn": 31,
"startRow": 3
},
"structure": [
{
"name": "unexpectedBeforeDigits",
"value": {
"text": "nil"
}
},
{
"name": "digits",
"value": {
"kind": "integerLiteral("32")",
"text": "32"
}
},
{
"name": "unexpectedAfterDigits",
"value": {
"text": "nil"
}
}
],
"text": "IntegerLiteralExpr",
"type": "expr"
},
{
"id": 25,
"parent": 24,
"range": {
"endColumn": 33,
"endRow": 3,
"graphemeEndColumn": 33,
"graphemeStartColumn": 31,
"startColumn": 31,
"startRow": 3
},
"structure": [],
"text": "32",
"token": {
"kind": "integerLiteral("32")",
"leadingTrivia": "",
"trailingTrivia": "<span class='whitespace'>␣</span>"
},
"type": "other"
},
{
"id": 26,
"parent": 14,
"range": {
"endColumn": 2,
"endRow": 5,
"graphemeEndColumn": 2,
"graphemeStartColumn": 34,
"startColumn
gitextract_tk66xfku/ ├── .dockerignore ├── .github/ │ ├── FUNDING.yml │ ├── renovate.json │ └── workflows/ │ ├── spm.yml │ └── test.yml ├── .gitignore ├── .swiftpm/ │ └── xcode/ │ └── package.xcworkspace/ │ └── contents.xcworkspacedata ├── .vscode/ │ ├── launch.json │ └── settings.json ├── CODE_OF_CONDUCT.md ├── DEPLOYMENT.md ├── Dockerfile ├── LICENSE ├── Package.resolved ├── Package.swift ├── Public/ │ ├── css/ │ │ ├── balloon.css │ │ ├── common.css │ │ ├── editor.css │ │ ├── lookup.css │ │ ├── popover.css │ │ ├── table.css │ │ ├── tree_view.css │ │ └── trivia.css │ ├── error.html │ ├── favicons/ │ │ ├── browserconfig.xml │ │ └── site.webmanifest │ ├── index.html │ ├── index.js │ ├── js/ │ │ ├── app.js │ │ ├── balloon.js │ │ ├── debounce.js │ │ ├── editor.js │ │ ├── icon.js │ │ ├── lookup_view.js │ │ ├── popover.js │ │ ├── statistics_view.js │ │ ├── structure_view.js │ │ ├── tree_view.js │ │ ├── trivia_view.js │ │ └── websocket.js │ ├── robots.txt │ └── scss/ │ └── default.scss ├── README.md ├── Resources/ │ └── parsers/ │ ├── 50800/ │ │ ├── .swiftpm/ │ │ │ └── xcode/ │ │ │ └── package.xcworkspace/ │ │ │ └── contents.xcworkspacedata │ │ ├── Package.resolved │ │ ├── Package.swift │ │ ├── Sources/ │ │ │ └── parser/ │ │ │ ├── Main.swift │ │ │ ├── SyntaxParser.swift │ │ │ ├── SyntaxResponse.swift │ │ │ ├── TokenVisitor.swift │ │ │ ├── TreeNode.swift │ │ │ └── Version.swift │ │ └── Tests/ │ │ └── Tests/ │ │ ├── Fixtures/ │ │ │ ├── test-1-1.html │ │ │ ├── test-1-1.json │ │ │ ├── test-1-2.html │ │ │ ├── test-1-2.json │ │ │ ├── test-1-3.html │ │ │ ├── test-1-3.json │ │ │ ├── test-1-4.html │ │ │ ├── test-1-4.json │ │ │ ├── test-1-5.html │ │ │ ├── test-1-5.json │ │ │ ├── test-1-6.html │ │ │ ├── test-1-6.json │ │ │ ├── test-2-1.html │ │ │ ├── test-2-1.json │ │ │ ├── test-2-2.html │ │ │ ├── test-2-2.json │ │ │ ├── test-2-3.html │ │ │ ├── test-2-3.json │ │ │ ├── test-2-4.html │ │ │ ├── test-2-4.json │ │ │ ├── test-2-5.html │ │ │ ├── test-2-5.json │ │ │ ├── test-2-6.html │ │ │ └── test-2-6.json │ │ └── Tests.swift │ ├── 50900/ │ │ ├── .swiftpm/ │ │ │ └── xcode/ │ │ │ └── package.xcworkspace/ │ │ │ └── contents.xcworkspacedata │ │ ├── Package.resolved │ │ ├── Package.swift │ │ ├── Sources/ │ │ │ └── parser/ │ │ │ ├── SyntaxParser.swift │ │ │ ├── TokenVisitor.swift │ │ │ └── Version.swift │ │ └── Tests/ │ │ └── Tests/ │ │ └── Fixtures/ │ │ ├── test-1-1.html │ │ ├── test-1-1.json │ │ ├── test-1-2.html │ │ ├── test-1-2.json │ │ ├── test-1-3.html │ │ ├── test-1-3.json │ │ ├── test-1-4.html │ │ ├── test-1-4.json │ │ ├── test-1-5.html │ │ ├── test-1-5.json │ │ ├── test-1-6.html │ │ ├── test-1-6.json │ │ ├── test-2-1.html │ │ ├── test-2-1.json │ │ ├── test-2-2.html │ │ ├── test-2-2.json │ │ ├── test-2-3.html │ │ ├── test-2-3.json │ │ ├── test-2-4.html │ │ ├── test-2-4.json │ │ ├── test-2-5.html │ │ ├── test-2-5.json │ │ ├── test-2-6.html │ │ └── test-2-6.json │ ├── 51000/ │ │ ├── .swiftpm/ │ │ │ └── xcode/ │ │ │ └── package.xcworkspace/ │ │ │ └── contents.xcworkspacedata │ │ ├── Package.resolved │ │ ├── Package.swift │ │ ├── Sources/ │ │ │ └── parser/ │ │ │ └── Version.swift │ │ └── Tests/ │ │ └── Tests/ │ │ └── Fixtures/ │ │ ├── test-1-1.html │ │ ├── test-1-1.json │ │ ├── test-1-2.html │ │ ├── test-1-2.json │ │ ├── test-1-3.html │ │ ├── test-1-3.json │ │ ├── test-1-4.html │ │ ├── test-1-4.json │ │ ├── test-1-5.html │ │ ├── test-1-5.json │ │ ├── test-1-6.html │ │ ├── test-1-6.json │ │ ├── test-2-1.html │ │ ├── test-2-1.json │ │ ├── test-2-2.html │ │ ├── test-2-2.json │ │ ├── test-2-3.html │ │ ├── test-2-3.json │ │ ├── test-2-4.html │ │ ├── test-2-4.json │ │ ├── test-2-5.html │ │ ├── test-2-5.json │ │ ├── test-2-6.html │ │ └── test-2-6.json │ ├── 60000/ │ │ ├── Package.resolved │ │ ├── Package.swift │ │ ├── Sources/ │ │ │ └── parser/ │ │ │ └── Version.swift │ │ └── Tests/ │ │ └── Tests/ │ │ └── Fixtures/ │ │ ├── test-1-1.html │ │ ├── test-1-1.json │ │ ├── test-1-2.html │ │ ├── test-1-2.json │ │ ├── test-1-3.html │ │ ├── test-1-3.json │ │ ├── test-1-4.html │ │ ├── test-1-4.json │ │ ├── test-1-5.html │ │ ├── test-1-5.json │ │ ├── test-1-6.html │ │ ├── test-1-6.json │ │ ├── test-2-1.html │ │ ├── test-2-1.json │ │ ├── test-2-2.html │ │ ├── test-2-2.json │ │ ├── test-2-3.html │ │ ├── test-2-3.json │ │ ├── test-2-4.html │ │ ├── test-2-4.json │ │ ├── test-2-5.html │ │ ├── test-2-5.json │ │ ├── test-2-6.html │ │ └── test-2-6.json │ ├── 60100/ │ │ ├── .swiftpm/ │ │ │ └── xcode/ │ │ │ └── package.xcworkspace/ │ │ │ └── contents.xcworkspacedata │ │ ├── Package.resolved │ │ ├── Package.swift │ │ ├── Sources/ │ │ │ └── parser/ │ │ │ └── Version.swift │ │ └── Tests/ │ │ └── Tests/ │ │ └── Fixtures/ │ │ ├── test-1-1.html │ │ ├── test-1-1.json │ │ ├── test-1-2.html │ │ ├── test-1-2.json │ │ ├── test-1-3.html │ │ ├── test-1-3.json │ │ ├── test-1-4.html │ │ ├── test-1-4.json │ │ ├── test-1-5.html │ │ ├── test-1-5.json │ │ ├── test-1-6.html │ │ ├── test-1-6.json │ │ ├── test-2-1.html │ │ ├── test-2-1.json │ │ ├── test-2-2.html │ │ ├── test-2-2.json │ │ ├── test-2-3.html │ │ ├── test-2-3.json │ │ ├── test-2-4.html │ │ ├── test-2-4.json │ │ ├── test-2-5.html │ │ ├── test-2-5.json │ │ ├── test-2-6.html │ │ └── test-2-6.json │ ├── 60200/ │ │ ├── .swiftpm/ │ │ │ └── xcode/ │ │ │ └── package.xcworkspace/ │ │ │ └── contents.xcworkspacedata │ │ ├── Package.resolved │ │ ├── Package.swift │ │ ├── Sources/ │ │ │ └── parser/ │ │ │ └── Version.swift │ │ └── Tests/ │ │ └── Tests/ │ │ └── Fixtures/ │ │ ├── test-1-1.html │ │ ├── test-1-1.json │ │ ├── test-1-2.html │ │ ├── test-1-2.json │ │ ├── test-1-3.html │ │ ├── test-1-3.json │ │ ├── test-1-4.html │ │ ├── test-1-4.json │ │ ├── test-1-5.html │ │ ├── test-1-5.json │ │ ├── test-1-6.html │ │ ├── test-1-6.json │ │ ├── test-2-1.html │ │ ├── test-2-1.json │ │ ├── test-2-2.html │ │ ├── test-2-2.json │ │ ├── test-2-3.html │ │ ├── test-2-3.json │ │ ├── test-2-4.html │ │ ├── test-2-4.json │ │ ├── test-2-5.html │ │ ├── test-2-5.json │ │ ├── test-2-6.html │ │ └── test-2-6.json │ ├── 60300/ │ │ ├── .swiftpm/ │ │ │ └── xcode/ │ │ │ └── package.xcworkspace/ │ │ │ └── contents.xcworkspacedata │ │ ├── Package.resolved │ │ ├── Package.swift │ │ ├── Sources/ │ │ │ └── parser/ │ │ │ └── Version.swift │ │ └── Tests/ │ │ └── Tests/ │ │ └── Fixtures/ │ │ ├── test-1-1.html │ │ ├── test-1-1.json │ │ ├── test-1-2.html │ │ ├── test-1-2.json │ │ ├── test-1-3.html │ │ ├── test-1-3.json │ │ ├── test-1-4.html │ │ ├── test-1-4.json │ │ ├── test-1-5.html │ │ ├── test-1-5.json │ │ ├── test-1-6.html │ │ ├── test-1-6.json │ │ ├── test-2-1.html │ │ ├── test-2-1.json │ │ ├── test-2-2.html │ │ ├── test-2-2.json │ │ ├── test-2-3.html │ │ ├── test-2-3.json │ │ ├── test-2-4.html │ │ ├── test-2-4.json │ │ ├── test-2-5.html │ │ ├── test-2-5.json │ │ ├── test-2-6.html │ │ └── test-2-6.json │ └── trunk/ │ ├── .swiftpm/ │ │ └── xcode/ │ │ └── package.xcworkspace/ │ │ └── contents.xcworkspacedata │ ├── Package.resolved │ ├── Package.swift │ ├── Sources/ │ │ └── parser/ │ │ └── Version.swift │ └── Tests/ │ └── Tests/ │ └── Fixtures/ │ ├── test-1-1.html │ ├── test-1-1.json │ ├── test-1-2.html │ ├── test-1-2.json │ ├── test-1-3.html │ ├── test-1-3.json │ ├── test-1-4.html │ ├── test-1-4.json │ ├── test-1-5.html │ ├── test-1-5.json │ ├── test-1-6.html │ ├── test-1-6.json │ ├── test-2-1.html │ ├── test-2-1.json │ ├── test-2-2.html │ ├── test-2-2.json │ ├── test-2-3.html │ ├── test-2-3.json │ ├── test-2-4.html │ ├── test-2-4.json │ ├── test-2-5.html │ ├── test-2-5.json │ ├── test-2-6.html │ └── test-2-6.json ├── SECURITY.md ├── Sources/ │ └── App/ │ ├── Middlewares/ │ │ ├── CommonErrorMiddleware.swift │ │ └── CustomHeaderMiddleware.swift │ ├── configure.swift │ ├── entrypoint.swift │ └── routes.swift ├── Tests/ │ └── AppTests/ │ └── AppTests.swift ├── build_pasers.sh ├── deploy/ │ └── Dockerfile ├── dev/ │ ├── .gitignore │ ├── index.js │ ├── package.json │ └── xml-formatter/ │ ├── .eslintignore │ ├── .eslintrc.json │ ├── .gitignore │ ├── .npmignore │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── publish.sh │ ├── src/ │ │ ├── index.d.ts │ │ └── index.ts │ ├── test/ │ │ ├── .eslintrc.json │ │ ├── browser/ │ │ │ ├── README.md │ │ │ └── index.html │ │ ├── data1/ │ │ │ ├── xml1-input.xml │ │ │ ├── xml1-output.xml │ │ │ ├── xml2-input.xml │ │ │ ├── xml2-output.xml │ │ │ ├── xml3-input.xml │ │ │ ├── xml3-output.xml │ │ │ ├── xml4-input.xml │ │ │ └── xml4-output.xml │ │ ├── data10/ │ │ │ ├── xml1-input.xml │ │ │ └── xml1-output.xml │ │ ├── data11/ │ │ │ ├── xml1-input.xml │ │ │ ├── xml1-output.xml │ │ │ ├── xml2-input.xml │ │ │ └── xml2-output.xml │ │ ├── data12/ │ │ │ ├── xml1-input.xml │ │ │ └── xml1-output.xml │ │ ├── data13/ │ │ │ ├── xml1-input.xml │ │ │ └── xml1-output.xml │ │ ├── data14/ │ │ │ ├── xml1-input.xml │ │ │ └── xml1-output.xml │ │ ├── data2/ │ │ │ ├── xml1-input.xml │ │ │ ├── xml1-output.xml │ │ │ ├── xml2-input.xml │ │ │ ├── xml2-output.xml │ │ │ ├── xml3-input.xml │ │ │ ├── xml3-output.xml │ │ │ ├── xml4-input.xml │ │ │ └── xml4-output.xml │ │ ├── data3/ │ │ │ ├── xml1-input.xml │ │ │ ├── xml1-output.xml │ │ │ ├── xml2-input.xml │ │ │ ├── xml2-output.xml │ │ │ ├── xml3-input.xml │ │ │ ├── xml3-output.xml │ │ │ ├── xml4-input.xml │ │ │ ├── xml4-output.xml │ │ │ ├── xml5-input.xml │ │ │ ├── xml5-output.xml │ │ │ ├── xml6-input.xml │ │ │ ├── xml6-output.xml │ │ │ ├── xml7-input.xml │ │ │ └── xml7-output.xml │ │ ├── data4/ │ │ │ ├── xml1-input.xml │ │ │ ├── xml1-output.xml │ │ │ ├── xml2-input.xml │ │ │ ├── xml2-output.xml │ │ │ ├── xml3-input.xml │ │ │ ├── xml3-output.xml │ │ │ ├── xml4-input.xml │ │ │ ├── xml4-output.xml │ │ │ ├── xml5-input.xml │ │ │ └── xml5-output.xml │ │ ├── data5/ │ │ │ ├── xml1-input.xml │ │ │ └── xml1-output.xml │ │ ├── data6/ │ │ │ ├── xml1-input.xml │ │ │ ├── xml1-output.xml │ │ │ ├── xml2-input.xml │ │ │ └── xml2-output.xml │ │ ├── data7/ │ │ │ ├── xml1-input.xml │ │ │ └── xml1-output.xml │ │ ├── data8/ │ │ │ ├── xml1-input.xml │ │ │ └── xml1-output.xml │ │ ├── data9/ │ │ │ ├── xml1-input.xml │ │ │ ├── xml1-output.xml │ │ │ ├── xml2-input.xml │ │ │ ├── xml2-output.xml │ │ │ ├── xml3-input.xml │ │ │ ├── xml3-output.xml │ │ │ ├── xml4-input.xml │ │ │ └── xml4-output.xml │ │ └── index.ts │ └── tsconfig.json ├── package.json ├── webpack.common.js ├── webpack.dev.js └── webpack.prod.js
SYMBOL INDEX (100 symbols across 14 files)
FILE: Public/js/app.js
class App (line 13) | class App {
method contentViewHeight (line 14) | get contentViewHeight() {
method constructor (line 21) | constructor() {
method init (line 41) | init() {
method update (line 111) | update() {
method updateStructure (line 153) | updateStructure() {
method updateLookup (line 191) | updateLookup() {
method updateTrivia (line 199) | updateTrivia() {
method updateStatistics (line 207) | updateStatistics() {
method onresize (line 279) | onresize() {
function branchOptions (line 294) | function branchOptions() {
function parserOptions (line 306) | function parserOptions() {
function showLoading (line 318) | function showLoading() {
function hideLoading (line 324) | function hideLoading() {
function formatRange (line 330) | function formatRange(range) {
FILE: Public/js/balloon.js
class Balloon (line 5) | class Balloon {
method constructor (line 6) | constructor() {
method init (line 11) | init() {
method setContent (line 16) | setContent(content) {
method show (line 21) | show(rect, options = {}) {
method hide (line 91) | hide() {
FILE: Public/js/debounce.js
function debounce (line 3) | function debounce(cb, delay = 250) {
FILE: Public/js/editor.js
class Editor (line 11) | class Editor {
method constructor (line 12) | constructor(container) {
method init (line 17) | init() {
method getValue (line 45) | getValue() {
method setValue (line 49) | setValue(value) {
method setSelection (line 53) | setSelection(range) {
method markText (line 61) | markText(range) {
method clearMarks (line 73) | clearMarks() {
method charCoords (line 79) | charCoords(range, mode = "page") {
method focus (line 86) | focus() {
method refresh (line 90) | refresh() {
method on (line 94) | on(event, callback) {
FILE: Public/js/lookup_view.js
class LookupView (line 6) | class LookupView {
method error (line 7) | set error(error) {
method constructor (line 11) | constructor(container) {
method update (line 16) | update(syntaxHTML) {
method createDOMRectElement (line 117) | createDOMRectElement(domRect) {
method removeDOMRectElement (line 137) | removeDOMRectElement() {
function escapeHTML (line 145) | function escapeHTML(text) {
FILE: Public/js/popover.js
class Popover (line 5) | class Popover {
method constructor (line 6) | constructor() {
method init (line 17) | init() {
method setContent (line 44) | setContent(content) {
method show (line 52) | show(target, options = {}) {
method hide (line 81) | hide() {
FILE: Public/js/statistics_view.js
class StatisticsView (line 8) | class StatisticsView {
method error (line 9) | set error(error) {
method constructor (line 13) | constructor(container) {
method update (line 20) | update(statistics) {
FILE: Public/js/structure_view.js
class StructureView (line 6) | class StructureView {
method error (line 7) | set error(error) {
method constructor (line 11) | constructor(container) {
method init (line 21) | init() {
method update (line 25) | update(structureData) {
function makeSyntaxPopoverContent (line 66) | function makeSyntaxPopoverContent(data) {
function makeTokenPopoverContent (line 88) | function makeTokenPopoverContent(data) {
function makeSourceRangePopoverContent (line 111) | function makeSourceRangePopoverContent(data, list) {
function makePropertyPopoverContent (line 117) | function makePropertyPopoverContent(property, list) {
function makeDescriptionList (line 133) | function makeDescriptionList(term, details, list) {
function makeSyntaxTypeBadge (line 144) | function makeSyntaxTypeBadge(type) {
FILE: Public/js/tree_view.js
class TreeView (line 5) | class TreeView {
method constructor (line 6) | constructor(container, tree) {
method init (line 20) | init() {
method renderTree (line 30) | renderTree(container, tree) {
method renderNode (line 40) | renderNode(node) {
method hasChildren (line 96) | hasChildren(id) {
method getChildren (line 102) | getChildren(id) {
method open (line 108) | open(node, li) {
method collapse (line 126) | collapse(node, li) {
method onclick (line 138) | onclick(event, node, li) {
FILE: Public/js/trivia_view.js
class TriviaView (line 6) | class TriviaView {
method error (line 7) | set error(error) {
method constructor (line 11) | constructor(container) {
method update (line 16) | update(syntaxHTML) {
method createDOMRectElement (line 144) | createDOMRectElement(domRect) {
method removeDOMRectElement (line 163) | removeDOMRectElement() {
FILE: Public/js/websocket.js
class WebSocketClient (line 5) | class WebSocketClient {
method constructor (line 6) | constructor(endpoint) {
method isReady (line 13) | get isReady() {
method send (line 17) | send(params) {
method createConnection (line 22) | createConnection(endpoint) {
FILE: dev/xml-formatter/src/index.d.ts
type FormatOptions (line 1) | type FormatOptions = {
FILE: dev/xml-formatter/src/index.ts
type XMLFormatterOptions (line 9) | type XMLFormatterOptions = {
type XMLFormatterMinifyOptions (line 61) | type XMLFormatterMinifyOptions = Omit<XMLFormatterOptions, 'lineSeparato...
type XMLFormatterState (line 63) | type XMLFormatterState = {
function newLine (line 70) | function newLine(state: XMLFormatterState): void {
function indent (line 79) | function indent(state: XMLFormatterState): void {
function appendContent (line 87) | function appendContent(state: XMLFormatterState, content: string): void {
function processNode (line 91) | function processNode(node: XmlParserNode, state: XMLFormatterState, pres...
function processContent (line 103) | function processContent(content: string, state: XMLFormatterState, prese...
function isPathMatchingIgnoredPaths (line 120) | function isPathMatchingIgnoredPaths(path: string[], ignoredPaths: string...
function processElementNode (line 126) | function processElementNode(node: XmlParserElementNode, state: XMLFormat...
function processAttributes (line 208) | function processAttributes(state: XMLFormatterState, attributes: Record<...
function processProcessingIntruction (line 214) | function processProcessingIntruction(node: XmlParserProcessingInstructio...
function formatXml (line 227) | function formatXml(xml: string, options: XMLFormatterOptions = {}): stri...
FILE: dev/xml-formatter/test/index.ts
function assertFormatError (line 9) | function assertFormatError(src: string, formatterOptions: XMLFormatterOp...
function assertFormat (line 32) | function assertFormat(src: string, formatterOptions: XMLFormatterOptions...
function assertMinifyFormat (line 54) | function assertMinifyFormat(src: string, formatterOptions: XMLFormatterM...
Copy disabled (too large)
Download .json
Condensed preview — 375 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (13,508K chars).
[
{
"path": ".dockerignore",
"chars": 18,
"preview": ".build/\n.swiftpm/\n"
},
{
"path": ".github/FUNDING.yml",
"chars": 25,
"preview": "github: kishikawakatsumi\n"
},
{
"path": ".github/renovate.json",
"chars": 212,
"preview": "{\n \"extends\": [\n \"config:recommended\"\n ],\n \"packageRules\": [\n {\n \"matchUpdateTypes\": [\n \"minor\",\n "
},
{
"path": ".github/workflows/spm.yml",
"chars": 1308,
"preview": "name: Update Swift Package\n\non:\n schedule:\n - cron: \"30 22 * * *\"\n workflow_dispatch:\n\njobs:\n update:\n runs-on:"
},
{
"path": ".github/workflows/test.yml",
"chars": 1301,
"preview": "name: Test\non:\n pull_request:\n branches: [master]\n workflow_dispatch:\n\nenv:\n FONTAWESOME_TOKEN: ${{ secrets.FONTAW"
},
{
"path": ".gitignore",
"chars": 4741,
"preview": "### https://raw.github.com/github/gitignore/991e760c1c6d50fdda246e0178b9c58b06770b90/Global/macOS.gitignore\n\n# General\n."
},
{
"path": ".swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata",
"chars": 135,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:\">\n </FileRef"
},
{
"path": ".vscode/launch.json",
"chars": 677,
"preview": "{\n \"configurations\": [\n {\n \"type\": \"swift\",\n \"request\": \"launch\",\n \"sourceLanguages\": [\"swift\"],\n "
},
{
"path": ".vscode/settings.json",
"chars": 144,
"preview": "{\n \"lldb.library\": \"/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/LLDB\",\n \"lldb.launch.e"
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 5257,
"preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participa"
},
{
"path": "DEPLOYMENT.md",
"chars": 1024,
"preview": "# Deployment Instructions\n\n## Prerequisites\n\nBefore deploying, make sure you have the following software installed on yo"
},
{
"path": "Dockerfile",
"chars": 2360,
"preview": "FROM node:lts-slim as node\n\nWORKDIR /build\n\nARG FONTAWESOME_TOKEN\nCOPY package*.json ./\nRUN echo \"@fortawesome:registry="
},
{
"path": "LICENSE",
"chars": 11357,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "Package.resolved",
"chars": 8877,
"preview": "{\n \"pins\" : [\n {\n \"identity\" : \"async-http-client\",\n \"kind\" : \"remoteSourceControl\",\n \"location\" : \"h"
},
{
"path": "Package.swift",
"chars": 952,
"preview": "// swift-tools-version:5.8\nimport PackageDescription\n\nlet package = Package(\n name: \"swift-ast-explorer\",\n platforms: "
},
{
"path": "Public/css/balloon.css",
"chars": 1532,
"preview": ".balloon {\n font-size: 80%;\n white-space: nowrap;\n border-radius: 4px;\n background-color: rgba(85, 85, 85, 0.9);\n c"
},
{
"path": "Public/css/common.css",
"chars": 827,
"preview": ".svg-inline--fa.fa-fw {\n width: 1em;\n}\n\n.nav-tabs {\n border-bottom: none;\n}\n\n.dropdown-menu {\n min-width: 260px;\n li"
},
{
"path": "Public/css/editor.css",
"chars": 568,
"preview": ".CodeMirror {\n font-family: Menlo, Consolas, \"DejaVu Sans Mono\", \"Ubuntu Mono\", monospace;\n font-size: 11pt;\n line-he"
},
{
"path": "Public/css/lookup.css",
"chars": 450,
"preview": ".keyword,\n.atSign {\n color: #c800a4;\n}\n\n.importKeyword {\n color: #1c00cf;\n}\n\n.stringLiteral {\n color: #df0002;\n}\n\n.St"
},
{
"path": "Public/css/popover.css",
"chars": 1817,
"preview": ".popover {\n position: absolute;\n z-index: 1070;\n font-size: 10pt;\n box-shadow: 0 8px 24px rgba(140, 149, 159, 0.2);\n"
},
{
"path": "Public/css/table.css",
"chars": 107,
"preview": "table.dataTable {\n margin-top: 0 !important;\n}\n\nth.statistics_count {\n text-align: initial !important;\n}\n"
},
{
"path": "Public/css/tree_view.css",
"chars": 2061,
"preview": ".tree-view {\n font-family: Menlo, Consolas, \"DejaVu Sans Mono\", \"Ubuntu Mono\", monospace;\n font-size: 11pt;\n}\n\n.tree-v"
},
{
"path": "Public/css/trivia.css",
"chars": 189,
"preview": "#trivia-container span.leading-trivia {\n background-color: #c8e1c8;\n}\n\n#trivia-container span.trailing-trivia {\n backg"
},
{
"path": "Public/error.html",
"chars": 6664,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n <!-- Simple HttpErrorPages | MIT License | https://github.com/AndiDittrich/Ht"
},
{
"path": "Public/favicons/browserconfig.xml",
"chars": 255,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<browserconfig>\n <msapplication>\n <tile>\n <square150x150logo"
},
{
"path": "Public/favicons/site.webmanifest",
"chars": 444,
"preview": "{\n \"name\": \"\",\n \"short_name\": \"\",\n \"icons\": [\n {\n \"src\": \"/favicons/android-chrome-192x192.pn"
},
{
"path": "Public/index.html",
"chars": 14929,
"preview": "<!doctype html>\n<html lang=\"en\">\n\n<head>\n <meta charset=\"utf-8\">\n\n <meta name=\"twitter:card\" content=\"summary\" />\n <m"
},
{
"path": "Public/index.js",
"chars": 143,
"preview": "\"use strict\";\n\nimport \"./scss/default.scss\";\nimport \"./css/common.css\";\n\nimport \"./js/icon.js\";\n\nimport { App } from \"./"
},
{
"path": "Public/js/app.js",
"chars": 9693,
"preview": "\"use strict\";\n\nimport { Tooltip } from \"bootstrap\";\nimport { Editor } from \"./editor.js\";\nimport { Balloon } from \"./bal"
},
{
"path": "Public/js/balloon.js",
"chars": 2407,
"preview": "\"use strict\";\n\nimport \"../css/balloon.css\";\n\nexport class Balloon {\n constructor() {\n this.balloon = document.create"
},
{
"path": "Public/js/debounce.js",
"chars": 199,
"preview": "\"use strict\";\n\nexport function debounce(cb, delay = 250) {\n let timeout;\n return (...args) => {\n clearTimeout(timeo"
},
{
"path": "Public/js/editor.js",
"chars": 2165,
"preview": "\"use strict\";\n\nimport \"codemirror/lib/codemirror.css\";\nimport \"../css/editor.css\";\n\nimport CodeMirror from \"codemirror\";"
},
{
"path": "Public/js/icon.js",
"chars": 1026,
"preview": "\"use strict\";\n\nimport { library, dom } from \"@fortawesome/fontawesome-svg-core\";\nimport {\n faPlay,\n faEraser,\n faAlig"
},
{
"path": "Public/js/lookup_view.js",
"chars": 4951,
"preview": "\"use strict\";\n\nimport \"../css/lookup.css\";\nimport { Popover } from \"./popover.js\";\n\nexport class LookupView {\n set erro"
},
{
"path": "Public/js/popover.js",
"chars": 2192,
"preview": "\"use strict\";\n\nimport \"../css/popover.css\";\n\nexport class Popover {\n constructor() {\n this.popover = document.create"
},
{
"path": "Public/js/statistics_view.js",
"chars": 1898,
"preview": "\"use strict\";\n\nimport DataTable from \"datatables.net\";\nimport \"datatables.net-bs5/css/dataTables.bootstrap5.min.css\";\n\ni"
},
{
"path": "Public/js/structure_view.js",
"chars": 4421,
"preview": "\"use strict\";\n\nimport { TreeView } from \"./tree_view.js\";\nimport { Popover } from \"./popover.js\";\n\nexport class Structur"
},
{
"path": "Public/js/tree_view.js",
"chars": 3444,
"preview": "\"use strict\";\n\nimport \"../css/tree_view.css\";\n\nexport class TreeView {\n constructor(container, tree) {\n this.contain"
},
{
"path": "Public/js/trivia_view.js",
"chars": 7208,
"preview": "\"use strict\";\n\nimport \"../css/trivia.css\";\nimport { Popover } from \"./popover.js\";\n\nexport class TriviaView {\n set erro"
},
{
"path": "Public/js/websocket.js",
"chars": 1244,
"preview": "\"use strict\";\n\nimport ReconnectingWebSocket from \"reconnecting-websocket\";\n\nexport class WebSocketClient {\n constructor"
},
{
"path": "Public/robots.txt",
"chars": 0,
"preview": ""
},
{
"path": "Public/scss/default.scss",
"chars": 785,
"preview": "@import \"bootstrap/scss/functions\";\n@import \"bootstrap/scss/variables\";\n@import \"bootstrap/scss/variables-dark\";\n@import"
},
{
"path": "README.md",
"chars": 2174,
"preview": "<p>\n<img src=\"https://img.shields.io/badge/os-macOS/Linux-green.svg?style=flat\" alt=\"macOS/Linux\">\n<a href=\"http://swift"
},
{
"path": "Resources/parsers/50800/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata",
"chars": 135,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:\">\n </FileRef"
},
{
"path": "Resources/parsers/50800/Package.resolved",
"chars": 304,
"preview": "{\n \"pins\" : [\n {\n \"identity\" : \"swift-syntax\",\n \"kind\" : \"remoteSourceControl\",\n \"location\" : \"https:"
},
{
"path": "Resources/parsers/50800/Package.swift",
"chars": 793,
"preview": "// swift-tools-version:5.8\nimport PackageDescription\n\nlet package = Package(\n name: \"parser\",\n platforms: [\n .macOS"
},
{
"path": "Resources/parsers/50800/Sources/parser/Main.swift",
"chars": 663,
"preview": "import Foundation\n\n@main\nstruct Main {\n static func main() throws {\n do {\n let code = String(decoding: FileHand"
},
{
"path": "Resources/parsers/50800/Sources/parser/SyntaxParser.swift",
"chars": 911,
"preview": "import Foundation\nimport SwiftSyntax\nimport SwiftOperators\nimport SwiftParser\n\nstruct SyntaxParser {\n static func parse"
},
{
"path": "Resources/parsers/50800/Sources/parser/SyntaxResponse.swift",
"chars": 131,
"preview": "import Foundation\n\nstruct SyntaxResponse: Codable {\n let syntaxHTML: String\n let syntaxJSON: String\n let swiftVersion"
},
{
"path": "Resources/parsers/50800/Sources/parser/TokenVisitor.swift",
"chars": 10484,
"preview": "import Foundation\nimport SwiftSyntax\n\nfinal class TokenVisitor: SyntaxRewriter {\n var list = [String]()\n var tree = [T"
},
{
"path": "Resources/parsers/50800/Sources/parser/TreeNode.swift",
"chars": 3801,
"preview": "import Foundation\n\nfinal class TreeNode: Codable {\n let id: Int\n var parent: Int?\n\n var text: String\n var range = Ra"
},
{
"path": "Resources/parsers/50800/Sources/parser/Version.swift",
"chars": 40,
"preview": "import Foundation\nlet version = \"5.8.1\"\n"
},
{
"path": "Resources/parsers/50800/Tests/Tests/Fixtures/test-1-1.html",
"chars": 3470,
"preview": "<span class='SourceFile' data-title='let␣number␣=␣0' data-content='SourceFileSyntax' data-type='Syntax' data-range='{\"st"
},
{
"path": "Resources/parsers/50800/Tests/Tests/Fixtures/test-1-1.json",
"chars": 10334,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 15,\n \"endRow\": 1,\n \"graphemeEndColumn\": 15,\n \"graphe"
},
{
"path": "Resources/parsers/50800/Tests/Tests/Fixtures/test-1-2.html",
"chars": 29452,
"preview": "<span class='SourceFile' data-title='var␣temperatureInFahrenheit␣=␣90↲↲if␣temperatureInFahrenheit␣<=␣32␣{↲␣␣print(&qu"
},
{
"path": "Resources/parsers/50800/Tests/Tests/Fixtures/test-1-2.json",
"chars": 72690,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 62,\n \"endRow\": 11,\n \"graphemeEndColumn\": 62,\n \"graph"
},
{
"path": "Resources/parsers/50800/Tests/Tests/Fixtures/test-1-3.html",
"chars": 137193,
"preview": "<span class='SourceFile' data-title='import␣Foundation↲↲struct␣BlackjackCard␣{↲␣␣//␣nested␣Suit␣enumeration↲␣␣enum␣Suit:"
},
{
"path": "Resources/parsers/50800/Tests/Tests/Fixtures/test-1-3.json",
"chars": 340654,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 1,\n \"endRow\": 45,\n \"graphemeEndColumn\": 1,\n \"graphem"
},
{
"path": "Resources/parsers/50800/Tests/Tests/Fixtures/test-1-4.html",
"chars": 11454,
"preview": "<span class='SourceFile' data-title='struct␣Result<␣{{↲␣␣let␣text:␣String↲␣␣let␣someOtherThing:␣String↲}' data-conten"
},
{
"path": "Resources/parsers/50800/Tests/Tests/Fixtures/test-1-4.json",
"chars": 33604,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 2,\n \"endRow\": 4,\n \"graphemeEndColumn\": 2,\n \"grapheme"
},
{
"path": "Resources/parsers/50800/Tests/Tests/Fixtures/test-1-5.html",
"chars": 6780,
"preview": "<span class='SourceFile' data-title='if␣a␣+␣b␣*␣c␣{↲␣␣return↲}' data-content='SourceFileSyntax' data-type='Syntax' data-"
},
{
"path": "Resources/parsers/50800/Tests/Tests/Fixtures/test-1-5.json",
"chars": 18625,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 2,\n \"endRow\": 3,\n \"graphemeEndColumn\": 2,\n \"grapheme"
},
{
"path": "Resources/parsers/50800/Tests/Tests/Fixtures/test-1-6.html",
"chars": 6780,
"preview": "<span class='SourceFile' data-title='if␣a␣+␣b␣×␣c␣{↲␣␣return↲}' data-content='SourceFileSyntax' data-type='Syntax' data-"
},
{
"path": "Resources/parsers/50800/Tests/Tests/Fixtures/test-1-6.json",
"chars": 18625,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 2,\n \"endRow\": 3,\n \"graphemeEndColumn\": 2,\n \"grapheme"
},
{
"path": "Resources/parsers/50800/Tests/Tests/Fixtures/test-2-1.html",
"chars": 3470,
"preview": "<span class='SourceFile' data-title='let␣number␣=␣0' data-content='SourceFileSyntax' data-type='Syntax' data-range='{\"st"
},
{
"path": "Resources/parsers/50800/Tests/Tests/Fixtures/test-2-1.json",
"chars": 10334,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 15,\n \"endRow\": 1,\n \"graphemeEndColumn\": 15,\n \"graphe"
},
{
"path": "Resources/parsers/50800/Tests/Tests/Fixtures/test-2-2.html",
"chars": 29077,
"preview": "<span class='SourceFile' data-title='var␣temperatureInFahrenheit␣=␣90↲↲if␣temperatureInFahrenheit␣<=␣32␣{↲␣␣print(&qu"
},
{
"path": "Resources/parsers/50800/Tests/Tests/Fixtures/test-2-2.json",
"chars": 73012,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 62,\n \"endRow\": 11,\n \"graphemeEndColumn\": 62,\n \"graph"
},
{
"path": "Resources/parsers/50800/Tests/Tests/Fixtures/test-2-3.html",
"chars": 136792,
"preview": "<span class='SourceFile' data-title='import␣Foundation↲↲struct␣BlackjackCard␣{↲␣␣//␣nested␣Suit␣enumeration↲␣␣enum␣Suit:"
},
{
"path": "Resources/parsers/50800/Tests/Tests/Fixtures/test-2-3.json",
"chars": 340966,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 1,\n \"endRow\": 45,\n \"graphemeEndColumn\": 1,\n \"graphem"
},
{
"path": "Resources/parsers/50800/Tests/Tests/Fixtures/test-2-4.html",
"chars": 11454,
"preview": "<span class='SourceFile' data-title='struct␣Result<␣{{↲␣␣let␣text:␣String↲␣␣let␣someOtherThing:␣String↲}' data-conten"
},
{
"path": "Resources/parsers/50800/Tests/Tests/Fixtures/test-2-4.json",
"chars": 33604,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 2,\n \"endRow\": 4,\n \"graphemeEndColumn\": 2,\n \"grapheme"
},
{
"path": "Resources/parsers/50800/Tests/Tests/Fixtures/test-2-5.html",
"chars": 6804,
"preview": "<span class='SourceFile' data-title='if␣a␣+␣b␣*␣c␣{↲␣␣return↲}' data-content='SourceFileSyntax' data-type='Syntax' data-"
},
{
"path": "Resources/parsers/50800/Tests/Tests/Fixtures/test-2-5.json",
"chars": 20068,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 2,\n \"endRow\": 3,\n \"graphemeEndColumn\": 2,\n \"grapheme"
},
{
"path": "Resources/parsers/50800/Tests/Tests/Fixtures/test-2-6.html",
"chars": 6803,
"preview": "<span class='SourceFile' data-title='if␣a␣+␣b␣×␣c␣{↲␣␣return↲}' data-content='SourceFileSyntax' data-type='Syntax' data-"
},
{
"path": "Resources/parsers/50800/Tests/Tests/Fixtures/test-2-6.json",
"chars": 20063,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 2,\n \"endRow\": 3,\n \"graphemeEndColumn\": 2,\n \"grapheme"
},
{
"path": "Resources/parsers/50800/Tests/Tests/Tests.swift",
"chars": 13470,
"preview": "@testable import parser\nimport XCTest\n\nfinal class Tests: XCTestCase {\n func testParser1() throws {\n let response = "
},
{
"path": "Resources/parsers/50900/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata",
"chars": 135,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:\">\n </FileRef"
},
{
"path": "Resources/parsers/50900/Package.resolved",
"chars": 304,
"preview": "{\n \"pins\" : [\n {\n \"identity\" : \"swift-syntax\",\n \"kind\" : \"remoteSourceControl\",\n \"location\" : \"https:"
},
{
"path": "Resources/parsers/50900/Package.swift",
"chars": 793,
"preview": "// swift-tools-version:5.9\nimport PackageDescription\n\nlet package = Package(\n name: \"parser\",\n platforms: [\n .macOS"
},
{
"path": "Resources/parsers/50900/Sources/parser/SyntaxParser.swift",
"chars": 915,
"preview": "import Foundation\nimport SwiftSyntax\nimport SwiftOperators\nimport SwiftParser\n\nstruct SyntaxParser {\n static func parse"
},
{
"path": "Resources/parsers/50900/Sources/parser/TokenVisitor.swift",
"chars": 9757,
"preview": "import Foundation\n@_spi(RawSyntax) import SwiftSyntax\n\nfinal class TokenVisitor: SyntaxRewriter {\n var list = [String]("
},
{
"path": "Resources/parsers/50900/Sources/parser/Version.swift",
"chars": 40,
"preview": "import Foundation\nlet version = \"5.9.0\"\n"
},
{
"path": "Resources/parsers/50900/Tests/Tests/Fixtures/test-1-1.html",
"chars": 3884,
"preview": "<span class='SourceFile' data-title='let␣number␣=␣0' data-content='SourceFileSyntax' data-type='Syntax' data-range='{\"st"
},
{
"path": "Resources/parsers/50900/Tests/Tests/Fixtures/test-1-1.json",
"chars": 11511,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 15,\n \"endRow\": 1,\n \"graphemeEndColumn\": 15,\n \"graphe"
},
{
"path": "Resources/parsers/50900/Tests/Tests/Fixtures/test-1-2.html",
"chars": 31125,
"preview": "<span class='SourceFile' data-title='var␣temperatureInFahrenheit␣=␣90↲↲if␣temperatureInFahrenheit␣<=␣32␣{↲␣␣print(&qu"
},
{
"path": "Resources/parsers/50900/Tests/Tests/Fixtures/test-1-2.json",
"chars": 75537,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 62,\n \"endRow\": 11,\n \"graphemeEndColumn\": 62,\n \"graph"
},
{
"path": "Resources/parsers/50900/Tests/Tests/Fixtures/test-1-3.html",
"chars": 147678,
"preview": "<span class='SourceFile' data-title='import␣Foundation↲↲struct␣BlackjackCard␣{↲␣␣//␣nested␣Suit␣enumeration↲␣␣enum␣Suit:"
},
{
"path": "Resources/parsers/50900/Tests/Tests/Fixtures/test-1-3.json",
"chars": 368098,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 1,\n \"endRow\": 45,\n \"graphemeEndColumn\": 1,\n \"graphem"
},
{
"path": "Resources/parsers/50900/Tests/Tests/Fixtures/test-1-4.html",
"chars": 12647,
"preview": "<span class='SourceFile' data-title='struct␣Result<␣{{↲␣␣let␣text:␣String↲␣␣let␣someOtherThing:␣String↲}' data-conten"
},
{
"path": "Resources/parsers/50900/Tests/Tests/Fixtures/test-1-4.json",
"chars": 36273,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 2,\n \"endRow\": 4,\n \"graphemeEndColumn\": 2,\n \"grapheme"
},
{
"path": "Resources/parsers/50900/Tests/Tests/Fixtures/test-1-5.html",
"chars": 7069,
"preview": "<span class='SourceFile' data-title='if␣a␣+␣b␣*␣c␣{↲␣␣return↲}' data-content='SourceFileSyntax' data-type='Syntax' data-"
},
{
"path": "Resources/parsers/50900/Tests/Tests/Fixtures/test-1-5.json",
"chars": 19070,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 2,\n \"endRow\": 3,\n \"graphemeEndColumn\": 2,\n \"grapheme"
},
{
"path": "Resources/parsers/50900/Tests/Tests/Fixtures/test-1-6.html",
"chars": 7069,
"preview": "<span class='SourceFile' data-title='if␣a␣+␣b␣×␣c␣{↲␣␣return↲}' data-content='SourceFileSyntax' data-type='Syntax' data-"
},
{
"path": "Resources/parsers/50900/Tests/Tests/Fixtures/test-1-6.json",
"chars": 19070,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 2,\n \"endRow\": 3,\n \"graphemeEndColumn\": 2,\n \"grapheme"
},
{
"path": "Resources/parsers/50900/Tests/Tests/Fixtures/test-2-1.html",
"chars": 3884,
"preview": "<span class='SourceFile' data-title='let␣number␣=␣0' data-content='SourceFileSyntax' data-type='Syntax' data-range='{\"st"
},
{
"path": "Resources/parsers/50900/Tests/Tests/Fixtures/test-2-1.json",
"chars": 11511,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 15,\n \"endRow\": 1,\n \"graphemeEndColumn\": 15,\n \"graphe"
},
{
"path": "Resources/parsers/50900/Tests/Tests/Fixtures/test-2-2.html",
"chars": 30750,
"preview": "<span class='SourceFile' data-title='var␣temperatureInFahrenheit␣=␣90↲↲if␣temperatureInFahrenheit␣<=␣32␣{↲␣␣print(&qu"
},
{
"path": "Resources/parsers/50900/Tests/Tests/Fixtures/test-2-2.json",
"chars": 75828,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 62,\n \"endRow\": 11,\n \"graphemeEndColumn\": 62,\n \"graph"
},
{
"path": "Resources/parsers/50900/Tests/Tests/Fixtures/test-2-3.html",
"chars": 147277,
"preview": "<span class='SourceFile' data-title='import␣Foundation↲↲struct␣BlackjackCard␣{↲␣␣//␣nested␣Suit␣enumeration↲␣␣enum␣Suit:"
},
{
"path": "Resources/parsers/50900/Tests/Tests/Fixtures/test-2-3.json",
"chars": 368380,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 1,\n \"endRow\": 45,\n \"graphemeEndColumn\": 1,\n \"graphem"
},
{
"path": "Resources/parsers/50900/Tests/Tests/Fixtures/test-2-4.html",
"chars": 12647,
"preview": "<span class='SourceFile' data-title='struct␣Result<␣{{↲␣␣let␣text:␣String↲␣␣let␣someOtherThing:␣String↲}' data-conten"
},
{
"path": "Resources/parsers/50900/Tests/Tests/Fixtures/test-2-4.json",
"chars": 36273,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 2,\n \"endRow\": 4,\n \"graphemeEndColumn\": 2,\n \"grapheme"
},
{
"path": "Resources/parsers/50900/Tests/Tests/Fixtures/test-2-5.html",
"chars": 7093,
"preview": "<span class='SourceFile' data-title='if␣a␣+␣b␣*␣c␣{↲␣␣return↲}' data-content='SourceFileSyntax' data-type='Syntax' data-"
},
{
"path": "Resources/parsers/50900/Tests/Tests/Fixtures/test-2-5.json",
"chars": 20488,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 2,\n \"endRow\": 3,\n \"graphemeEndColumn\": 2,\n \"grapheme"
},
{
"path": "Resources/parsers/50900/Tests/Tests/Fixtures/test-2-6.html",
"chars": 7092,
"preview": "<span class='SourceFile' data-title='if␣a␣+␣b␣×␣c␣{↲␣␣return↲}' data-content='SourceFileSyntax' data-type='Syntax' data-"
},
{
"path": "Resources/parsers/50900/Tests/Tests/Fixtures/test-2-6.json",
"chars": 20484,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 2,\n \"endRow\": 3,\n \"graphemeEndColumn\": 2,\n \"grapheme"
},
{
"path": "Resources/parsers/51000/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata",
"chars": 135,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:\">\n </FileRef"
},
{
"path": "Resources/parsers/51000/Package.resolved",
"chars": 304,
"preview": "{\n \"pins\" : [\n {\n \"identity\" : \"swift-syntax\",\n \"kind\" : \"remoteSourceControl\",\n \"location\" : \"https:"
},
{
"path": "Resources/parsers/51000/Package.swift",
"chars": 794,
"preview": "// swift-tools-version:5.10\nimport PackageDescription\n\nlet package = Package(\n name: \"parser\",\n platforms: [\n .macO"
},
{
"path": "Resources/parsers/51000/Sources/parser/Version.swift",
"chars": 41,
"preview": "import Foundation\nlet version = \"5.10.0\"\n"
},
{
"path": "Resources/parsers/51000/Tests/Tests/Fixtures/test-1-1.html",
"chars": 3884,
"preview": "<span class='SourceFile' data-title='let␣number␣=␣0' data-content='SourceFileSyntax' data-type='Syntax' data-range='{\"st"
},
{
"path": "Resources/parsers/51000/Tests/Tests/Fixtures/test-1-1.json",
"chars": 11511,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 15,\n \"endRow\": 1,\n \"graphemeEndColumn\": 15,\n \"graphe"
},
{
"path": "Resources/parsers/51000/Tests/Tests/Fixtures/test-1-2.html",
"chars": 31125,
"preview": "<span class='SourceFile' data-title='var␣temperatureInFahrenheit␣=␣90↲↲if␣temperatureInFahrenheit␣<=␣32␣{↲␣␣print(&qu"
},
{
"path": "Resources/parsers/51000/Tests/Tests/Fixtures/test-1-2.json",
"chars": 75537,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 62,\n \"endRow\": 11,\n \"graphemeEndColumn\": 62,\n \"graph"
},
{
"path": "Resources/parsers/51000/Tests/Tests/Fixtures/test-1-3.html",
"chars": 147678,
"preview": "<span class='SourceFile' data-title='import␣Foundation↲↲struct␣BlackjackCard␣{↲␣␣//␣nested␣Suit␣enumeration↲␣␣enum␣Suit:"
},
{
"path": "Resources/parsers/51000/Tests/Tests/Fixtures/test-1-3.json",
"chars": 368098,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 1,\n \"endRow\": 45,\n \"graphemeEndColumn\": 1,\n \"graphem"
},
{
"path": "Resources/parsers/51000/Tests/Tests/Fixtures/test-1-4.html",
"chars": 12647,
"preview": "<span class='SourceFile' data-title='struct␣Result<␣{{↲␣␣let␣text:␣String↲␣␣let␣someOtherThing:␣String↲}' data-conten"
},
{
"path": "Resources/parsers/51000/Tests/Tests/Fixtures/test-1-4.json",
"chars": 36273,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 2,\n \"endRow\": 4,\n \"graphemeEndColumn\": 2,\n \"grapheme"
},
{
"path": "Resources/parsers/51000/Tests/Tests/Fixtures/test-1-5.html",
"chars": 7069,
"preview": "<span class='SourceFile' data-title='if␣a␣+␣b␣*␣c␣{↲␣␣return↲}' data-content='SourceFileSyntax' data-type='Syntax' data-"
},
{
"path": "Resources/parsers/51000/Tests/Tests/Fixtures/test-1-5.json",
"chars": 19070,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 2,\n \"endRow\": 3,\n \"graphemeEndColumn\": 2,\n \"grapheme"
},
{
"path": "Resources/parsers/51000/Tests/Tests/Fixtures/test-1-6.html",
"chars": 7069,
"preview": "<span class='SourceFile' data-title='if␣a␣+␣b␣×␣c␣{↲␣␣return↲}' data-content='SourceFileSyntax' data-type='Syntax' data-"
},
{
"path": "Resources/parsers/51000/Tests/Tests/Fixtures/test-1-6.json",
"chars": 19070,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 2,\n \"endRow\": 3,\n \"graphemeEndColumn\": 2,\n \"grapheme"
},
{
"path": "Resources/parsers/51000/Tests/Tests/Fixtures/test-2-1.html",
"chars": 3884,
"preview": "<span class='SourceFile' data-title='let␣number␣=␣0' data-content='SourceFileSyntax' data-type='Syntax' data-range='{\"st"
},
{
"path": "Resources/parsers/51000/Tests/Tests/Fixtures/test-2-1.json",
"chars": 11511,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 15,\n \"endRow\": 1,\n \"graphemeEndColumn\": 15,\n \"graphe"
},
{
"path": "Resources/parsers/51000/Tests/Tests/Fixtures/test-2-2.html",
"chars": 30750,
"preview": "<span class='SourceFile' data-title='var␣temperatureInFahrenheit␣=␣90↲↲if␣temperatureInFahrenheit␣<=␣32␣{↲␣␣print(&qu"
},
{
"path": "Resources/parsers/51000/Tests/Tests/Fixtures/test-2-2.json",
"chars": 75828,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 62,\n \"endRow\": 11,\n \"graphemeEndColumn\": 62,\n \"graph"
},
{
"path": "Resources/parsers/51000/Tests/Tests/Fixtures/test-2-3.html",
"chars": 147277,
"preview": "<span class='SourceFile' data-title='import␣Foundation↲↲struct␣BlackjackCard␣{↲␣␣//␣nested␣Suit␣enumeration↲␣␣enum␣Suit:"
},
{
"path": "Resources/parsers/51000/Tests/Tests/Fixtures/test-2-3.json",
"chars": 368380,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 1,\n \"endRow\": 45,\n \"graphemeEndColumn\": 1,\n \"graphem"
},
{
"path": "Resources/parsers/51000/Tests/Tests/Fixtures/test-2-4.html",
"chars": 12647,
"preview": "<span class='SourceFile' data-title='struct␣Result<␣{{↲␣␣let␣text:␣String↲␣␣let␣someOtherThing:␣String↲}' data-conten"
},
{
"path": "Resources/parsers/51000/Tests/Tests/Fixtures/test-2-4.json",
"chars": 36273,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 2,\n \"endRow\": 4,\n \"graphemeEndColumn\": 2,\n \"grapheme"
},
{
"path": "Resources/parsers/51000/Tests/Tests/Fixtures/test-2-5.html",
"chars": 7093,
"preview": "<span class='SourceFile' data-title='if␣a␣+␣b␣*␣c␣{↲␣␣return↲}' data-content='SourceFileSyntax' data-type='Syntax' data-"
},
{
"path": "Resources/parsers/51000/Tests/Tests/Fixtures/test-2-5.json",
"chars": 20488,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 2,\n \"endRow\": 3,\n \"graphemeEndColumn\": 2,\n \"grapheme"
},
{
"path": "Resources/parsers/51000/Tests/Tests/Fixtures/test-2-6.html",
"chars": 7092,
"preview": "<span class='SourceFile' data-title='if␣a␣+␣b␣×␣c␣{↲␣␣return↲}' data-content='SourceFileSyntax' data-type='Syntax' data-"
},
{
"path": "Resources/parsers/51000/Tests/Tests/Fixtures/test-2-6.json",
"chars": 20484,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 2,\n \"endRow\": 3,\n \"graphemeEndColumn\": 2,\n \"grapheme"
},
{
"path": "Resources/parsers/60000/Package.resolved",
"chars": 389,
"preview": "{\n \"originHash\" : \"8515d5150b83025ad58574845ed771a96d911ed4b25e0cab591227cc70c2eab4\",\n \"pins\" : [\n {\n \"identit"
},
{
"path": "Resources/parsers/60000/Package.swift",
"chars": 794,
"preview": "// swift-tools-version:5.10\nimport PackageDescription\n\nlet package = Package(\n name: \"parser\",\n platforms: [\n .macO"
},
{
"path": "Resources/parsers/60000/Sources/parser/Version.swift",
"chars": 41,
"preview": "import Foundation\nlet version = \"6.00.0\"\n"
},
{
"path": "Resources/parsers/60000/Tests/Tests/Fixtures/test-1-1.html",
"chars": 3884,
"preview": "<span class='SourceFile' data-title='let␣number␣=␣0' data-content='SourceFileSyntax' data-type='Syntax' data-range='{\"st"
},
{
"path": "Resources/parsers/60000/Tests/Tests/Fixtures/test-1-1.json",
"chars": 11511,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 15,\n \"endRow\": 1,\n \"graphemeEndColumn\": 15,\n \"graphe"
},
{
"path": "Resources/parsers/60000/Tests/Tests/Fixtures/test-1-2.html",
"chars": 31125,
"preview": "<span class='SourceFile' data-title='var␣temperatureInFahrenheit␣=␣90↲↲if␣temperatureInFahrenheit␣<=␣32␣{↲␣␣print(&qu"
},
{
"path": "Resources/parsers/60000/Tests/Tests/Fixtures/test-1-2.json",
"chars": 75537,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 62,\n \"endRow\": 11,\n \"graphemeEndColumn\": 62,\n \"graph"
},
{
"path": "Resources/parsers/60000/Tests/Tests/Fixtures/test-1-3.html",
"chars": 147678,
"preview": "<span class='SourceFile' data-title='import␣Foundation↲↲struct␣BlackjackCard␣{↲␣␣//␣nested␣Suit␣enumeration↲␣␣enum␣Suit:"
},
{
"path": "Resources/parsers/60000/Tests/Tests/Fixtures/test-1-3.json",
"chars": 368098,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 1,\n \"endRow\": 45,\n \"graphemeEndColumn\": 1,\n \"graphem"
},
{
"path": "Resources/parsers/60000/Tests/Tests/Fixtures/test-1-4.html",
"chars": 12647,
"preview": "<span class='SourceFile' data-title='struct␣Result<␣{{↲␣␣let␣text:␣String↲␣␣let␣someOtherThing:␣String↲}' data-conten"
},
{
"path": "Resources/parsers/60000/Tests/Tests/Fixtures/test-1-4.json",
"chars": 36273,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 2,\n \"endRow\": 4,\n \"graphemeEndColumn\": 2,\n \"grapheme"
},
{
"path": "Resources/parsers/60000/Tests/Tests/Fixtures/test-1-5.html",
"chars": 7069,
"preview": "<span class='SourceFile' data-title='if␣a␣+␣b␣*␣c␣{↲␣␣return↲}' data-content='SourceFileSyntax' data-type='Syntax' data-"
},
{
"path": "Resources/parsers/60000/Tests/Tests/Fixtures/test-1-5.json",
"chars": 19070,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 2,\n \"endRow\": 3,\n \"graphemeEndColumn\": 2,\n \"grapheme"
},
{
"path": "Resources/parsers/60000/Tests/Tests/Fixtures/test-1-6.html",
"chars": 7069,
"preview": "<span class='SourceFile' data-title='if␣a␣+␣b␣×␣c␣{↲␣␣return↲}' data-content='SourceFileSyntax' data-type='Syntax' data-"
},
{
"path": "Resources/parsers/60000/Tests/Tests/Fixtures/test-1-6.json",
"chars": 19070,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 2,\n \"endRow\": 3,\n \"graphemeEndColumn\": 2,\n \"grapheme"
},
{
"path": "Resources/parsers/60000/Tests/Tests/Fixtures/test-2-1.html",
"chars": 3884,
"preview": "<span class='SourceFile' data-title='let␣number␣=␣0' data-content='SourceFileSyntax' data-type='Syntax' data-range='{\"st"
},
{
"path": "Resources/parsers/60000/Tests/Tests/Fixtures/test-2-1.json",
"chars": 11511,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 15,\n \"endRow\": 1,\n \"graphemeEndColumn\": 15,\n \"graphe"
},
{
"path": "Resources/parsers/60000/Tests/Tests/Fixtures/test-2-2.html",
"chars": 30750,
"preview": "<span class='SourceFile' data-title='var␣temperatureInFahrenheit␣=␣90↲↲if␣temperatureInFahrenheit␣<=␣32␣{↲␣␣print(&qu"
},
{
"path": "Resources/parsers/60000/Tests/Tests/Fixtures/test-2-2.json",
"chars": 75828,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 62,\n \"endRow\": 11,\n \"graphemeEndColumn\": 62,\n \"graph"
},
{
"path": "Resources/parsers/60000/Tests/Tests/Fixtures/test-2-3.html",
"chars": 147277,
"preview": "<span class='SourceFile' data-title='import␣Foundation↲↲struct␣BlackjackCard␣{↲␣␣//␣nested␣Suit␣enumeration↲␣␣enum␣Suit:"
},
{
"path": "Resources/parsers/60000/Tests/Tests/Fixtures/test-2-3.json",
"chars": 368380,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 1,\n \"endRow\": 45,\n \"graphemeEndColumn\": 1,\n \"graphem"
},
{
"path": "Resources/parsers/60000/Tests/Tests/Fixtures/test-2-4.html",
"chars": 12647,
"preview": "<span class='SourceFile' data-title='struct␣Result<␣{{↲␣␣let␣text:␣String↲␣␣let␣someOtherThing:␣String↲}' data-conten"
},
{
"path": "Resources/parsers/60000/Tests/Tests/Fixtures/test-2-4.json",
"chars": 36273,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 2,\n \"endRow\": 4,\n \"graphemeEndColumn\": 2,\n \"grapheme"
},
{
"path": "Resources/parsers/60000/Tests/Tests/Fixtures/test-2-5.html",
"chars": 7093,
"preview": "<span class='SourceFile' data-title='if␣a␣+␣b␣*␣c␣{↲␣␣return↲}' data-content='SourceFileSyntax' data-type='Syntax' data-"
},
{
"path": "Resources/parsers/60000/Tests/Tests/Fixtures/test-2-5.json",
"chars": 20488,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 2,\n \"endRow\": 3,\n \"graphemeEndColumn\": 2,\n \"grapheme"
},
{
"path": "Resources/parsers/60000/Tests/Tests/Fixtures/test-2-6.html",
"chars": 7092,
"preview": "<span class='SourceFile' data-title='if␣a␣+␣b␣×␣c␣{↲␣␣return↲}' data-content='SourceFileSyntax' data-type='Syntax' data-"
},
{
"path": "Resources/parsers/60000/Tests/Tests/Fixtures/test-2-6.json",
"chars": 20484,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 2,\n \"endRow\": 3,\n \"graphemeEndColumn\": 2,\n \"grapheme"
},
{
"path": "Resources/parsers/60100/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata",
"chars": 135,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:\">\n </FileRef"
},
{
"path": "Resources/parsers/60100/Package.resolved",
"chars": 389,
"preview": "{\n \"originHash\" : \"9c1380812b25a7a61cbbf113c12ca68af64c132e23b44e1f060ec564652daef2\",\n \"pins\" : [\n {\n \"identit"
},
{
"path": "Resources/parsers/60100/Package.swift",
"chars": 794,
"preview": "// swift-tools-version:5.10\nimport PackageDescription\n\nlet package = Package(\n name: \"parser\",\n platforms: [\n .macO"
},
{
"path": "Resources/parsers/60100/Sources/parser/Version.swift",
"chars": 41,
"preview": "import Foundation\nlet version = \"6.01.0\"\n"
},
{
"path": "Resources/parsers/60100/Tests/Tests/Fixtures/test-1-1.html",
"chars": 3884,
"preview": "<span class='SourceFile' data-title='let␣number␣=␣0' data-content='SourceFileSyntax' data-type='Syntax' data-range='{\"st"
},
{
"path": "Resources/parsers/60100/Tests/Tests/Fixtures/test-1-1.json",
"chars": 11511,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 15,\n \"endRow\": 1,\n \"graphemeEndColumn\": 15,\n \"graphe"
},
{
"path": "Resources/parsers/60100/Tests/Tests/Fixtures/test-1-2.html",
"chars": 31125,
"preview": "<span class='SourceFile' data-title='var␣temperatureInFahrenheit␣=␣90↲↲if␣temperatureInFahrenheit␣<=␣32␣{↲␣␣print(&qu"
},
{
"path": "Resources/parsers/60100/Tests/Tests/Fixtures/test-1-2.json",
"chars": 75537,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 62,\n \"endRow\": 11,\n \"graphemeEndColumn\": 62,\n \"graph"
},
{
"path": "Resources/parsers/60100/Tests/Tests/Fixtures/test-1-3.html",
"chars": 147678,
"preview": "<span class='SourceFile' data-title='import␣Foundation↲↲struct␣BlackjackCard␣{↲␣␣//␣nested␣Suit␣enumeration↲␣␣enum␣Suit:"
},
{
"path": "Resources/parsers/60100/Tests/Tests/Fixtures/test-1-3.json",
"chars": 368098,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 1,\n \"endRow\": 45,\n \"graphemeEndColumn\": 1,\n \"graphem"
},
{
"path": "Resources/parsers/60100/Tests/Tests/Fixtures/test-1-4.html",
"chars": 12647,
"preview": "<span class='SourceFile' data-title='struct␣Result<␣{{↲␣␣let␣text:␣String↲␣␣let␣someOtherThing:␣String↲}' data-conten"
},
{
"path": "Resources/parsers/60100/Tests/Tests/Fixtures/test-1-4.json",
"chars": 36273,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 2,\n \"endRow\": 4,\n \"graphemeEndColumn\": 2,\n \"grapheme"
},
{
"path": "Resources/parsers/60100/Tests/Tests/Fixtures/test-1-5.html",
"chars": 7069,
"preview": "<span class='SourceFile' data-title='if␣a␣+␣b␣*␣c␣{↲␣␣return↲}' data-content='SourceFileSyntax' data-type='Syntax' data-"
},
{
"path": "Resources/parsers/60100/Tests/Tests/Fixtures/test-1-5.json",
"chars": 19070,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 2,\n \"endRow\": 3,\n \"graphemeEndColumn\": 2,\n \"grapheme"
},
{
"path": "Resources/parsers/60100/Tests/Tests/Fixtures/test-1-6.html",
"chars": 7069,
"preview": "<span class='SourceFile' data-title='if␣a␣+␣b␣×␣c␣{↲␣␣return↲}' data-content='SourceFileSyntax' data-type='Syntax' data-"
},
{
"path": "Resources/parsers/60100/Tests/Tests/Fixtures/test-1-6.json",
"chars": 19070,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 2,\n \"endRow\": 3,\n \"graphemeEndColumn\": 2,\n \"grapheme"
},
{
"path": "Resources/parsers/60100/Tests/Tests/Fixtures/test-2-1.html",
"chars": 3884,
"preview": "<span class='SourceFile' data-title='let␣number␣=␣0' data-content='SourceFileSyntax' data-type='Syntax' data-range='{\"st"
},
{
"path": "Resources/parsers/60100/Tests/Tests/Fixtures/test-2-1.json",
"chars": 11511,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 15,\n \"endRow\": 1,\n \"graphemeEndColumn\": 15,\n \"graphe"
},
{
"path": "Resources/parsers/60100/Tests/Tests/Fixtures/test-2-2.html",
"chars": 30750,
"preview": "<span class='SourceFile' data-title='var␣temperatureInFahrenheit␣=␣90↲↲if␣temperatureInFahrenheit␣<=␣32␣{↲␣␣print(&qu"
},
{
"path": "Resources/parsers/60100/Tests/Tests/Fixtures/test-2-2.json",
"chars": 75828,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 62,\n \"endRow\": 11,\n \"graphemeEndColumn\": 62,\n \"graph"
},
{
"path": "Resources/parsers/60100/Tests/Tests/Fixtures/test-2-3.html",
"chars": 147277,
"preview": "<span class='SourceFile' data-title='import␣Foundation↲↲struct␣BlackjackCard␣{↲␣␣//␣nested␣Suit␣enumeration↲␣␣enum␣Suit:"
},
{
"path": "Resources/parsers/60100/Tests/Tests/Fixtures/test-2-3.json",
"chars": 368380,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 1,\n \"endRow\": 45,\n \"graphemeEndColumn\": 1,\n \"graphem"
},
{
"path": "Resources/parsers/60100/Tests/Tests/Fixtures/test-2-4.html",
"chars": 12647,
"preview": "<span class='SourceFile' data-title='struct␣Result<␣{{↲␣␣let␣text:␣String↲␣␣let␣someOtherThing:␣String↲}' data-conten"
},
{
"path": "Resources/parsers/60100/Tests/Tests/Fixtures/test-2-4.json",
"chars": 36273,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 2,\n \"endRow\": 4,\n \"graphemeEndColumn\": 2,\n \"grapheme"
},
{
"path": "Resources/parsers/60100/Tests/Tests/Fixtures/test-2-5.html",
"chars": 7093,
"preview": "<span class='SourceFile' data-title='if␣a␣+␣b␣*␣c␣{↲␣␣return↲}' data-content='SourceFileSyntax' data-type='Syntax' data-"
},
{
"path": "Resources/parsers/60100/Tests/Tests/Fixtures/test-2-5.json",
"chars": 20488,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 2,\n \"endRow\": 3,\n \"graphemeEndColumn\": 2,\n \"grapheme"
},
{
"path": "Resources/parsers/60100/Tests/Tests/Fixtures/test-2-6.html",
"chars": 7092,
"preview": "<span class='SourceFile' data-title='if␣a␣+␣b␣×␣c␣{↲␣␣return↲}' data-content='SourceFileSyntax' data-type='Syntax' data-"
},
{
"path": "Resources/parsers/60100/Tests/Tests/Fixtures/test-2-6.json",
"chars": 20484,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 2,\n \"endRow\": 3,\n \"graphemeEndColumn\": 2,\n \"grapheme"
},
{
"path": "Resources/parsers/60200/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata",
"chars": 135,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:\">\n </FileRef"
},
{
"path": "Resources/parsers/60200/Package.resolved",
"chars": 389,
"preview": "{\n \"originHash\" : \"ea0acfa5036e50d9e86176f9c8bdc2453fc3789f6df5f40e20fe5d5ce712a71e\",\n \"pins\" : [\n {\n \"identit"
},
{
"path": "Resources/parsers/60200/Package.swift",
"chars": 794,
"preview": "// swift-tools-version:5.10\nimport PackageDescription\n\nlet package = Package(\n name: \"parser\",\n platforms: [\n .macO"
},
{
"path": "Resources/parsers/60200/Sources/parser/Version.swift",
"chars": 41,
"preview": "import Foundation\nlet version = \"6.02.0\"\n"
},
{
"path": "Resources/parsers/60200/Tests/Tests/Fixtures/test-1-1.html",
"chars": 3884,
"preview": "<span class='SourceFile' data-title='let␣number␣=␣0' data-content='SourceFileSyntax' data-type='Syntax' data-range='{\"st"
},
{
"path": "Resources/parsers/60200/Tests/Tests/Fixtures/test-1-1.json",
"chars": 11511,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 15,\n \"endRow\": 1,\n \"graphemeEndColumn\": 15,\n \"graphe"
},
{
"path": "Resources/parsers/60200/Tests/Tests/Fixtures/test-1-2.html",
"chars": 31125,
"preview": "<span class='SourceFile' data-title='var␣temperatureInFahrenheit␣=␣90↲↲if␣temperatureInFahrenheit␣<=␣32␣{↲␣␣print(&qu"
},
{
"path": "Resources/parsers/60200/Tests/Tests/Fixtures/test-1-2.json",
"chars": 75537,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 62,\n \"endRow\": 11,\n \"graphemeEndColumn\": 62,\n \"graph"
},
{
"path": "Resources/parsers/60200/Tests/Tests/Fixtures/test-1-3.html",
"chars": 147678,
"preview": "<span class='SourceFile' data-title='import␣Foundation↲↲struct␣BlackjackCard␣{↲␣␣//␣nested␣Suit␣enumeration↲␣␣enum␣Suit:"
},
{
"path": "Resources/parsers/60200/Tests/Tests/Fixtures/test-1-3.json",
"chars": 368098,
"preview": "[\n {\n \"id\": 0,\n \"range\": {\n \"endColumn\": 1,\n \"endRow\": 45,\n \"graphemeEndColumn\": 1,\n \"graphem"
}
]
// ... and 175 more files (download for full content)
About this extraction
This page contains the full source code of the kishikawakatsumi/swift-ast-explorer GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 375 files (11.4 MB), approximately 3.0M tokens, and a symbol index with 100 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.