From e247deb844e0c7c0ff96955166ac37ed481e6f37 Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Sat, 1 Sep 2018 12:02:20 -0400 Subject: [PATCH] Point to denoland repo --- .appveyor.yml | 361 -------- .gitattributes | 5 - .gitignore | 12 - .gitmodules | 3 - .gn | 49 -- .prettierignore | 1 - .travis.yml | 50 -- BUILD.gn | 334 -------- Cargo.toml | 18 - LICENSE | 21 - README.md | 110 +-- Roadmap.md | 404 --------- build | 1 - build_extra/deno.gni | 47 - build_extra/flatbuffers/BUILD.gn | 128 --- build_extra/flatbuffers/flatbuffer.gni | 239 ------ build_extra/flatbuffers/rust/BUILD.gn | 6 - .../flatbuffers/rust/rust_flatbuffer.gni | 44 - build_extra/rust/BUILD.gn | 810 ------------------ build_extra/rust/dummy.rs | 1 - build_extra/rust/get_rust_ldflags.cmd | 1 - build_extra/rust/get_rust_ldflags.py | 180 ---- build_extra/rust/rust.gni | 330 ------- build_extra/toolchain/validate.gni | 15 - build_extra/toolchain/win/BUILD.gn | 494 ----------- build_extra/toolchain/win/mods.gni | 28 - build_overrides | 1 - buildtools | 1 - gclient_config.py | 44 - js/assets.ts | 108 --- js/compiler.ts | 722 ---------------- js/compiler_test.ts | 505 ----------- js/console.ts | 138 --- js/console_test.ts | 85 -- js/deno.ts | 13 - js/errors.ts | 15 - js/fetch.ts | 197 ----- js/fetch_types.d.ts | 452 ---------- js/global-eval.ts | 6 - js/globals.ts | 47 - js/lib.globals.d.ts | 5 - js/libdeno.ts | 28 - js/main.ts | 103 --- js/mock_builtin.js | 1 - js/os.ts | 278 ------ js/plugins.d.ts | 7 - js/test_util.ts | 68 -- js/testing/testing.ts | 88 -- js/testing/util.ts | 64 -- js/testing/util_test.ts | 40 - js/text_encoding.ts | 28 - js/timers.ts | 104 --- js/tsconfig.generated.json | 18 - js/types.d.ts | 147 ---- js/unit_tests.ts | 181 ---- js/util.ts | 77 -- js/v8_source_maps.ts | 276 ------ libdeno/binding.cc | 443 ---------- libdeno/deno.h | 65 -- libdeno/file_util.cc | 90 -- libdeno/file_util.h | 14 - libdeno/file_util_test.cc | 46 - libdeno/from_filesystem.cc | 61 -- libdeno/from_snapshot.cc | 86 -- libdeno/internal.h | 47 - libdeno/libdeno_test.cc | 207 ----- libdeno/libdeno_test.js | 152 ---- libdeno/snapshot_creator.cc | 75 -- libdeno/test.cc | 10 - node_modules | 1 - package.json | 27 - rollup.config.js | 217 ----- src/binding.rs | 39 - src/deno_dir.rs | 488 ----------- src/errors.rs | 145 ---- src/flags.rs | 193 ----- src/fs.rs | 60 -- src/handlers.rs | 598 ------------- src/main.rs | 159 ---- src/msg.fbs | 179 ---- src/net.rs | 33 - src/version.rs | 14 - testing | 1 - tests/001_hello.js | 1 - tests/001_hello.js.out | 1 - tests/002_hello.ts | 1 - tests/002_hello.ts.out | 1 - tests/003_relative_import.ts | 3 - tests/003_relative_import.ts.out | 1 - tests/004_set_timeout.ts | 11 - tests/004_set_timeout.ts.out | 2 - tests/005_more_imports.ts | 11 - tests/005_more_imports.ts.out | 1 - tests/006_url_imports.ts | 3 - tests/006_url_imports.ts.out | 3 - tests/010_set_interval.ts | 7 - tests/010_set_interval.ts.out | 2 - tests/012_async.ts | 11 - tests/012_async.ts.out | 3 - tests/013_dynamic_import.ts | 17 - tests/013_dynamic_import.ts.out | 1 - tests/014_duplicate_import.ts | 9 - tests/014_duplicate_import.ts.out | 1 - tests/async_error.ts | 8 - tests/async_error.ts.out | 10 - tests/error_001.ts | 9 - tests/error_001.ts.out | 9 - tests/error_002.ts | 7 - tests/error_002.ts.out | 8 - tests/error_003_typescript.ts | 2 - tests/error_003_typescript.ts.out | 10 - tests/error_004_missing_module.ts | 1 - tests/error_004_missing_module.ts.out | 12 - tests/error_005_missing_dynamic_import.ts | 3 - tests/error_005_missing_dynamic_import.ts.out | 12 - tests/exit_error42.ts | 5 - tests/exit_error42.ts.out | 1 - tests/fetch_deps.ts | 14 - tests/https_import.ts | 5 - tests/https_import.ts.out | 2 - tests/subdir/auto_print_hello.ts | 2 - tests/subdir/mod1.ts | 17 - tests/subdir/print_hello.ts | 3 - tests/subdir/subdir2/mod2.ts | 9 - third_party | 1 - tools/build.py | 21 - tools/check_output_test.py | 62 -- tools/clang | 1 - tools/format.py | 30 - tools/http_server.py | 32 - tools/lint.py | 18 - tools/run_node.py | 19 - tools/run_rustc.py | 49 -- tools/rustfmt.toml | 2 - tools/setup.py | 98 --- tools/sha256sum.py | 70 -- tools/sync_third_party.py | 13 - tools/test.py | 56 -- tools/third_party.py | 190 ---- tools/unit_tests.py | 26 - tools/util.py | 175 ---- tools/util_test.py | 43 - tsconfig.json | 23 - tslint.json | 68 -- 144 files changed, 1 insertion(+), 12224 deletions(-) delete mode 100644 .appveyor.yml delete mode 100644 .gitattributes delete mode 100644 .gitignore delete mode 100644 .gitmodules delete mode 100644 .gn delete mode 100644 .prettierignore delete mode 100644 .travis.yml delete mode 100644 BUILD.gn delete mode 100644 Cargo.toml delete mode 100644 LICENSE delete mode 100644 Roadmap.md delete mode 120000 build delete mode 100644 build_extra/deno.gni delete mode 100644 build_extra/flatbuffers/BUILD.gn delete mode 100644 build_extra/flatbuffers/flatbuffer.gni delete mode 100644 build_extra/flatbuffers/rust/BUILD.gn delete mode 100644 build_extra/flatbuffers/rust/rust_flatbuffer.gni delete mode 100644 build_extra/rust/BUILD.gn delete mode 100644 build_extra/rust/dummy.rs delete mode 100644 build_extra/rust/get_rust_ldflags.cmd delete mode 100755 build_extra/rust/get_rust_ldflags.py delete mode 100644 build_extra/rust/rust.gni delete mode 100644 build_extra/toolchain/validate.gni delete mode 100644 build_extra/toolchain/win/BUILD.gn delete mode 100644 build_extra/toolchain/win/mods.gni delete mode 120000 build_overrides delete mode 120000 buildtools delete mode 100644 gclient_config.py delete mode 100644 js/assets.ts delete mode 100644 js/compiler.ts delete mode 100644 js/compiler_test.ts delete mode 100644 js/console.ts delete mode 100644 js/console_test.ts delete mode 100644 js/deno.ts delete mode 100644 js/errors.ts delete mode 100644 js/fetch.ts delete mode 100644 js/fetch_types.d.ts delete mode 100644 js/global-eval.ts delete mode 100644 js/globals.ts delete mode 100644 js/lib.globals.d.ts delete mode 100644 js/libdeno.ts delete mode 100644 js/main.ts delete mode 100644 js/mock_builtin.js delete mode 100644 js/os.ts delete mode 100644 js/plugins.d.ts delete mode 100644 js/test_util.ts delete mode 100644 js/testing/testing.ts delete mode 100644 js/testing/util.ts delete mode 100644 js/testing/util_test.ts delete mode 100644 js/text_encoding.ts delete mode 100644 js/timers.ts delete mode 100644 js/tsconfig.generated.json delete mode 100644 js/types.d.ts delete mode 100644 js/unit_tests.ts delete mode 100644 js/util.ts delete mode 100644 js/v8_source_maps.ts delete mode 100644 libdeno/binding.cc delete mode 100644 libdeno/deno.h delete mode 100644 libdeno/file_util.cc delete mode 100644 libdeno/file_util.h delete mode 100644 libdeno/file_util_test.cc delete mode 100644 libdeno/from_filesystem.cc delete mode 100644 libdeno/from_snapshot.cc delete mode 100644 libdeno/internal.h delete mode 100644 libdeno/libdeno_test.cc delete mode 100644 libdeno/libdeno_test.js delete mode 100644 libdeno/snapshot_creator.cc delete mode 100644 libdeno/test.cc delete mode 120000 node_modules delete mode 100644 package.json delete mode 100644 rollup.config.js delete mode 100644 src/binding.rs delete mode 100644 src/deno_dir.rs delete mode 100644 src/errors.rs delete mode 100644 src/flags.rs delete mode 100644 src/fs.rs delete mode 100644 src/handlers.rs delete mode 100644 src/main.rs delete mode 100644 src/msg.fbs delete mode 100644 src/net.rs delete mode 100644 src/version.rs delete mode 120000 testing delete mode 100644 tests/001_hello.js delete mode 100644 tests/001_hello.js.out delete mode 100644 tests/002_hello.ts delete mode 100644 tests/002_hello.ts.out delete mode 100644 tests/003_relative_import.ts delete mode 100644 tests/003_relative_import.ts.out delete mode 100644 tests/004_set_timeout.ts delete mode 100644 tests/004_set_timeout.ts.out delete mode 100644 tests/005_more_imports.ts delete mode 100644 tests/005_more_imports.ts.out delete mode 100644 tests/006_url_imports.ts delete mode 100644 tests/006_url_imports.ts.out delete mode 100644 tests/010_set_interval.ts delete mode 100644 tests/010_set_interval.ts.out delete mode 100644 tests/012_async.ts delete mode 100644 tests/012_async.ts.out delete mode 100644 tests/013_dynamic_import.ts delete mode 100644 tests/013_dynamic_import.ts.out delete mode 100644 tests/014_duplicate_import.ts delete mode 100644 tests/014_duplicate_import.ts.out delete mode 100644 tests/async_error.ts delete mode 100644 tests/async_error.ts.out delete mode 100644 tests/error_001.ts delete mode 100644 tests/error_001.ts.out delete mode 100644 tests/error_002.ts delete mode 100644 tests/error_002.ts.out delete mode 100644 tests/error_003_typescript.ts delete mode 100644 tests/error_003_typescript.ts.out delete mode 100644 tests/error_004_missing_module.ts delete mode 100644 tests/error_004_missing_module.ts.out delete mode 100644 tests/error_005_missing_dynamic_import.ts delete mode 100644 tests/error_005_missing_dynamic_import.ts.out delete mode 100644 tests/exit_error42.ts delete mode 100644 tests/exit_error42.ts.out delete mode 100644 tests/fetch_deps.ts delete mode 100644 tests/https_import.ts delete mode 100644 tests/https_import.ts.out delete mode 100644 tests/subdir/auto_print_hello.ts delete mode 100644 tests/subdir/mod1.ts delete mode 100644 tests/subdir/print_hello.ts delete mode 100644 tests/subdir/subdir2/mod2.ts delete mode 160000 third_party delete mode 100755 tools/build.py delete mode 100755 tools/check_output_test.py delete mode 120000 tools/clang delete mode 100755 tools/format.py delete mode 100755 tools/http_server.py delete mode 100755 tools/lint.py delete mode 100755 tools/run_node.py delete mode 100644 tools/run_rustc.py delete mode 100644 tools/rustfmt.toml delete mode 100755 tools/setup.py delete mode 100644 tools/sha256sum.py delete mode 100755 tools/sync_third_party.py delete mode 100755 tools/test.py delete mode 100644 tools/third_party.py delete mode 100755 tools/unit_tests.py delete mode 100644 tools/util.py delete mode 100644 tools/util_test.py delete mode 100644 tsconfig.json delete mode 100644 tslint.json diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index da96eb2b3f761a..00000000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,361 +0,0 @@ -version: '{build}.{branch}' - -skip_branch_with_pr: true - -clone_folder: c:\deno -clone_depth: 1 - -environment: - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - DENO_BUILD_MODE: release - DENO_BUILD_PATH: $(APPVEYOR_BUILD_FOLDER)\out\release - DENO_THIRD_PARTY_PATH: $(APPVEYOR_BUILD_FOLDER)\third_party - CARGO_HOME: $(USERPROFILE)\.cargo - RUSTUP_HOME: $(USERPROFILE)\.rustup - RELEASE_ARTIFACT: deno_win_x64.zip - - # Appveyor uses 7zip to pack cache directories. We use these options: - # -t7z : Use '7z' format. The default is 'zip' which can't store symlinks. - # -snl : Store symlinks. - # -mtc : Use UTC timestamps. This is required for incremental builds. - # -mx=1 : Fast compression. - APPVEYOR_CACHE_ENTRY_ZIP_ARGS: -t7z -snl -mtc -mx=1 - - # Define some PowerShell helper functions which are used in the scripts below. - # They're defined in an environment variable to reduce noise in the build log. - PS_UTILS: |- - # `Exec` runs a regular executable. It looks at the process' exit code, - # rather than its stderr output, to tell if a command has failed. - function Exec([ScriptBlock] $Command, [switch] $NoNewLines) { - "$Command".TrimStart(" &") | Write-Host # Echo command. - & $Command 2>&1 | Write-Host -NoNewLine:$NoNewLines # Execute command. - if ($NoNewLines) { Write-Host } # Write newline. - if ($LastExitCode -ne 0) { throw "Failure. Exit code: $LastExitCode" } - } - - # Get-Tree lists all objects in a tree. It's different from Get-ChildItem - # in that the latter recurses through symlinks, which is problematic. - function Get-Tree([string[]] $Path, [switch] $Recurse, [switch] $Force) { - function Get-SubDirs([string[]] $Path) { - Get-ChildItem $Path -Force:$Force ` - -Attributes Directory+!ReparsePoint | - foreach { $_.FullName } | - foreach { $_; Get-SubDirs $_ } - } - if ($Recurse) { $Path += Get-SubDirs $Path } - Get-ChildItem $Path -Force:$Force @args - } - - # `Delete-Tree` is a simple wrapper around Remove-Item. It doesn't set - # an error status if one of the paths to be deleted doesn't exist. - function Delete-Tree([string[]] $Path) { - $Path | foreach { - "Deleting '$_'" | Write-Host -NoNewLine - if (Test-Path $_) { - Remove-Item $_ -Recurse -Force -ErrorAction Ignore - $(if ($?) { " - ok" } else { " - failed" }) | Write-Host - } else { - " - not found" | Write-Host - } - } - } - - # We set file atimes to this date and see if it changes. - $FILE_NOT_NEEDED = Get-Date -Date "1984-04-11T00:00:00Z" # A good year. - # Traced files are stored a hash table, using their full path as key. - $not_needed = @{} - # Whether filesystem last access time tracking has been enabled yet. - $atime_enabled = $false - - # Trace whether files are actually used, so we can find and remove files - # that unnecessary. We use this to avoid hoarding stale build outputs. - function Start-TraceFilesNeeded([string[]] $Path, [switch] $Recurse) { - # Don't enable if the cache won't be saved. - if (-not (Get-SaveCache)) { return } - # Identify (new) files to trace. A non-existing path is not an error. - $files = $Path | - where { Test-Path $_ } | - foreach { Get-Tree $_ -Recurse:$Recurse -File } | - where { -not $not_needed.ContainsKey($_.FullName) } - # Set newly traced files' last access time to very long ago. - $files | foreach { $_.LastAccessTime = $FILE_NOT_NEEDED } - # Add newly traced files to the hash table with unnecessary files. - $files | foreach { $not_needed.Add($_.FullName, $true) } - # Enable last access time tracking only if any files were found. - if ($files -and -not $atime_enabled) { - Exec { fsutil behavior set DisableLastAccess 0 } - Set-Variable -Name atime_enabled -Value $true -Scope 1 - } - # Log statistics. - Write-Host "Tracing file access for $($files.Count) files." - } - - # Marks files as needed. - # -Auto : Auto mark files if their access time has changed. - # -Path : Explicitly mark file(s) as needed. - # -Recurse : Recurse into directories specified with -Path. - # -Reason : Optional reason, written to the build log. - function Set-FilesNeeded([switch] $Auto, [string[]] $Path, - [switch] $Recurse, [string] $Reason) { - # Helper function. - function Mark([System.IO.FileSystemInfo[]] $Files, [string] $How) { - # Find matching files that are traced, then remove them. - $keys = $Files.FullName | - where { $_ -and $not_needed.ContainsKey($_) } - $keys | foreach { $not_needed.Remove($_) } - # Write log message. - if ($keys.Count -gt 0) { - Write-Host ("$Reason$(if ($Reason) { ': ' })" + - "$($keys.Count) files $How marked 'needed'.") - } - } - # Skip marking step if there are no files being traced. - if ($not_needed.Count -eq 0) { return } - # Auto mark files 'needed' when their last access time has changed. - if ($Auto) { - $files = $not_needed.Keys | - where { Test-Path $_ -PathType Leaf } | - foreach { Get-Item $_ -Force } | - where { $_.LastAccessTime -ne $FILE_NOT_NEEDED } - Mark -Files $files -How "automatically" - } - # Mark explicitly specified paths. - if ($Path) { - $files = $Path | - where { Test-Path $_ } | - foreach { Get-Tree $_ -Recurse:$Recurse -Force -File } - Mark -Files $files -How "explicitly" - } - } - - # Clean up stale files and end file tracking. - function Stop-TraceFilesNeeded { - # Look for files that had their atime changed, and mark them needed. - Set-FilesNeeded -Auto - # Make a list of all files to delete, then delete them. - $files = $not_needed.Keys | - where { Test-Path $_ -PathType Leaf } | - foreach { Get-Item $_ -Force } - # Compute the total size of all deleted files. - $size_info = $files | measure -Property Length -Sum - $size_mb = "{0:N1}" -f ($size_info.Sum / (1024 * 1024)) - # Delete files, as well as parent directories if they became empty. - $files | Remove-Item -Force - $dirs = $files | foreach { - try { while ($_ = $_.Directory) { $_.Delete(); $_ } } catch {} - } - # All unnecessary files are now gone. - $not_needed.Clear() - # Log about what what was cleaned up. - if ($files.Count -gt 0) { - Write-Host "Deleted $($files.Count) unnecessary files and", - "$($dirs.Count) directories ($size_mb MB)." - } - } - - # Get-SaveCache returns $true if the cache will be saved at the end. - function Get-SaveCache { - -not $env:APPVEYOR_PULL_REQUEST_NUMBER -and - -not $env:APPVEYOR_CACHE_SKIP_SAVE -eq "true" - } - -for: - # Do no save the build cache for feature branches. TODO: Once we have multiple - # permanent branches, use a build matrix so each branch has it's own cache. - - branches: - except: - - master - environment: - APPVEYOR_CACHE_SKIP_SAVE: true - -cache: - # Python packages installed with `pip --user` and Pip cache. - - $(APPDATA)\Python - - $(LOCALAPPDATA)\pip - # Rust stuff. - - $(CARGO_HOME) - - $(RUSTUP_HOME) - # Cache the third_party submodule to preserve binaries downloaded by setup.py, - # and to make incremental builds work. - - $(APPVEYOR_BUILD_FOLDER)\.git\modules\third_party - - $(APPVEYOR_BUILD_FOLDER)\third_party - # Build incrementally. - - $(DENO_BUILD_PATH) - -init: - # Load utility functions - - ps: Invoke-Expression $env:PS_UTILS - - # Make git check out symlinks (not placeholder text files). - - git config --global core.symlinks true - -install: - # Clone the third_party submodule. - - ps: |- - try { - Exec { & git submodule update --init --force --depth 1 } - } catch { - # Git will fail if the `third_party` directory was restored from cache, - # but the `.git/modules` directory wasn't. Rebuild it from scratch. - Delete-Tree $env:DENO_THIRD_PARTY_PATH - Exec -NoNewLines { & git submodule update --init --force --depth 1 } - } - - # Prune and pack git objects. Thus when we upload `.git/modules/` to the - # Appveyor cache, it'll include only objects that were actually needed. - # This step is skipped if the cache is not going to be saved. - - ps: |- - if (Get-SaveCache) { - Push-Location $env:DENO_THIRD_PARTY_PATH - Exec { & git gc --prune=all } - Pop-Location - } - - # Configure depot_tools and add it to the search path. This is necessary - # because, later in this script, we need to invoke ninja directly. - - ps: |- - $env:PATH = "$env:DENO_THIRD_PARTY_PATH\depot_tools;$env:PATH" - $env:DEPOT_TOOLS_WIN_TOOLCHAIN = "0" - - # Install a recent Node.js version. - - ps: Install-Product -Product node -Version 10 -Platform x64 - - # Make sure the right Python version is in PATH, and others are not. - - ps: |- - # Remove the wrong Python version(s) from PATH. - $p = $env:PATH -split ";" | where { - -not (Test-Path "$_\python.exe") -and - -not (Test-Path "$_\pip.exe") - } - # Add binary dir for `pip --user` packages. - $p += "$env:APPDATA\Python\Scripts" - # Add python27-x64. - $p += "c:\Python27-x64" - $p += "c:\Python27-x64\Scripts" - $env:PATH = $p -join ";" - - # Pip on Appveyor is too old. Install a recent version in our user dir. - - python -m pip install --upgrade --user pip - - # Install Python packages. - - pip install --upgrade --user pywin32 yapf - - # Add Rust/Cargo to PATH. - - ps: $env:PATH += ";$env:CARGO_HOME\bin" - - # Look for Rust updates. - # * If there are no updates, rustup will exit cleanly. - # * If there are updates, rustup will attempt to install them, and then blow - # up because we removed the 'rust-docs' component. - # * The actual update is done by removing and reinstalling with rustup-init. - - ps: |- - if (Get-SaveCache -and (Test-Path $env:CARGO_HOME)) { - try { - Exec -NoNewLines { & rustup update stable-x86_64-pc-windows-msvc } - } catch { - Delete-Tree $env:CARGO_HOME, $env:RUSTUP_HOME - } - } - - # Install or reinstall Rust via rustup-init. - # * After install/update, the rustup directory is very big, with many files, - # slowing down cache save/restore a lot, so we remove unnecessary stuff. - # * TODO: Use `rustup component remove docs` instead, when this issue - # is resolved: https://github.com/rust-lang-nursery/rustup.rs/issues/998. - # * TODO: Ship Rust in the third_party repo. See issue #386. - - ps: |- - if (-not (Test-Path $env:CARGO_HOME)) { - Invoke-WebRequest -Uri "https://win.rustup.rs" ` - -OutFile "$env:TEMP\rustup-init.exe" - Exec -NoNewLines { & "$env:TEMP\rustup-init.exe" -y } - Delete-Tree @( - "$env:RUSTUP_HOME\downloads", - "$env:RUSTUP_HOME\tmp", - "$env:RUSTUP_HOME\toolchains\stable-x86_64-pc-windows-msvc\share\doc" - ) - } - - # Log installed Node.js version + processor architecture. - - node -p "`Node ${process.version} ${process.arch}`" - - # Log installed Python version + processor architecture. - - ps: |- - @("from sys import version", - "print 'Python', version") -join "`n" | & python - - - # Log some more versions. - - pip --version - - rustc --version - - cargo --version - -before_build: - # Mark all files in the build dir 'not needed' until proven otherwise. - # TODO: also track files in third_party that aren't checked into the repo. - - ps: Start-TraceFilesNeeded $env:DENO_BUILD_PATH -Recurse - - # Download clang and gn, generate ninja files. - - python tools\setup.py - - ps: Set-FilesNeeded -Auto -Reason "Setup finished" - - # Mark files that are produced during the build, and are known to ninja, as - # needed. We obtain this list by dry-running `ninja -t clean`. - - ps: |- - $outputs = ninja -C $env:DENO_BUILD_PATH -n -t clean -g | - where { $_ -match "^Remove (.*)$" } | - foreach { "$env:DENO_BUILD_PATH\$($Matches[1])" } - Set-FilesNeeded -Auto -Path $outputs -Reason "Build dependency graph" - -build_script: - - python tools\build.py - - ps: Set-FilesNeeded -Auto -Reason "Build finished" - -test_script: - - python tools\lint.py - - ps: Exec { & python tools\test.py $env:DENO_BUILD_PATH } - -after_test: - # Remove stale files and empty dirs from the build directory. - - ps: Stop-TraceFilesNeeded - - # Verify that the build is fully up-to-date. Running ninja should be a no-op. - # This catches erroneous file cleanup, and incorrectly set up build deps. - - ps: |- - $out = ninja -C $env:DENO_BUILD_PATH -n -d explain - if ($out -notcontains "ninja: no work to do.") { - throw "Build should be up-to-date but isnt't." - } - - # Verify that generated ninja files do not use absolute path names. - # If they do, it makes ccache/sccache much less effective. - - ps: |- - $trap = "NO_ABS_PATH_PLS" - $dir = "$env:APPVEYOR_BUILD_FOLDER\out\$trap" - Exec { gn gen $dir | Out-Null } - $files = Get-Tree $dir -File -Force -Recurse | where Extension -ne ".dll" - Select-String $trap -Path $files -SimpleMatch | tee -Variable line_matches - if ($line_matches) { - $ctx = $line_matches.Line | - Select-String "[^\s;,]*[\s=]*[^\s;,=]*$trap[^\s;,]*" -AllMatches | - foreach { $_.Matches.Value -replace '\$(.)', '$1' } | - sort -Unique - throw @("Absolute path(s) found in build script:") + $ctx -join "`n " - } - - # If this build is going to be deployed, build a zip file. - - ps: |- - if ($env:APPVEYOR_REPO_TAG -eq "true") { - Compress-Archive -CompressionLevel Optimal -Force ` - -Path "$env:DENO_BUILD_PATH\deno.exe" ` - -DestinationPath "$env:APPVEYOR_BUILD_FOLDER\$env:RELEASE_ARTIFACT" - } - -artifacts: - path: $(RELEASE_ARTIFACT) - -deploy: - provider: GitHub - auth_token: - secure: HQIIUEOtep3yRiBacZCtX8hVmgtdNvt6Hx7u9fP4Wj2ZYp+eBFP2OLf67RKVa5VZ - on: - APPVEYOR_REPO_NAME: denoland/deno - APPVEYOR_REPO_TAG: true diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 3385d7774c29a6..00000000000000 --- a/.gitattributes +++ /dev/null @@ -1,5 +0,0 @@ -# Auto-detect text files. -* text=auto - -# Force Unix EOLs, to prevent Windows from breaking them. -*.* text eol=lf diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 51eb81ca8bb148..00000000000000 --- a/.gitignore +++ /dev/null @@ -1,12 +0,0 @@ -# build -/out/ -*.pyc -gclient_config.py_entries -Cargo.lock -yarn.lock -# npm deps -node_modules -.idea - -# RLS generated files -/target/ diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index fd6e074e6d7253..00000000000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "third_party"] - path = third_party - url = https://github.com/denoland/deno_third_party.git diff --git a/.gn b/.gn deleted file mode 100644 index 0892ffc862fcbe..00000000000000 --- a/.gn +++ /dev/null @@ -1,49 +0,0 @@ -# This file is used by the GN meta build system to find the root of the source -# tree and to set startup options. For documentation on the values set in this -# file, run "gn help dotfile" at the command line. - -# The location of the build configuration file. -buildconfig = "//build/config/BUILDCONFIG.gn" - -# These are the targets to check headers for by default. The files in targets -# matching these patterns (see "gn help label_pattern" for format) will have -# their includes checked for proper dependencies when you run either -# "gn check" or "gn gen --check". -check_targets = [] - -default_args = { - # Various global chrome args that are unrelated to deno. - proprietary_codecs = false - safe_browsing_mode = 0 - toolkit_views = false - use_aura = false - use_dbus = false - use_gio = false - use_glib = false - use_ozone = false - use_udev = false - - # TODO(ry) We may want to turn on CFI at some point. Disabling for simplicity - # for now. See http://clang.llvm.org/docs/ControlFlowIntegrity.html - is_cfi = false - - is_component_build = false - symbol_level = 1 - treat_warnings_as_errors = false - rust_treat_warnings_as_errors = false - - # https://cs.chromium.org/chromium/src/docs/ccache_mac.md - clang_use_chrome_plugins = false - - v8_deprecation_warnings = false - v8_embedder_string = "-deno" - v8_enable_gdbjit = false - v8_enable_i18n_support = false - v8_experimental_extra_library_files = [] - v8_extra_library_files = [] - v8_imminent_deprecation_warnings = false - v8_monolithic = true - v8_untrusted_code_mitigations = false - v8_use_external_startup_data = false - v8_use_snapshot = true -} diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index dab25cd2a20413..00000000000000 --- a/.prettierignore +++ /dev/null @@ -1 +0,0 @@ -js/flatbuffers.js diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 27f50544eb41d6..00000000000000 --- a/.travis.yml +++ /dev/null @@ -1,50 +0,0 @@ -language: c++ -os: - - linux - - osx -env: - global: - - CARGO_PATH=$HOME/.cargo/ - - RUSTUP_PATH=$HOME/.rustup/ - - DENO_BUILD_ARGS="use_custom_libcxx=false use_sysroot=false" - - DENO_BUILD_PATH=$HOME/out/Default - - DENO_BUILD_MODE=release - - PATH=$TRAVIS_BUILD_DIR/third_party/llvm-build/Release+Asserts/bin:$CARGO_PATH/bin:$PATH - - CCACHE_CPP2=yes - - CCACHE_SLOPPINESS=time_macros -cache: - ccache: true - directories: - - "$CARGO_PATH" - - "$RUSTUP_PATH" - - third_party/v8/build/linux/debian_sid_amd64-sysroot/ - - third_party/v8/third_party/llvm-build/ -install: | - # Install Rust. - # TODO(ry) Include rustc in third_party https://github.com/denoland/deno/issues/386 - rustc --version - if [ $? != 0 ]; then - curl -sSf https://sh.rustup.rs | sh -s -- -y - fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then - brew install ccache && export PATH="/usr/local/opt/ccache/libexec:$PATH"; - fi -before_script: -- ccache -s -- "./tools/setup.py" -script: -- "./tools/lint.py" -- bash -c "sleep 2100; pkill ninja" & -- "./tools/build.py -j2" -- "./tools/test.py $DENO_BUILD_PATH" -before_deploy: | - # gzip and name release to denote platform - gzip -c $DENO_BUILD_PATH/deno > $DENO_BUILD_PATH/deno_${TRAVIS_OS_NAME}_x64.gz -deploy: - provider: releases - api_key: - secure: RIwv515oDcPAlEvt7uG8FeSFi6Tz6ODJUOXcFj6FYUPszxJ7Cg1kBLKln+fNW5OeOc52VsaZb/vPZ85skyEM6zk2ijL9FcSnnfNEm548w77iH6G0sk09NgBTy6KRXES6NZHD9jN1YTWYkT2G1NQi7mLqxR8a8pnWTbeK5HhtSWGsZPtXqf5iQbvnWsmKA0/w+FIgKupU0xe/qsYjh0eMLYpZDUWoKO0VxBKJ/ix5Uz91aJTjMIcHHij+ALg4pk+FkDotdyx39XB9b25KDxGuaI7NxWjSPzDxs/ZBHP6QYDLO0ti93ftvLAxRoBKPFoZrXqAu3KG9anr9WvxE40DO9OdV0VX2ZUatMUQm3DpSheN8ml2sErFqjIInqlpkdOVDYORz7FikPxkb9DKt+iuyFfxPRa4YWJv2tg8+Hy/nRCQw69OoKqrSNJ8KJDB3OjYbRBtdHz79RLJhTsGZla6RiyXfM7crR7CbFjbwdbW3Pt60t24fhvXQ0SwR0QTgzS/ieYEQHq/9GtSQA/Tn4kdIkyN6BdOMrQd/aUtgKmNdqbSlfmWGNyNZIxHdB+3RrTNT1tagkRI4UHEUfEujpIdYKwLjv0Xmi/VtTM+zOSkzHsIWGPfHBmIGnXfAItUHqivQYJ15E+dzg3T1CEbBxkDQtvwien9Fa8/pBsMkyovl8ps= - file: "$DENO_BUILD_PATH/deno_${TRAVIS_OS_NAME}_x64.gz" - on: - tags: true - repo: denoland/deno diff --git a/BUILD.gn b/BUILD.gn deleted file mode 100644 index 0cae2087f74df0..00000000000000 --- a/BUILD.gn +++ /dev/null @@ -1,334 +0,0 @@ -# Copyright 2018 the Deno authors. All rights reserved. MIT license. -import("//build/toolchain/cc_wrapper.gni") -import("//third_party/v8/gni/v8.gni") -import("//third_party/v8/snapshot_toolchain.gni") -import("//build_extra/flatbuffers/flatbuffer.gni") -import("//build_extra/flatbuffers/rust/rust_flatbuffer.gni") -import("//build_extra/deno.gni") -import("//build_extra/rust/rust.gni") -import("//build_extra/toolchain/validate.gni") - -group("default") { - testonly = true - deps = [ - ":deno", - ":deno_ns", - ":test_cc", - ":test_rs", - ] -} - -config("deno_config") { - include_dirs = [ "third_party/v8" ] # This allows us to v8/src/base/ libraries. - configs = [ "third_party/v8:external_config" ] - if (is_debug) { - defines = [ "DEBUG" ] - } - - # Targets built with the `rust_executable()` template automatically pick up - # these dependencies, but those built with `executable()` need them when they - # have Rust inputs. Currently, there's only one such target, `test_cc`. - if (is_mac) { - libs = [ "resolv" ] - } - if (is_win) { - libs = [ "userenv.lib" ] - } -} - -main_extern = [ - "$rust_build:hyper", - "$rust_build:hyper_rustls", - "$rust_build:futures", - "$rust_build:libc", - "$rust_build:log", - "$rust_build:ring", - "$rust_build:tempfile", - "$rust_build:rand", - "$rust_build:tokio", - "$rust_build:url", - "//build_extra/flatbuffers/rust:flatbuffers", - ":msg_rs", -] - -rust_executable("deno") { - source_root = "src/main.rs" - extern = main_extern - deps = [ - ":libdeno", - ] -} - -# This target is for fast incremental development. -# When modifying the javascript runtime, this target will not go through the -# extra process of building a snapshot and instead load the bundle from disk. -# ns = no snapshot -rust_executable("deno_ns") { - source_root = "src/main.rs" - extern = main_extern - deps = [ - ":libdeno_nosnapshot", - ] -} - -rust_test("test_rs") { - source_root = "src/main.rs" - extern = main_extern - deps = [ - ":libdeno", - ] -} - -v8_executable("test_cc") { - testonly = true - sources = [ - "libdeno/test.cc", - ] - deps = [ - ":deno_base_test", - "//testing/gtest:gtest", - ] - configs = [ ":deno_config" ] -} - -static_library("libdeno") { - complete_static_lib = true - sources = [ - "libdeno/from_snapshot.cc", - ] - inputs = [ - "$target_gen_dir/snapshot_deno.bin", - ] - deps = [ - ":create_snapshot_deno", - ":deno_bindings", - ] - configs += [ ":deno_config" ] - - # from_snapshot.cc uses an assembly '.incbin' directive to embed the snapshot. - # This causes trouble when using sccache: since the snapshot file is not - # inlined by the c preprocessor, sccache doesn't take its contents into - # consideration, leading to false-positive cache hits. - # Maybe other caching tools have this issue too, but ccache is unaffected. - # Therefore, if a cc_wrapper is used that isn't ccache, include a generated - # header file that contains the the sha256 hash of the snapshot. - if (cc_wrapper != "" && cc_wrapper != "ccache") { - hash_h = "$target_gen_dir/bundle/hash.h" - inputs += [ hash_h ] - deps += [ ":bundle_hash_h" ] - if (is_win) { - cflags = [ "/FI" + rebase_path(hash_h, target_out_dir) ] - } else { - cflags = [ - "-include", - rebase_path(hash_h, target_out_dir), - ] - } - } -} - -# Only functionality needed for libdeno_test and snapshot_creator -# In particular no flatbuffers, no assets, no rust, no msg handlers. -# Because snapshots are slow, it's important that snapshot_creator's -# dependencies are minimal. -v8_source_set("deno_base") { - sources = [ - "libdeno/binding.cc", - "libdeno/deno.h", - "libdeno/file_util.cc", - "libdeno/file_util.h", - "libdeno/internal.h", - ] - public_deps = [ - "third_party/v8:v8_monolith", - ] - configs = [ ":deno_config" ] -} - -v8_source_set("deno_base_test") { - testonly = true - sources = [ - "libdeno/file_util_test.cc", - "libdeno/from_snapshot.cc", - "libdeno/libdeno_test.cc", - ] - inputs = [ - "$target_gen_dir/snapshot_libdeno_test.bin", - ] - deps = [ - ":create_snapshot_libdeno_test", - ":deno_base", - "//testing/gtest:gtest", - ] - defines = [ "LIBDENO_TEST" ] - configs = [ ":deno_config" ] -} - -v8_source_set("deno_bindings") { - deps = [ - ":deno_base", - ] - configs = [ ":deno_config" ] -} - -executable("snapshot_creator") { - sources = [ - "libdeno/snapshot_creator.cc", - ] - deps = [ - ":deno_base", - ] - configs += [ ":deno_config" ] -} - -# Generates type declarations for files that need to be included -# in the runtime bundle -run_node("gen_declarations") { - out_dir = target_gen_dir - sources = [ - "js/compiler.ts", - "js/console.ts", - "js/deno.ts", - "js/globals.ts", - "js/os.ts", - "js/timers.ts", - "js/tsconfig.generated.json", - "js/util.ts", - ] - outputs = [ - out_dir + "/js/compiler.d.ts", - out_dir + "/js/console.d.ts", - out_dir + "/js/deno.d.ts", - out_dir + "/js/globals.d.ts", - out_dir + "/js/os.d.ts", - out_dir + "/js/timers.d.ts", - out_dir + "/js/util.d.ts", - ] - deps = [ - ":msg_ts", - ] - args = [ - "./node_modules/typescript/bin/tsc", - "-p", - rebase_path("js/tsconfig.generated.json", root_build_dir), - "--baseUrl", - rebase_path(root_build_dir, root_build_dir), - "--outDir", - rebase_path(out_dir, root_build_dir), - ] -} - -run_node("bundle") { - out_dir = "$target_gen_dir/bundle/" - sources = [ - "js/assets.ts", - "js/compiler.ts", - "js/console.ts", - "js/fetch.ts", - "js/fetch_types.d.ts", - "js/globals.ts", - "js/lib.globals.d.ts", - "js/main.ts", - "js/os.ts", - "js/plugins.d.ts", - "js/text_encoding.ts", - "js/timers.ts", - "js/types.d.ts", - "js/util.ts", - "js/v8_source_maps.ts", - "rollup.config.js", - "src/msg.fbs", - "tsconfig.json", - ] - outputs = [ - out_dir + "main.js", - out_dir + "main.js.map", - ] - deps = [ - ":gen_declarations", - ":msg_ts", - ] - args = [ - "./node_modules/rollup/bin/rollup", - "-c", - rebase_path("rollup.config.js", root_build_dir), - "-i", - rebase_path("js/main.ts", root_build_dir), - "-o", - rebase_path(out_dir + "main.js", root_build_dir), - "--sourcemapFile", - rebase_path("."), - "--silent", - "--environment", - "BASEPATH:" + rebase_path(".", root_build_dir), - ] -} - -action("bundle_hash_h") { - script = "//tools/sha256sum.py" - inputs = get_target_outputs(":bundle") - outputs = [ - "$target_gen_dir/bundle/hash.h", - ] - deps = [ - ":bundle", - ] - args = [ - "--format", - "__attribute__((__unused__)) static const int dummy_%s = 0;", - "--outfile", - rebase_path(outputs[0], root_build_dir), - ] - foreach(input, inputs) { - args += [ - "--infile", - rebase_path(input, root_build_dir), - ] - } -} - -source_set("libdeno_nosnapshot") { - bundle_outputs = get_target_outputs(":bundle") - bundle_location = rebase_path(bundle_outputs[0], root_build_dir) - bundle_map_location = rebase_path(bundle_outputs[1], root_build_dir) - inputs = bundle_outputs - sources = [ - "libdeno/from_filesystem.cc", - ] - deps = [ - ":bundle", - ":deno_bindings", - ] - configs += [ ":deno_config" ] - defines = [ - "BUNDLE_LOCATION=\"$bundle_location\"", - "BUNDLE_MAP_LOCATION=\"$bundle_map_location\"", - ] -} - -ts_flatbuffer("msg_ts") { - sources = [ - "src/msg.fbs", - ] -} - -rust_flatbuffer("msg_rs") { - sources = [ - "src/msg.fbs", - ] -} - -# Generates $target_gen_dir/snapshot_deno.bin -create_snapshot("deno") { - js = "$target_gen_dir/bundle/main.js" - source_map = "$target_gen_dir/bundle/main.js.map" - deps = [ - ":bundle", - ] -} - -# Generates $target_gen_dir/snapshot_libdeno_test.bin -create_snapshot("libdeno_test") { - testonly = true - js = "libdeno/libdeno_test.js" -} diff --git a/Cargo.toml b/Cargo.toml deleted file mode 100644 index 1407831c1a72cd..00000000000000 --- a/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -# Dummy package info required by `cargo fetch`. -# Use tools/sync_third_party.py to install deps after editing this file. -# Deno does not build with cargo. Deno uses a build system called gn. -# See build_extra/rust/BUILD.gn for the manually built configuration of rust -# crates. -[package] -name = "deno" -version = "0.0.0" - -[dependencies] -url = "1.7.1" -libc = "0.2.42" -log = "0.4.3" -rand = "0.4.2" -tempfile = "3" -tokio = "0.1" -hyper = "0.12.8" -hyper-rustls = "0.14.0" diff --git a/LICENSE b/LICENSE deleted file mode 100644 index bd98abb828c4ce..00000000000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018 Ryan Dahl - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/README.md b/README.md index c13616d682d71e..6f51878948ee6e 100644 --- a/README.md +++ b/README.md @@ -1,109 +1 @@ -# deno - -| **Linux & Mac** | **Windows** | -|:---------------:|:-----------:| -| [![Travis](https://travis-ci.com/denoland/deno.svg?branch=master)](https://travis-ci.com/denoland/deno) | [![Appveyor](https://ci.appveyor.com/api/projects/status/yel7wtcqwoy0to8x?branch=master&svg=true)](https://ci.appveyor.com/project/deno/deno) | - - - -## A secure TypeScript runtime built on V8 - -* Supports TypeScript 3.0.1 out of the box. Uses V8 6.9.297. That is, it's - very modern JavaScript. - -* No `package.json`. No npm. Not explicitly compatible with Node. - -* Imports reference source code URLs only. - ``` - import { test } from "https://unpkg.com/deno_testing@0.0.5/testing.ts" - import { log } from "./util.ts" - ``` - Remote code is fetched and cached on first execution, and never updated until - the code is run with the `--reload` flag. (So, this will still work on an - airplane. See `~/.deno/src` for details on the cache.) - -* File system and network access can be controlled in order to run sandboxed - code. Defaults to read-only file system access and no network access. - Access between V8 (unprivileged) and Rust (privileged) is only done via - serialized messages defined in this - [flatbuffer](https://github.com/denoland/deno/blob/master/src/msg.fbs). This makes it - easy to audit. - To enable write access explicitly use `--allow-write` and `--allow-net` for - network access. - -* Single executable: - ``` - > ls -lh out/release/deno - -rwxr-xr-x 1 rld staff 48M Aug 2 13:24 out/release/deno - > otool -L out/release/deno - out/release/deno: - /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.50.4) - /usr/lib/libresolv.9.dylib (compatibility version 1.0.0, current version 1.0.0) - /System/Library/Frameworks/Security.framework/Versions/A/Security (compatibility version 1.0.0, current version 58286.51.6) - /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.0) - > - ``` - -* Always dies on uncaught errors. - -* Supports top-level `await`. - -* Aims to be browser compatible. - - -## Status - -Under development. - -We make binary releases [here](https://github.com/denoland/deno/releases). - -Progress towards future releases is tracked -[here](https://github.com/denoland/deno/milestones). - -Roadmap is [here](https://github.com/denoland/deno/blob/master/Roadmap.md). -Also see [this presentation](http://tinyclouds.org/jsconf2018.pdf). - -[Chat room](https://gitter.im/denolife/Lobby). - - -## Build instructions - -To ensure reproducible builds, Deno has most of its dependencies in a git -submodule. However, you need to install separately: - -1. [Rust](https://www.rust-lang.org/en-US/install.html) -2. [Node](http://nodejs.org/) -3. Python 2. [Not 3](https://github.com/denoland/deno/issues/464#issuecomment-411795578). -4. [ccache](https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Build_Instructions/ccache) (Optional but helpful for speeding up rebuilds of V8.) -. - -To build: - - # Fetch deps. - git clone --recurse-submodules https://github.com/denoland/deno.git - cd deno - ./tools/setup.py - - # Build. - ./tools/build.py - - # Run - ./out/debug/deno tests/002_hello.ts - -Other useful commands: - - # Call ninja manually. - ./third_party/depot_tools/ninja -C out/debug - # Build a release binary. - DENO_BUILD_MODE=release ./tools/build.py :deno - # List executable targets. - ./third_party/depot_tools/gn ls out/debug //:* --as=output --type=executable - # List build configuation. - ./third_party/depot_tools/gn args out/debug/ --list - # Edit build configuration. - ./third_party/depot_tools/gn args out/debug/ - # Describe a target. - ./third_party/depot_tools/gn desc out/debug/ :deno - ./third_party/depot_tools/gn help - -Env vars: `DENO_BUILD_MODE`, `DENO_BUILD_PATH`, `DENO_BUILD_ARGS`. +https://github.com/denoland/deno diff --git a/Roadmap.md b/Roadmap.md deleted file mode 100644 index 67a5a66f5c85dd..00000000000000 --- a/Roadmap.md +++ /dev/null @@ -1,404 +0,0 @@ -# Deno Roadmap - -API and Feature requests should be submitted as PRs to this document. - -## Target Use Cases - -### Low-level, fast memory efficient sockets - -Example, non-final API for piping a socket to stdout: - -```javascript -function nonblockingpipe(fd) { - let buf = new Uint8Array(1024); // Fixed 1k buffer. - for (;;) { - let code = await deno.pollNB(fd, deno.POLL_RD | deno.POLL_WR); - switch (code) { - case "READABLE": - let [nread, err] = deno.readNB(fd, buf, buf.byteSize); - if (err === "EAGAIN") continue; - if (err != null) break; - await deno.stdout.write(buf.slice(0, nread)); - break; - case "ERROR": - throw Error("blah"); - } - } -} -``` - -### List deps - -``` -% deno --list-deps http://gist.com/blah.js -http://gist.com/blah.js -http://gist.com/dep.js -https://github.com/denoland/deno/master/testing.js -% -``` - -## Security Model - -* We want to be secure by default; user should be able to run untrusted code, - like the web. -* Threat model: - * Modifiying/deleting local files - * Leaking private information -* Disallowed default: - * Network access - * Local write access - * Non-JS extensions - * Subprocesses - * Env access -* Allowed default: - * Local read access. - * argv, stdout, stderr, stdin access always allowed. - * Maybe: temp dir write access. (But what if they create symlinks there?) -* The user gets prompted when the software tries to do something it doesn't have - the privilege for. -* Have an option to get a stack trace when access is requested. -* Worried that granting access per file will give a false sense of security due - to monkey patching techniques. Access should be granted per program (js - context). - -Example security prompts. Options are: YES, NO, PRINT STACK -``` -Program requests write access to "~/.ssh/id_rsa". Grant? [yNs] -http://gist.github.com/asdfasd.js requests network access to "www.facebook.com". Grant? [yNs] -Program requests access to environment variables. Grant? [yNs] -Program requests to spawn `rm -rf /`. Grant? [yNs] -``` - -* cli flags to grant access ahead of time --allow-all --allow-write --allow-net - --allow-env --allow-exec -* in version two we will add ability to give finer grain access - --allow-net=facebook.com - -## Milestone 1: Rust rewrite / V8 snapshot - -ETA: July 2018. - -Go is a garbage collected language and we are worried that combining it with -V8's GC will lead to difficult contention problems down the road. - -The V8Worker2 binding/concept is being ported to a new C++ library called -libdeno. libdeno will include the entire JS runtime as a V8 snapshot. It still -follows the message passing paradigm. Rust will be bound to this library to -implement the privileged part of Deno. See deno2/README.md for more details. - -V8 Snapshots allow Deno to avoid recompiling the TypeScript compiler at -startup. This is already working. - -When the rewrite is at feature parity with the Go prototype, we will release -binaries for people to try. - -## libdeno C API. - -Deno's privileged side will primarily be programmed in Rust. However there -will be a small C API that wraps V8 to 1) define the low-level message passing -semantics 2) provide a low-level test target 3) provide an ANSI C API binding -interface for Rust. V8 plus this C API is called libdeno and the important bits -of the API is specified here: - -```c -// Data that gets transmitted. -typedef struct { - const char* data; - size_t len; -} deno_buf; - -typedef void (*deno_sub_cb)(Deno* d, deno_buf bufs[], size_t nbufs) -void deno_set_callback(Deno* deno, deno_sub_cb cb); - -// Executes javascript source code. -// Get error text with deno_last_exception(). -// 0 = success, non-zero = failure. -// TODO(ry) Currently the return code has opposite semantics. -int deno_execute(Deno* d, const char* js_filename, const char* js_source); - -// This call doesn't go into JS. This is thread-safe. -// TODO(ry) Currently this is called deno_pub. It should be renamed. -// deno_append is the desired name. -void deno_append(deno_buf buf); - -// Should only be called at most once during the deno_sub_cb. -void deno_set_response(Deno* deno, deno_buf bufs[], size_t nbufs); - -const char* deno_last_exception(Deno* d); -``` - -## TypeScript API. - - -There are three layers of API to consider: -* L1: the low-level message passing API exported by libdeno (L1), -* L2: the flatbuffer messages used internally (L2), -* L3: the final "deno" namespace exported to users (L3). - -### L1 - -```typescript -function send(...ab: ArrayBuffer[]): ArrayBuffer[] | null; -``` -Used to make calls outside of V8. Send an ArrayBuffer and synchronously receive -an ArrayBuffer back. - -```typescript -function poll(): ArrayBuffer[]; -``` -Poll for new asynchronous events from the privileged side. This will be done -as the main event loop. - -```typescript -function print(x: string): void; -``` -A way to print to stdout. Although this could be easily implemented thru -`send()` this is an important debugging tool to avoid intermediate -infrastructure. - - -The current implementation is out of sync with this document: -https://github.com/denoland/deno/blob/master/js/deno.d.ts - -#### L1 Examples - -The main event loop of Deno should look something like this: -```js -function main() { - // Setup... - while (true) { - const messages = deno.poll(); - processMessages(messages); - } -} -``` - - -### L2 - -https://github.com/denoland/deno/blob/master/src/msg.fbs - -### L3 - -With in Deno this is the high-level user facing API. However, the intention -is to expose functionality as simply as possible. There should be little or -no "ergonomics" APIs. (For example, `deno.readFileSync` only deals with -ArrayBuffers and does not have an encoding parameter to return strings.) -The intention is to make very easy to extend and link in external modules -which can then add this functionality. - -Deno does not aim to be API compatible with Node in any respect. Deno will -export a single flat namespace "deno" under which all core functions are -defined. We leave it up to users to wrap Deno's namespace to provide some -compatibility with Node. - -*Top-level await*: This will be put off until at least deno2 Milestone1 is -complete. One of the major problems is that top-level await calls are not -syntactically valid TypeScript. - -Functions exported under Deno namespace: -```ts -deno.readFileSync(filename: string): ArrayBuffer; -deno.writeFileSync(filename: string, data: Uint8Array, perm: number): void; -``` - -Timers: -```ts -setTimeout(cb: TimerCallback, delay: number, ...args: any[]): number; -setInterval(cb: TimerCallbac, duration: number, ...args: any[]): number; -clearTimeout(timerId: number); -clearInterval(timerId: number); -``` - -Console: -```ts -declare var console: { - log(...args: any[]): void; - error(...args: any[]): void; - assert(assertion: boolean, ...msg: any[]): void; -} -``` - -URL: -```ts -URL(url: string, base?: string): URL; -``` - -Text encoding: -```ts -declare var TextEncoder: { - new (utfLabel?: string, options?: TextEncoderOptions): TextEncoder; - (utfLabel?: string, options?: TextEncoderOptions): TextEncoder; - encoding: string; -}; - -declare var TextDecoder: { - new (label?: string, options?: TextDecoderOptions): TextDecoder; - (label?: string, options?: TextDecoderOptions): TextDecoder; - encoding: string; -}; -``` - -Fetch API: -```ts -fetch(input?: Request | string, init?: RequestInit): Promise; -``` - -#### I/O - -There are many OS constructs that perform I/O: files, sockets, pipes. -Deno aims to provide a unified lowest common denominator interface to work with -these objects. Deno needs to operate on all of these asynchronously in order -to not block the event loop and it. - -Sockets and pipes support non-blocking reads and write. Generally file I/O is -blocking but it can be done in a thread pool to avoid blocking the main thread. -Although file I/O can be made asynchronous, it does not support the same -non-blocking reads and writes that sockets and pipes do. - -The following interfaces support files, socket, and pipes and are heavily -inspired by Go. The main difference in porting to JavaScript is that errors will -be handled by exceptions, modulo EOF, which is returned as part of -`ReadResult`. - -```ts -// The bytes read during an I/O call and a boolean indicating EOF. -interface ReadResult { - nread: number; - eof: boolean; -} - -// Reader is the interface that wraps the basic read() method. -// https://golang.org/pkg/io/#Reader -interface Reader { - // read() reads up to p.byteLength bytes into p. It returns the number of bytes - // read (0 <= n <= p.byteLength) and any error encountered. Even if read() - // returns n < p.byteLength, it may use all of p as scratch space during the - // call. If some data is available but not p.byteLength bytes, read() - // conventionally returns what is available instead of waiting for more. - // - // When read() encounters an error or end-of-file condition after successfully - // reading n > 0 bytes, it returns the number of bytes read. It may return the - // (non-nil) error from the same call or return the error (and n == 0) from a - // subsequent call. An instance of this general case is that a Reader - // returning a non-zero number of bytes at the end of the input stream may - // return either err == EOF or err == nil. The next read() should return 0, EOF. - // - // Callers should always process the n > 0 bytes returned before considering - // the error err. Doing so correctly handles I/O errors that happen after - // reading some bytes and also both of the allowed EOF behaviors. - // - // Implementations of read() are discouraged from returning a zero byte count - // with a nil error, except when p.byteLength == 0. Callers should treat a - // return of 0 and nil as indicating that nothing happened; in particular it - // does not indicate EOF. - // - // Implementations must not retain p. - async read(p: ArrayBufferView): Promise; -} - -// Writer is the interface that wraps the basic write() method. -// https://golang.org/pkg/io/#Writer -interface Writer { - // write() writes p.byteLength bytes from p to the underlying data stream. It - // returns the number of bytes written from p (0 <= n <= p.byteLength) and any - // error encountered that caused the write to stop early. write() must return a - // non-nil error if it returns n < p.byteLength. write() must not modify the - // slice data, even temporarily. - // - // Implementations must not retain p. - async write(p: ArrayBufferView): Promise; -} - -// https://golang.org/pkg/io/#Closer -interface Closer { - // The behavior of Close after the first call is undefined. Specific - // implementations may document their own behavior. - close(): void; -} - -// https://golang.org/pkg/io/#Seeker -interface Seeker { - // Seek sets the offset for the next read() or write() to offset, interpreted - // according to whence: SeekStart means relative to the start of the file, - // SeekCurrent means relative to the current offset, and SeekEnd means - // relative to the end. Seek returns the new offset relative to the start of - // the file and an error, if any. - // - // Seeking to an offset before the start of the file is an error. Seeking to - // any positive offset is legal, but the behavior of subsequent I/O operations - // on the underlying object is implementation-dependent. - async seek(offset: number, whence: number): Promise; -} - -// https://golang.org/pkg/io/#ReadCloser -interface ReaderCloser extends Reader, Closer { } - -// https://golang.org/pkg/io/#WriteCloser -interface WriteCloser extends Writer, Closer { } - -// https://golang.org/pkg/io/#ReadSeeker -interface ReadSeeker extends Reader, Seeker { } - -// https://golang.org/pkg/io/#WriteSeeker -interface WriteSeeker extends Writer, Seeker { } - -// https://golang.org/pkg/io/#ReadWriteCloser -interface ReadWriteCloser extends Reader, Writer, Closer { } - -// https://golang.org/pkg/io/#ReadWriteSeeker -interface ReadWriteSeeker extends Reader, Writer, Seeker { } -``` -These interfaces are well specified, simple, and have very nice utility -functions that will be easy to port. Some example utilites: -```ts -// copy() copies from src to dst until either EOF is reached on src or an error -// occurs. It returns the number of bytes copied and the first error encountered -// while copying, if any. -// -// Because copy() is defined to read from src until EOF, it does not treat an EOF -// from read() as an error to be reported. -// -// https://golang.org/pkg/io/#Copy -async function copy(dst: Writer, src: Reader): Promise { - let n = 0; - const b = new ArrayBufferView(1024); - let got_eof = false; - while (got_eof === false) { - let result = await src.read(b); - if (result.eof) got_eof = true; - n += await dst.write(b.subarray(0, result.nread)); - } - return n; -} - -// MultiWriter creates a writer that duplicates its writes to all the provided -// writers, similar to the Unix tee(1) command. -// -// Each write is written to each listed writer, one at a time. If a listed -// writer returns an error, that overall write operation stops and returns the -// error; it does not continue down the list. -// -// https://golang.org/pkg/io/#MultiWriter -function multiWriter(writers: ...Writer): Writer { - return { - write: async (p: ArrayBufferView) => Promise { - let n; - let nwritten = await Promise.all(writers.map((w) => w.write(p))); - return nwritten[0]; - // TODO unsure of proper semantics for return value.. - } - }; -} -``` - -A utility function will be provided to make any `Reader` into an -`AsyncIterator`, which has very similar semanatics. - -```ts -function readerIterator(r: deno.Reader): AsyncIterator; -// Example -for await (let buf of readerIterator(socket)) { - console.log(`read ${buf.byteLength} from socket`); -} -``` diff --git a/build b/build deleted file mode 120000 index 57ae3a6c85f87c..00000000000000 --- a/build +++ /dev/null @@ -1 +0,0 @@ -third_party/v8/build \ No newline at end of file diff --git a/build_extra/deno.gni b/build_extra/deno.gni deleted file mode 100644 index 08cccfdea96a9e..00000000000000 --- a/build_extra/deno.gni +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright 2018 the Deno authors. All rights reserved. MIT license. -import("//build/compiled_action.gni") - -template("run_node") { - action(target_name) { - forward_variables_from(invoker, "*") - script = "//tools/run_node.py" - } -} - -# Template to generate different V8 snapshots based on different runtime flags. -# Can be invoked with run_mksnapshot(). The target will resolve to -# run_mksnapshot_. If is "default", no file suffixes will be used. -# Otherwise files are suffixed, e.g. embedded_.cc and -# snapshot_blob_.bin. -# -# The template exposes the variables: -# args: additional flags for mksnapshots -# embedded_suffix: a camel case suffix for method names in the embedded -# snapshot. -template("create_snapshot") { - name = target_name - compiled_action("create_snapshot_" + name) { - forward_variables_from(invoker, - [ - "testonly", - "deps", - ]) - tool = ":snapshot_creator" - visibility = [ ":*" ] # Only targets in this file can depend on this. - snapshot_out_bin = "$target_gen_dir/snapshot_$name.bin" - inputs = [ - invoker.js, - ] - if (defined(invoker.source_map)) { - inputs += [ invoker.source_map ] - } - outputs = [ - snapshot_out_bin, - ] - args = rebase_path(outputs, root_build_dir) + - rebase_path(inputs, root_build_dir) - - # To debug snapshotting problems: - # args += ["--trace-serializer"] - } -} diff --git a/build_extra/flatbuffers/BUILD.gn b/build_extra/flatbuffers/BUILD.gn deleted file mode 100644 index aaf82422c50563..00000000000000 --- a/build_extra/flatbuffers/BUILD.gn +++ /dev/null @@ -1,128 +0,0 @@ -# Copyright 2016 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("flatbuffer.gni") - -fb_src = flatbuffers_source_location - -config("flatbuffers_config") { - include_dirs = [ "$fb_src/include" ] - - if (is_clang) { - cflags = [ - "-Wno-exit-time-destructors", - "-Wno-header-hygiene", - - # TODO: rust branch of flatbuffers has this warning. - # This should be removed when the branch fixed. - "-Wno-return-type", - ] - } -} - -# The part of FlatBuffers that Chrome is interested in. -source_set("flatbuffers") { - sources = [ - "$fb_src/include/flatbuffers/flatbuffers.h", - ] - - configs -= [ "//build/config/compiler:chromium_code" ] - configs += [ "//build/config/compiler:no_chromium_code" ] - - public_configs = [ ":flatbuffers_config" ] -} - -# The complete FlatBuffers library, as required to build the flatc compiler and -# some of the tests. -source_set("compiler_files") { - include_dirs = [ "$fb_src/grpc" ] - sources = [ - "$fb_src/grpc/src/compiler/config.h", - "$fb_src/grpc/src/compiler/config.h", - "$fb_src/grpc/src/compiler/cpp_generator.cc", - "$fb_src/grpc/src/compiler/cpp_generator.h", - "$fb_src/grpc/src/compiler/go_generator.cc", - "$fb_src/grpc/src/compiler/go_generator.h", - "$fb_src/grpc/src/compiler/java_generator.cc", - "$fb_src/grpc/src/compiler/java_generator.h", - "$fb_src/grpc/src/compiler/schema_interface.h", - "$fb_src/include/flatbuffers/code_generators.h", - "$fb_src/include/flatbuffers/flatc.h", - "$fb_src/include/flatbuffers/flexbuffers.h", - "$fb_src/include/flatbuffers/grpc.h", - "$fb_src/include/flatbuffers/hash.h", - "$fb_src/include/flatbuffers/idl.h", - "$fb_src/include/flatbuffers/reflection.h", - "$fb_src/include/flatbuffers/reflection_generated.h", - "$fb_src/include/flatbuffers/util.h", - "$fb_src/src/code_generators.cpp", - "$fb_src/src/flatc.cpp", - "$fb_src/src/idl_gen_cpp.cpp", - "$fb_src/src/idl_gen_dart.cpp", - "$fb_src/src/idl_gen_fbs.cpp", - "$fb_src/src/idl_gen_general.cpp", - "$fb_src/src/idl_gen_go.cpp", - "$fb_src/src/idl_gen_grpc.cpp", - "$fb_src/src/idl_gen_js.cpp", - "$fb_src/src/idl_gen_json_schema.cpp", - "$fb_src/src/idl_gen_lobster.cpp", - "$fb_src/src/idl_gen_lua.cpp", - "$fb_src/src/idl_gen_php.cpp", - "$fb_src/src/idl_gen_python.cpp", - "$fb_src/src/idl_gen_rust.cpp", - "$fb_src/src/idl_gen_text.cpp", - "$fb_src/src/idl_parser.cpp", - "$fb_src/src/reflection.cpp", - "$fb_src/src/util.cpp", - ] - configs -= [ "//build/config/compiler:chromium_code" ] - configs += [ "//build/config/compiler:no_chromium_code" ] - visibility = [ ":*" ] - deps = [ - ":flatbuffers", - ] -} - -executable("flatc") { - sources = [ - "$fb_src/src/flatc_main.cpp", - ] - deps = [ - ":compiler_files", - ":flatbuffers", - ] -} - -# The following is just for testing. - -flatbuffer("flatbuffers_samplebuffer") { - testonly = true - sources = [ - "$fb_src/tests/include_test/include_test1.fbs", - "$fb_src/tests/include_test/sub/include_test2.fbs", - "$fb_src/tests/monster_test.fbs", - "$fb_src/tests/namespace_test/namespace_test1.fbs", - "$fb_src/tests/namespace_test/namespace_test2.fbs", - ] - flatc_include_dirs = [ "$fb_src/tests/include_test" ] -} -# test("flatbuffers_unittest") { -# sources = [ -# "src/tests/test.cpp", -# ] -# deps = [ -# ":compiler_files", -# ":flatbuffers", -# ":flatbuffers_samplebuffer", -# ] -# data = [ -# "src/tests/", -# ] -# -# if (is_win) { -# # Suppress "object allocated on the heap may not be aligned 16". -# cflags = [ "/wd4316" ] -# } -# defines = [ "FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE" ] -# } diff --git a/build_extra/flatbuffers/flatbuffer.gni b/build_extra/flatbuffers/flatbuffer.gni deleted file mode 100644 index ff4a48dfa0a881..00000000000000 --- a/build_extra/flatbuffers/flatbuffer.gni +++ /dev/null @@ -1,239 +0,0 @@ -# Copyright 2016 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//build/compiled_action.gni") - -declare_args() { - # Location of flatbuffers source code. - flatbuffers_source_location = "//third_party/flatbuffers/" - - # Absolute location flatbuffers BUILD.gn file. - flatbuffers_build_location = "//build_extra/flatbuffers/" -} - -# Compile a flatbuffer for C++. -# -# flatc_out_dir (optional) -# Specifies the path suffix that output files are generated under. This -# path will be appended to root_gen_dir. -# -# Targets that depend on the flatbuffer target will be able to include -# the resulting FlatBuffers header with an include like: -# #include "dir/for/my_flatbuffer/buffer_generated.h" -# If undefined, this defaults to matchign the input directory for each -# .fbs file (you should almost always use the default mode). -# -# flatc_include_dirs (optional) -# Specifies the directories which FlatBuffers compiler uses to find -# included .fbs files in. Almost always should be empty. -# -# The list always has an implicit first item corresponding to the root of -# the source tree. This enables including .fbs files by absolute path. -# -# The compiler will try the directories in the order given, and if all -# fail it will try to load relative to the directory of the schema file -# being parsed. -# -# deps (optional) -# Additional dependencies. -# -# Parameters for compiling the generated code: -# -# defines (optional) -# Defines to supply to the source set that compiles the generated source -# code. -# -# extra_configs (optional) -# A list of config labels that will be appended to the configs applying -# to the source set. -# -# testonly (optional) -# Boolean to indicate whether the generated source sets should be labeled -# as testonly. -# -# Example: -# flatbuffer("mylib") { -# sources = [ -# "foo.fbs", -# ] -# } -template("flatbuffer") { - assert(defined(invoker.sources), "Need sources for flatbuffers_library") - - # Don't apply OS-specific sources filtering to the assignments later on. - # Platform files should have gotten filtered out in the sources assignment - # when this template was invoked. If they weren't, it was on purpose and - # this template shouldn't re-apply the filter. - set_sources_assignment_filter([]) - - action_name = "${target_name}_gen" - source_set_name = target_name - compiled_action_foreach(action_name) { - visibility = [ ":$source_set_name" ] - - tool = "$flatbuffers_build_location:flatc" - - sources = invoker.sources - deps = [] - - if (defined(invoker.flatc_out_dir)) { - out_dir = "$root_gen_dir/" + invoker.flatc_out_dir - } else { - out_dir = "{{source_gen_dir}}" - } - - outputs = [ - "$out_dir/{{source_name_part}}_generated.h", - ] - - args = [ - "-c", - "--keep-prefix", - "-o", - "$out_dir", - "-I", - rebase_path("//", root_build_dir), - ] - - if (defined(invoker.flatc_include_dirs)) { - foreach(include_dir, invoker.flatc_include_dirs) { - args += [ - "-I", - rebase_path(include_dir, root_build_dir), - ] - } - } - - args += [ "{{source}}" ] - - # The deps may have steps that have to run before running flatc. - if (defined(invoker.deps)) { - deps += invoker.deps - } - } - - source_set(target_name) { - forward_variables_from(invoker, - [ - "visibility", - "defines", - ]) - - sources = get_target_outputs(":$action_name") - - if (defined(invoker.extra_configs)) { - configs += invoker.extra_configs - } - - if (defined(invoker.testonly)) { - testonly = invoker.testonly - } - - public_configs = [ "$flatbuffers_build_location:flatbuffers_config" ] - - public_deps = [ - # The generated headers reference headers within FlatBuffers, so - # dependencies must be able to find those headers too. - flatbuffers_build_location, - ] - deps = [ - ":$action_name", - ] - - # This will link any libraries in the deps (the use of invoker.deps in the - # action won't link it). - if (defined(invoker.deps)) { - deps += invoker.deps - } - - # Same for public_deps. - if (defined(invoker.public_deps)) { - public_deps += invoker.public_deps - } - } -} - -# Compile a flatbuffer to typescript. -# -# flatc_include_dirs (optional) -# Specifies the directories which FlatBuffers compiler uses to find -# included .fbs files in. Almost always should be empty. -# -# The list always has an implicit first item corresponding to the root of -# the source tree. This enables including .fbs files by absolute path. -# -# The compiler will try the directories in the order given, and if all -# fail it will try to load relative to the directory of the schema file -# being parsed. -# -# deps (optional) -# Additional dependencies. -# -# Example: -# ts_flatbuffer("foo_ts") { -# sources = [ -# "foo.fbs", -# ] -# } -template("ts_flatbuffer") { - assert(defined(invoker.sources), "Need sources for flatbuffers_library") - - # Don't apply OS-specific sources filtering to the assignments later on. - # Platform files should have gotten filtered out in the sources assignment - # when this template was invoked. If they weren't, it was on purpose and - # this template shouldn't re-apply the filter. - set_sources_assignment_filter([]) - - copy_name = target_name + "_copy" - - copy(copy_name) { - sources = [ - "$flatbuffers_source_location/js/flatbuffers.js", - ] - outputs = [ - "$target_gen_dir/flatbuffers.js", - ] - } - - compiled_action_foreach(target_name) { - tool = "$flatbuffers_build_location:flatc" - - sources = invoker.sources - deps = [ - ":" + copy_name, - ] - - out_dir = target_gen_dir - - outputs = [ - "$out_dir/{{source_name_part}}_generated.ts", - ] - - args = [ - "--ts", - "--no-fb-import", - "--gen-mutable", - "-o", - rebase_path(out_dir, root_build_dir), - "-I", - rebase_path("//", root_build_dir), - ] - - if (defined(invoker.flatc_include_dirs)) { - foreach(include_dir, invoker.flatc_include_dirs) { - args += [ - "-I", - rebase_path(include_dir, root_build_dir), - ] - } - } - - args += [ "{{source}}" ] - - # The deps may have steps that have to run before running flatc. - if (defined(invoker.deps)) { - deps += invoker.deps - } - } -} diff --git a/build_extra/flatbuffers/rust/BUILD.gn b/build_extra/flatbuffers/rust/BUILD.gn deleted file mode 100644 index dd4a5c64c41e9a..00000000000000 --- a/build_extra/flatbuffers/rust/BUILD.gn +++ /dev/null @@ -1,6 +0,0 @@ -import("//build_extra/rust/rust.gni") - -rust_crate("flatbuffers") { - source_root = "//third_party/flatbuffers/rust/flatbuffers/src/lib.rs" - args = [ "-Aunused_variables" ] # TODO Remove this. -} diff --git a/build_extra/flatbuffers/rust/rust_flatbuffer.gni b/build_extra/flatbuffers/rust/rust_flatbuffer.gni deleted file mode 100644 index 4255b21ec01f9b..00000000000000 --- a/build_extra/flatbuffers/rust/rust_flatbuffer.gni +++ /dev/null @@ -1,44 +0,0 @@ -import("//build_extra/rust/rust.gni") - -# TODO(ry) "flatbuffer.gni" should be "flatbuffers.gni" we should be consistent -# in our pluralization. -import("//build_extra/flatbuffers/flatbuffer.gni") - -template("rust_flatbuffer") { - action_name = "${target_name}_gen" - source_set_name = target_name - compiled_action_foreach(action_name) { - tool = "$flatbuffers_build_location:flatc" - - sources = invoker.sources - deps = [] - out_dir = target_gen_dir - - outputs = [ - "$out_dir/{{source_name_part}}_generated.rs", - ] - - args = [ - "--rust", - "-o", - rebase_path(out_dir, root_build_dir), - "-I", - rebase_path("//", root_build_dir), - ] - args += [ "{{source}}" ] - - # The deps may have steps that have to run before running flatc. - if (defined(invoker.deps)) { - deps += invoker.deps - } - } - - rust_crate(source_set_name) { - sources = get_target_outputs(":$action_name") - source_root = sources[0] - deps = [ - ":$action_name", - ] - extern = [ "//build_extra/flatbuffers/rust:flatbuffers" ] - } -} diff --git a/build_extra/rust/BUILD.gn b/build_extra/rust/BUILD.gn deleted file mode 100644 index 382f9a90b2970b..00000000000000 --- a/build_extra/rust/BUILD.gn +++ /dev/null @@ -1,810 +0,0 @@ -# Copyright 2018 the Deno authors. All rights reserved. MIT license. - -# Dependencies between third party crates is mapped out here manually. This is -# not so difficult and having it be tedious to add dependencies might help us -# avoid dependency hell later on. Always try to minimize dependencies. -# Versioning for third party rust crates is controlled in //Cargo.toml -# Use //tools/sync_third_party.py instead of running "cargo install". - -import("rust.gni") - -crates = "//third_party/rust_crates" -registry_github = "$crates/registry/src/github.com-1ecc6299db9ec823/" - -rust_crate("libc") { - source_root = "$registry_github/libc-0.2.42/src/lib.rs" - features = [ "use_std" ] -} - -rust_crate("url") { - source_root = "$registry_github/url-1.7.1/src/lib.rs" - extern = [ - ":matches", - ":idna", - ":percent_encoding", - ] -} - -rust_crate("percent_encoding") { - source_root = "$registry_github/percent-encoding-1.0.1/lib.rs" - args = [ - # TODO: Suppress some warnings at this moment - # This should be removed when it's fixed in servo/rust-url repository - # https://github.com/servo/rust-url/issues/455 - "-Aunused-imports", - "-Adeprecated", - ] -} - -rust_crate("matches") { - source_root = "$registry_github/matches-0.1.7/lib.rs" -} - -rust_crate("idna") { - source_root = "$registry_github/idna-0.1.5/src/lib.rs" - extern = [ - ":matches", - ":unicode_bidi", - ":unicode_normalization", - ] -} - -rust_crate("unicode_bidi") { - source_root = "$registry_github/unicode-bidi-0.3.4/src/lib.rs" - extern = [ ":matches" ] -} - -rust_crate("unicode_normalization") { - source_root = "$registry_github/unicode-normalization-0.1.7/src/lib.rs" -} - -rust_crate("log") { - source_root = "$registry_github/log-0.4.3/src/lib.rs" - extern = [ ":cfg_if" ] -} - -rust_crate("cfg_if") { - source_root = "$registry_github/cfg-if-0.1.4/src/lib.rs" -} - -rust_crate("tempfile") { - source_root = "$registry_github/tempfile-3.0.2/src/lib.rs" - extern = [ - ":libc", - ":rand", - ":remove_dir_all", - ":winapi", - ] -} - -rust_crate("rand") { - source_root = "$registry_github/rand-0.4.2/src/lib.rs" - features = [ - "std", - "alloc", - ] - extern = [ - ":libc", - ":winapi", - ] - if (is_mac) { - libs = [ "Security.framework" ] - } -} - -rust_crate("remove_dir_all") { - source_root = "$registry_github/remove_dir_all-0.5.1/src/lib.rs" - extern = [ ":winapi" ] -} - -rust_crate("winapi") { - source_root = "$registry_github/winapi-0.3.5/src/lib.rs" - features = [ - "basetsd", - "cfg", - "cfgmgr32", - "errhandlingapi", - "excpt", - "fileapi", - "guiddef", - "handleapi", - "inaddr", - "in6addr", - "ktmtypes", - "libloaderapi", - "lsalookup", - "minwinbase", - "minwindef", - "mstcpip", - "ntdef", - "ntsecapi", - "ntstatus", - "processthreadsapi", - "profileapi", - "qos", - "rpcndr", - "sspi", - "std", - "subauth", - "sysinfoapi", - "timezoneapi", - "vadefs", - "vcruntime", - "winbase", - "wincred", - "windef", - "winerror", - "winnt", - "winreg", - "winsock2", - "ws2def", - "ws2ipdef", - "ws2tcpip", - "wtypes", - "wtypesbase", - ] -} - -# Old version of the 'winapi' crate, required by 'mio', 'miow', and 'iovec'. -# This exceptional! Generally we don't allow multiple versions of a crate. -# TODO: Remove this dependency. https://github.com/denoland/deno/issues/484 -rust_crate("winapi-0.2") { - crate_name = "winapi" - crate_version = "0.2" - source_root = "$registry_github/winapi-0.2.8/src/lib.rs" -} - -# TODO: Remove this crate together with crate 'winapi-0.2'. -rust_crate("kernel32") { - source_root = "$registry_github/kernel32-sys-0.2.2/src/lib.rs" - extern_version = [ - { - label = ":winapi-0.2" - crate_name = "winapi" - crate_version = "0.2" - }, - ] -} - -# TODO: Remove this crate together with crate 'winapi-0.2'. -rust_crate("ws2_32") { - source_root = "$registry_github/ws2_32-sys-0.2.1/src/lib.rs" - extern_version = [ - { - label = ":winapi-0.2" - crate_name = "winapi" - crate_version = "0.2" - }, - ] -} - -rust_crate("futures") { - source_root = "$registry_github/futures-0.1.23/src/lib.rs" - features = [ - "use_std", - "with-deprecated", - ] -} - -rust_crate("mio") { - source_root = "$registry_github/mio-0.6.15/src/lib.rs" - features = [ - "default", - "with-deprecated", - ] - extern = [ - ":iovec", - ":kernel32", - ":lazycell", - ":libc", - ":log", - ":miow", - ":net2", - ":slab", - ] - - # TODO: Upgrade to a current version of the 'winapi' crate. - # See https://github.com/denoland/deno/issues/484. - extern_version = [ - { - label = ":winapi-0.2" - crate_name = "winapi" - crate_version = "0.2" - }, - ] -} - -rust_crate("miow") { - source_root = "$registry_github/miow-0.2.1/src/lib.rs" - extern = [ - ":kernel32", - ":net2", - ":ws2_32", - ] - - # TODO: Upgrade to a current version of the 'winapi' crate. - # See https://github.com/denoland/deno/issues/484. - extern_version = [ - { - label = ":winapi-0.2" - crate_name = "winapi" - crate_version = "0.2" - }, - ] -} - -rust_crate("iovec") { - source_root = "$registry_github/iovec-0.1.2/src/lib.rs" - extern = [ ":libc" ] - - # TODO: Upgrade to a current version of the 'winapi' crate. - # See https://github.com/denoland/deno/issues/484. - extern_version = [ - { - label = ":winapi-0.2" - crate_name = "winapi" - crate_version = "0.2" - }, - ] -} - -rust_crate("lazycell") { - source_root = "$registry_github/lazycell-0.6.0/src/lib.rs" - args = [ - # TODO Remove these: - "-Aunused_unsafe", - "-Aunused_mut", - ] -} - -rust_crate("net2") { - source_root = "$registry_github/net2-0.2.33/src/lib.rs" - features = [ - "default", - "duration", - ] - extern = [ - ":cfg_if", - ":libc", - ":winapi", - ] -} - -rust_crate("slab") { - source_root = "$registry_github/slab-0.4.1/src/lib.rs" -} - -rust_crate("bytes") { - source_root = "$registry_github/bytes-0.4.9/src/lib.rs" - extern = [ - ":byteorder", - ":iovec", - ] -} - -rust_crate("byteorder") { - source_root = "$registry_github/byteorder-1.2.4/src/lib.rs" -} - -rust_crate("crossbeam_deque") { - source_root = "$registry_github/crossbeam-deque-0.3.1/src/lib.rs" - features = [ "use_std" ] - extern = [ - ":crossbeam_epoch", - ":crossbeam_utils", - ] -} - -rust_crate("crossbeam_epoch") { - source_root = "$registry_github/crossbeam-epoch-0.4.3/src/lib.rs" - features = [ - "use_std", - "lazy_static", - "default", - "crossbeam-utils", - ] - extern = [ - ":arrayvec", - ":cfg_if", - ":crossbeam_utils", - ":lazy_static", - ":memoffset", - ":scopeguard", - ] -} - -rust_crate("crossbeam_utils") { - source_root = "$registry_github/crossbeam-utils-0.3.2/src/lib.rs" - features = [ - "use_std", - "default", - ] - extern = [ ":cfg_if" ] -} - -rust_crate("arrayvec") { - source_root = "$registry_github/arrayvec-0.4.7/src/lib.rs" - extern = [ ":nodrop" ] -} - -rust_crate("nodrop") { - source_root = "$registry_github/nodrop-0.1.12/src/lib.rs" -} - -rust_crate("lazy_static") { - source_root = "$registry_github/lazy_static-1.1.0/src/lib.rs" - args = [ - "--cfg", - "lazy_static_inline_impl", - ] -} - -rust_crate("memoffset") { - source_root = "$registry_github/memoffset-0.2.1/src/lib.rs" -} - -rust_crate("scopeguard") { - source_root = "$registry_github/scopeguard-0.3.3/src/lib.rs" - features = [ "use_std" ] -} - -rust_crate("num_cpus") { - source_root = "$registry_github/num_cpus-1.8.0/src/lib.rs" - extern = [ ":libc" ] -} - -rust_crate("hyper") { - source_root = "$registry_github/hyper-0.12.8/src/lib.rs" - features = [ "runtime" ] - extern = [ - ":bytes", - ":futures", - ":futures_cpupool", - ":h2", - ":http", - ":httparse", - ":iovec", - ":itoa", - ":log", - ":net2", - ":time", - ":tokio", - ":tokio_executor", - ":tokio_io", - ":tokio_reactor", - ":tokio_tcp", - ":tokio_timer", - ":want", - ] - args = [ - # TODO Remove these. - "-Adeprecated", - "-Aunused_imports", - ] -} - -rust_crate("tokio_core") { - source_root = "$registry_github/tokio-core-0.1.17/src/lib.rs" - extern = [ - ":mio", - ":futures", - ":tokio", - ":tokio_executor", - ":tokio_reactor", - ":tokio_timer", - ":tokio_io", - ":log", - ":iovec", - ":bytes", - ":scoped_tls", - ] -} - -rust_crate("h2") { - source_root = "$registry_github/h2-0.1.12/src/lib.rs" - extern = [ - ":byteorder", - ":bytes", - ":fnv", - ":futures", - ":http", - ":indexmap", - ":log", - ":slab", - ":string", - ":tokio_io", - ] -} - -rust_crate("http") { - source_root = "$registry_github/http-0.1.10/src/lib.rs" - extern = [ - ":bytes", - ":fnv", - ":itoa", - ] -} - -rust_crate("httparse") { - source_root = "$registry_github/httparse-1.3.2/src/lib.rs" -} - -rust_crate("fnv") { - source_root = "$registry_github/fnv-1.0.6/lib.rs" -} - -rust_crate("futures_cpupool") { - source_root = "$registry_github/futures-cpupool-0.1.8/src/lib.rs" - extern = [ - ":futures", - ":num_cpus", - ] -} - -rust_crate("indexmap") { - source_root = "$registry_github/indexmap-1.0.1/src/lib.rs" -} - -rust_crate("itoa") { - source_root = "$registry_github/itoa-0.4.2/src/lib.rs" - features = [ "std" ] -} - -rust_crate("string") { - source_root = "$registry_github/string-0.1.1/src/lib.rs" -} - -rust_crate("time") { - source_root = "$registry_github/time-0.1.40/src/lib.rs" - extern = [ - ":libc", - ":winapi", - ] -} - -rust_crate("try_lock") { - source_root = "$registry_github/try-lock-0.2.2/src/lib.rs" -} - -rust_crate("want") { - source_root = "$registry_github/want-0.0.6/src/lib.rs" - extern = [ - ":futures", - ":try_lock", - ":log", - ] -} - -rust_crate("tokio") { - source_root = "$registry_github/tokio-0.1.7/src/lib.rs" - extern = [ - ":futures", - ":mio", - ":tokio_executor", - ":tokio_fs", - ":tokio_io", - ":tokio_reactor", - ":tokio_tcp", - ":tokio_threadpool", - ":tokio_timer", - ":tokio_udp", - ] -} - -rust_crate("tokio_executor") { - source_root = "$registry_github/tokio-executor-0.1.3/src/lib.rs" - extern = [ ":futures" ] -} - -rust_crate("tokio_fs") { - source_root = "$registry_github/tokio-fs-0.1.3/src/lib.rs" - extern = [ - ":futures", - ":tokio_io", - ":tokio_threadpool", - ] -} - -rust_crate("tokio_io") { - source_root = "$registry_github/tokio-io-0.1.7/src/lib.rs" - extern = [ - ":bytes", - ":futures", - ":log", - ] -} - -rust_crate("tokio_timer") { - source_root = "$registry_github/tokio-timer-0.2.5/src/lib.rs" - extern = [ - ":futures", - ":tokio_executor", - ] -} - -rust_crate("tokio_udp") { - source_root = "$registry_github/tokio-udp-0.1.1/src/lib.rs" - extern = [ - ":bytes", - ":futures", - ":log", - ":mio", - ":tokio_codec", - ":tokio_io", - ":tokio_reactor", - ] -} - -rust_crate("tokio_codec") { - source_root = "$registry_github/tokio-codec-0.1.0/src/lib.rs" - extern = [ - ":bytes", - ":futures", - ":tokio_io", - ] -} - -rust_crate("tokio_reactor") { - source_root = "$registry_github/tokio-reactor-0.1.3/src/lib.rs" - extern = [ - ":futures", - ":log", - ":mio", - ":slab", - ":tokio_executor", - ":tokio_io", - ] -} - -rust_crate("tokio_tcp") { - source_root = "$registry_github/tokio-tcp-0.1.1/src/lib.rs" - extern = [ - ":bytes", - ":futures", - ":iovec", - ":mio", - ":tokio_io", - ":tokio_reactor", - ] -} - -rust_crate("tokio_threadpool") { - source_root = "$registry_github/tokio-threadpool-0.1.5/src/lib.rs" - extern = [ - ":crossbeam_deque", - ":crossbeam_utils", - ":futures", - ":log", - ":num_cpus", - ":rand", - ":tokio_executor", - ] -} - -rust_crate("hyper_rustls") { - source_root = "$registry_github/hyper-rustls-0.14.0/src/lib.rs" - extern = [ - ":ct_logs", - ":futures", - ":http", - ":hyper", - ":rustls", - ":tokio_core", - ":tokio_io", - ":tokio_rustls", - ":tokio_tcp", - ":webpki", - ":webpki_roots", - ] -} - -ring_root = "$registry_github/ring-0.13.2/" - -component("ring_primitives") { - sources = [ - "$ring_root/crypto/constant_time_test.c", - "$ring_root/crypto/cpu-aarch64-linux.c", - "$ring_root/crypto/cpu-arm-linux.c", - "$ring_root/crypto/cpu-arm.c", - "$ring_root/crypto/cpu-intel.c", - "$ring_root/crypto/crypto.c", - "$ring_root/crypto/fipsmodule/aes/aes.c", - "$ring_root/crypto/fipsmodule/aes/internal.h", - "$ring_root/crypto/fipsmodule/bn/exponentiation.c", - "$ring_root/crypto/fipsmodule/bn/generic.c", - "$ring_root/crypto/fipsmodule/bn/internal.h", - "$ring_root/crypto/fipsmodule/bn/montgomery.c", - "$ring_root/crypto/fipsmodule/bn/montgomery_inv.c", - "$ring_root/crypto/fipsmodule/bn/shift.c", - "$ring_root/crypto/fipsmodule/cipher/e_aes.c", - "$ring_root/crypto/fipsmodule/cipher/internal.h", - "$ring_root/crypto/fipsmodule/ec", - "$ring_root/crypto/fipsmodule/ec/ecp_nistz.c", - "$ring_root/crypto/fipsmodule/ec/ecp_nistz.h", - "$ring_root/crypto/fipsmodule/ec/ecp_nistz256.c", - "$ring_root/crypto/fipsmodule/ec/ecp_nistz256.h", - "$ring_root/crypto/fipsmodule/ec/ecp_nistz384.h", - "$ring_root/crypto/fipsmodule/ec/gfp_p256.c", - "$ring_root/crypto/fipsmodule/ec/gfp_p384.c", - "$ring_root/crypto/fipsmodule/modes/gcm.c", - "$ring_root/crypto/fipsmodule/modes/internal.h", - "$ring_root/crypto/internal.h", - "$ring_root/crypto/limbs/limbs.c", - "$ring_root/crypto/limbs/limbs.h", - "$ring_root/crypto/mem.c", - "$ring_root/include/GFp/aes.h", - "$ring_root/include/GFp/arm_arch.h", - "$ring_root/include/GFp/base.h", - "$ring_root/include/GFp/cpu.h", - "$ring_root/include/GFp/mem.h", - "$ring_root/include/GFp/type_check.h", - "$ring_root/third_party/fiat/curve25519.c", - "$ring_root/third_party/fiat/curve25519_tables.h", - "$ring_root/third_party/fiat/internal.h", - - #"$ring_root/crypto/fipsmodule/modes/polyval.c", - ] - if (is_mac) { - sources += [ - "$ring_root/pregenerated/aes-586-macosx.S", - "$ring_root/pregenerated/aes-x86_64-macosx.S", - "$ring_root/pregenerated/aesni-gcm-x86_64-macosx.S", - "$ring_root/pregenerated/aesni-x86-macosx.S", - "$ring_root/pregenerated/aesni-x86_64-macosx.S", - "$ring_root/pregenerated/chacha-x86-macosx.S", - "$ring_root/pregenerated/chacha-x86_64-macosx.S", - "$ring_root/pregenerated/ecp_nistz256-x86-macosx.S", - "$ring_root/pregenerated/ghash-x86-macosx.S", - "$ring_root/pregenerated/ghash-x86_64-macosx.S", - "$ring_root/pregenerated/p256-x86_64-asm-macosx.S", - "$ring_root/pregenerated/poly1305-x86-macosx.S", - "$ring_root/pregenerated/poly1305-x86_64-macosx.S", - "$ring_root/pregenerated/sha256-586-macosx.S", - "$ring_root/pregenerated/sha256-x86_64-macosx.S", - "$ring_root/pregenerated/sha512-586-macosx.S", - "$ring_root/pregenerated/sha512-x86_64-macosx.S", - "$ring_root/pregenerated/vpaes-x86-macosx.S", - "$ring_root/pregenerated/vpaes-x86_64-macosx.S", - "$ring_root/pregenerated/x86-mont-macosx.S", - "$ring_root/pregenerated/x86_64-mont-macosx.S", - "$ring_root/pregenerated/x86_64-mont5-macosx.S", - ] - } - if (is_linux) { - sources += [ - "$ring_root/pregenerated/aes-x86_64-elf.S", - "$ring_root/pregenerated/aesni-gcm-x86_64-elf.S", - "$ring_root/pregenerated/aesni-x86_64-elf.S", - "$ring_root/pregenerated/aesv8-armx-linux64.S", - "$ring_root/pregenerated/chacha-x86_64-elf.S", - "$ring_root/pregenerated/ghash-x86_64-elf.S", - "$ring_root/pregenerated/ghashv8-armx-linux64.S", - "$ring_root/pregenerated/p256-x86_64-asm-elf.S", - "$ring_root/pregenerated/poly1305-x86_64-elf.S", - "$ring_root/pregenerated/sha256-x86_64-elf.S", - "$ring_root/pregenerated/sha512-x86_64-elf.S", - "$ring_root/pregenerated/vpaes-x86_64-elf.S", - "$ring_root/pregenerated/x86_64-mont-elf.S", - "$ring_root/pregenerated/x86_64-mont5-elf.S", - ] - } - if (is_win) { - libs = [ - "$ring_root/pregenerated/aes-x86_64-nasm.obj", - "$ring_root/pregenerated/aesni-gcm-x86_64-nasm.obj", - "$ring_root/pregenerated/aesni-x86_64-nasm.obj", - "$ring_root/pregenerated/chacha-x86_64-nasm.obj", - "$ring_root/pregenerated/ghash-x86_64-nasm.obj", - "$ring_root/pregenerated/p256-x86_64-asm-nasm.obj", - "$ring_root/pregenerated/poly1305-x86_64-nasm.obj", - "$ring_root/pregenerated/sha256-x86_64-nasm.obj", - "$ring_root/pregenerated/sha512-x86_64-nasm.obj", - "$ring_root/pregenerated/vpaes-x86_64-nasm.obj", - "$ring_root/pregenerated/x86_64-mont-nasm.obj", - "$ring_root/pregenerated/x86_64-mont5-nasm.obj", - ] - } - include_dirs = [ "$ring_root/include/" ] -} - -rust_crate("ring") { - source_root = "$ring_root/src/lib.rs" - features = [ - "use_heap", - "rsa_signing", - ] - extern = [ - ":libc", - ":untrusted", - ":lazy_static", - ] - deps = [ - ":ring_primitives", - ] -} - -rust_crate("rustls") { - source_root = "$registry_github/rustls-0.13.1/src/lib.rs" - extern = [ - ":untrusted", - ":base64", - ":log", - ":ring", - ":webpki", - ":sct", - ] - args = [ "-Aunused_variables" ] # TODO Remove. -} - -rust_crate("ct_logs") { - source_root = "$registry_github/ct-logs-0.4.0/src/lib.rs" - extern = [ ":sct" ] -} - -rust_crate("tokio_rustls") { - source_root = "$registry_github/tokio-rustls-0.7.2/src/lib.rs" - extern = [ - ":rustls", - ":webpki", - ":tokio", - ] - features = [ - "default", - "tokio", - "tokio-support", - ] - args = [ "-Adead_code" ] # TODO Remove. -} - -rust_crate("untrusted") { - source_root = "$registry_github/untrusted-0.6.2/src/untrusted.rs" - extern = [] -} - -rust_crate("webpki") { - source_root = "$registry_github/webpki-0.18.1/src/webpki.rs" - features = [ - "std", - "trust_anchor_util", - ] - extern = [ - ":ring", - ":untrusted", - ] -} - -rust_crate("webpki_roots") { - source_root = "$registry_github/webpki-roots-0.15.0/src/lib.rs" - extern = [ - ":webpki", - ":untrusted", - ] -} - -rust_crate("sct") { - source_root = "$registry_github/sct-0.4.0/src/lib.rs" - extern = [ - ":ring", - ":untrusted", - ] -} - -rust_crate("base64") { - source_root = "$registry_github/base64-0.9.2/src/lib.rs" - extern = [ - ":byteorder", - ":safemem", - ] -} - -rust_crate("safemem") { - source_root = "$registry_github/safemem-0.2.0/src/lib.rs" -} - -rust_crate("scoped_tls") { - source_root = "$registry_github/scoped-tls-0.1.2/src/lib.rs" - extern = [ - ":ring", - ":untrusted", - ] -} diff --git a/build_extra/rust/dummy.rs b/build_extra/rust/dummy.rs deleted file mode 100644 index f328e4d9d04c31..00000000000000 --- a/build_extra/rust/dummy.rs +++ /dev/null @@ -1 +0,0 @@ -fn main() {} diff --git a/build_extra/rust/get_rust_ldflags.cmd b/build_extra/rust/get_rust_ldflags.cmd deleted file mode 100644 index 9d5ce12a16b2a5..00000000000000 --- a/build_extra/rust/get_rust_ldflags.cmd +++ /dev/null @@ -1 +0,0 @@ -@"%PYTHON_EXE%" "%~dpn0.py" %* diff --git a/build_extra/rust/get_rust_ldflags.py b/build_extra/rust/get_rust_ldflags.py deleted file mode 100755 index 79c7bc3fb60d38..00000000000000 --- a/build_extra/rust/get_rust_ldflags.py +++ /dev/null @@ -1,180 +0,0 @@ -#!/usr/bin/env python -# Copyright 2018 the Deno authors. All rights reserved. MIT license. -# -# The Rust compiler normally builds source code directly into an executable. -# Internally, object code is produced, and then the (system) linker is called, -# but this all happens under the covers. -# -# However Deno's build system uses it's own linker. For it to successfully -# produce an executable from rustc-generated object code, it needs to link -# with a dozen or so "built-in" Rust libraries (as in: not Cargo crates), -# and we need to tell the linker which and where those .rlibs are. -# -# Hard-coding these libraries into the GN configuration isn't possible: the -# required .rlib files have some sort of hash code in their file name, and their -# location depends on how Rust is set up, and which toolchain is active. -# -# So instead, we have this script: it writes a list of linker options (ldflags) -# to stdout, separated by newline characters. It is called from `rust.gni` when -# GN is generating ninja files (it doesn't run in the build phase). -# -# There is no official way through which rustc will give us the information -# we need, so a "back door" is used. We tell `rustc` to compile a (dummy) -# program, and to use a custom linker. This "linker" doesn't actually link -# anything; it just dumps it's argv to a temporary file. When rustc is done, -# this script then reads the linker arguments from that temporary file, and -# then filters it to remove flags that are irrelevant or undesirable. - -import sys -import os -from os import path -import re -import subprocess -import tempfile - - -def capture_args(argsfile_path): - with open(argsfile_path, "wb") as argsfile: - argsfile.write("\n".join(sys.argv[1:])) - - -def main(): - # If ARGSFILE_PATH is set this script is being invoked by rustc, which - # thinks we are a linker. All we do now is write our argv to the specified - # file and exit. Further processing is done by our grandparent process, - # also this script but invoked by gn. - argsfile_path = os.getenv("ARGSFILE_PATH") - if argsfile_path is not None: - return capture_args(argsfile_path) - - # Prepare the environment for rustc. - rustc_env = os.environ.copy() - - # We'll capture the arguments rustc passes to the linker by telling it - # that this script *is* the linker. - # On Posix systems, this file is directly executable thanks to it's shebang. - # On Windows, we use a .cmd wrapper file. - if os.name == "nt": - rustc_linker_base, rustc_linker_ext = path.splitext(__file__) - rustc_linker = rustc_linker_base + ".cmd" - else: - rustc_linker = __file__ - - # Make sure that when rustc invokes this script, it uses the same version - # of the Python interpreter as we're currently using. On Posix systems this - # is done making the Python directory the first element of PATH. - # On Windows, the wrapper script uses the PYTHON_EXE environment variable. - if os.name == "nt": - rustc_env["PYTHON_EXE"] = sys.executable - else: - python_dir = path.dirname(sys.executable) - rustc_env["PATH"] = python_dir + path.pathsep + os.environ["PATH"] - - # Create a temporary file to write captured Rust linker arguments to. - # Unfortunately we can't use tempfile.NamedTemporaryFile here, because the - # file it creates can't be open in two processes at the same time. - argsfile_fd, argsfile_path = tempfile.mkstemp() - rustc_env["ARGSFILE_PATH"] = argsfile_path - - try: - # Build the rustc command line. - # * `-Clinker=` tells rustc to use our fake linker. - # * `-Csave-temps` prevents rustc from deleting object files after - # linking. We need to preserve the file `xx.crate.allocator.rcgu.o`. - rustc_cmd = [ - "rustc", - "-Clinker=" + rustc_linker, - "-Csave-temps", - ] + sys.argv[1:] - - # Spawn the rust compiler. - rustc_proc = subprocess.Popen( - rustc_cmd, - env=rustc_env, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT) - - # Forward rustc's output to stderr. - for line in rustc_proc.stdout: - # Suppress the warning: - # `-C save-temps` might not produce all requested temporary - # products when incremental compilation is enabled. - # It's pointless, because incremental compilation is disabled. - if re.match(r"^warning:.*save-temps.*incremental compilation", - line): - continue - # Also, do not write completely blank lines to stderr. - if line.strip() == "": - continue - sys.stderr.write(line) - - # The rustc process should return zero. If not, raise an exception. - rustc_retcode = rustc_proc.wait() - if rustc_retcode != 0: - raise subprocess.CalledProcessError(rustc_retcode, rustc_cmd) - - # Read captured linker arguments from argsfile. - argsfile_size = os.fstat(argsfile_fd).st_size - argsfile_content = os.read(argsfile_fd, argsfile_size) - args = argsfile_content.split("\n") - - except OSError as e: # Note: in python 3 this will be a FileNotFoundError. - print "Error executing rustc command (is rust installed?):" - print " ".join(rustc_cmd) + "\n" - raise e - - finally: - # Close and delete the temporary file. - os.close(argsfile_fd) - os.unlink(argsfile_path) - - # From the list of captured linker arguments, build the list of ldflags that - # we actually need. - ldflags = [] - next_arg_is_flag_value = False - for arg in args: - # Note that within the following if/elif blocks, `pass` means that - # that captured arguments gets included in `ldflags`. The final `else` - # clause filters out unrecognized/unwanted flags. - if next_arg_is_flag_value: - # We're looking at a value that follows certain parametric flags, - # e.g. the path in '-L '. - next_arg_is_flag_value = False - elif arg.endswith(".rlib"): - # Built-in Rust library, e.g. `libstd-8524caae8408aac2.rlib`. - pass - elif arg.endswith(".crate.allocator.rcgu.o"): - # This file is needed because it contains certain allocator - # related symbols (e.g. `__rust_alloc`, `__rust_oom`). - # The Rust compiler normally generates this file just before - # linking an executable. We pass `-Csave-temps` to rustc so it - # doesn't delete the file when it's done linking. - pass - elif arg.endswith(".lib") and not arg.startswith("msvcrt"): - # Include most Windows static/import libraries (e.g. `ws2_32.lib`). - # However we ignore Rusts choice of C runtime (`mvcrt*.lib`). - # Rust insists on always using the release "flavor", even in debug - # mode, which causes conflicts with other libraries we link with. - pass - elif arg.upper().startswith("/LIBPATH:"): - # `/LIBPATH:`: Linker search path (Microsoft style). - pass - elif arg == "-l" or arg == "-L": - # `-l `: Link with library (GCC style). - # `-L `: Linker search path (GCC style). - next_arg_is_flag_value = True # Ensure flag argument is captured. - elif arg == "-Wl,--start-group" or arg == "-Wl,--end-group": - # Start or end of an archive group (GCC style). - pass - else: - # Not a flag we're interested in -- don't add it to ldflags. - continue - - ldflags += [arg] - - # Write the filtered ldflags to stdout, separated by newline characters. - sys.stdout.write("\n".join(ldflags)) - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/build_extra/rust/rust.gni b/build_extra/rust/rust.gni deleted file mode 100644 index 1600602e0851a5..00000000000000 --- a/build_extra/rust/rust.gni +++ /dev/null @@ -1,330 +0,0 @@ -declare_args() { - # Absolute path of rust build files. - rust_build = "//build_extra/rust/" - - # treat the warnings in rust files as errors - rust_treat_warnings_as_errors = true -} - -if (is_win) { - executable_suffix = ".exe" -} else { - executable_suffix = "" -} - -# To simplify transitive dependency management with gn, we build all rust -# crates into the same directory. We need to be careful not to have crates -# with the same name. -out_dir = "$root_out_dir/rust_crates" - -# The official way of building Rust executables is to to let rustc do the -# linking. However, we'd prefer to leave it in the hands of gn/ninja: -# * It allows us to use source sets. -# * It allows us to use the bundled lld that Chromium and V8 use. -# * We have more control over build flags. -# * To sidestep rustc weirdness (e.g. on Windows, it always links with the -# release C runtime library, even for debug builds). -# -# The `get_rust_ldflags` tool outputs the linker flags that are needed to -# successfully link rustc object code into an executable. -# We generate two sets of ldflags: -# `rust_bin_ldflags`: Used for rust_executable targets. -# `rust_test_ldflags`: Used for rust_test targets; includes the test harness. -# -# The tool works by compiling and linking something with rustc, and analyzing -# the arguments it passes to the system linker. That's what dummy.rs is for. -dummy_rs_path = rebase_path("dummy.rs", root_build_dir) -rust_bin_ldflags = - exec_script("get_rust_ldflags.py", [ dummy_rs_path ], "list lines") -rust_test_ldflags = exec_script("get_rust_ldflags.py", - [ - dummy_rs_path, - "--test", - ], - "list lines") - -template("run_rustc") { - action(target_name) { - assert(defined(invoker.source_root), "Must specify source_root") - forward_variables_from(invoker, - [ - "crate_name", - "crate_type", - "crate_version", - "deps", - "extern_infos", - "features", - "is_test", - "source_root", - "testonly", - ]) - if (!defined(crate_name)) { - crate_name = target_name - } - if (!defined(is_test)) { - is_test = false - } - - sources = [ - source_root, - ] - script = "//tools/run_rustc.py" - - args = [ - rebase_path(source_root, root_build_dir), - "--crate-name=$crate_name", - "--crate-type=$crate_type", - ] - - if (rust_treat_warnings_as_errors) { - args += [ "-Dwarnings" ] - } - - if (!is_win) { - args += [ "--color=always" ] - } - - if (!defined(crate_version)) { - crate_name_and_version = crate_name - } else { - crate_name_and_version = "$crate_name-$crate_version" - } - - if (crate_type == "bin") { - output_file = "$out_dir/$crate_name_and_version.o" - emit_type = "obj" - } else if (crate_type == "rlib") { - output_file = "$out_dir/lib$crate_name_and_version.rlib" - emit_type = "link" - } - outputs = [ - output_file, - ] - output_file_rel = rebase_path(output_file, root_build_dir) - args += [ "--emit=$emit_type=$output_file_rel" ] - - depfile = "$out_dir/$crate_name_and_version.d" - args += [ - "--emit=dep-info=" + rebase_path(depfile, root_build_dir), - - # The following two args are used by run_rustc.py to fix - # the depfile on the fly. They are not passed thru to rustc. - "--depfile=" + rebase_path(depfile, root_build_dir), - "--output_file=" + output_file_rel, - - # This is needed for transitive dependencies. - "-L", - "dependency=" + rebase_path(out_dir, root_build_dir), - ] - - if (defined(crate_version)) { - # Compute the sha256sum of the version number. See comments below. - # Note that we do this only if there are multiple versions of this crate. - hash = exec_script("//tools/sha256sum.py", - [ - "--input", - crate_version, - "--format", - "%.8s", - ], - "trim string") - - args += [ - # In our build setup, all crates are built in the same directory. The - # actual build outputs have unique names (e.g. 'foo-1.2.3.rlib'), but - # rustc also creates many temp files (e.g. 'foo.crate.metadata.rcgu.bc', - # 'foo.foo0.rcgu.o'), and with those files, name collisions do occur. - # This causes random failures during parallel builds and on CI. - # - # These name conflicts can be avoided by setting `-C extra-filename=` to - # some unique value. Unfortunately the version number as such can't be - # used: everything after the first dot (.) is thrown away, so winapi-0.2 - # vs. winapi-0.3 would still have conflicts -- so we use a hash instead. - "-C", - "extra-filename=$hash", - - # Rustc blows up if a target (directly or indirectly) depends on two+ - # crates that have the same name *and* the same metadata. So we use the - # hash to give 'metadata' a unique value too (any unique value will do). - "-C", - "metadata=$hash", - ] - } - - if (is_debug) { - args += [ "-g" ] - } - - if (is_official_build) { - args += [ "-O" ] - } - - if (is_test) { - args += [ "--test" ] - } - - if (defined(features)) { - foreach(f, features) { - args += [ - "--cfg", - "feature=\"" + f + "\"", - ] - } - } - - if (defined(invoker.args)) { - args += invoker.args - } - - if (!defined(deps)) { - deps = [] - } - - # Build the list of '--extern' arguments from the 'extern_infos' array. - foreach(info, extern_infos) { - rlib = "$out_dir/lib${info.crate_name_and_version}.rlib" - args += [ - "--extern", - info.crate_name + "=" + rebase_path(rlib, root_build_dir), - ] - deps += [ info.label ] - } - } -} - -template("rust_crate") { - rustc_name = target_name + "_rustc" - rustc_label = ":" + rustc_name - config_name = target_name + "_config" - - # Convert all 'extern' and 'extern_version' items to a single format. - extern_infos = [] - if (defined(invoker.extern)) { - foreach(label, invoker.extern) { - extern_infos += [ - { - label = label - crate_name = get_label_info(label, "name") - crate_name_and_version = crate_name - }, - ] - } - } - if (defined(invoker.extern_version)) { - foreach(info, invoker.extern_version) { - extern_infos += [ - { - forward_variables_from(info, - [ - "label", - "crate_name", - "crate_version", - ]) - crate_name_and_version = "$crate_name-$crate_version" - }, - ] - } - } - - forward_variables_from(invoker, - [ - "crate_name", - "crate_type", - ]) - if (!defined(crate_name)) { - crate_name = target_name - } - if (!defined(crate_type)) { - crate_type = "rlib" - } - - run_rustc(rustc_name) { - forward_variables_from(invoker, - [ - "args", - "crate_version", - "deps", - "features", - "is_test", - "source_root", - "testonly", - ]) - } - - crate_outputs = get_target_outputs(rustc_label) - crate_obj = crate_outputs[0] - - config(config_name) { - lib_dirs = [] - forward_variables_from(invoker, [ "libs" ]) - if (!defined(libs)) { - libs = [] - } - foreach(info, extern_infos) { - rlib = "$out_dir/lib${info.crate_name_and_version}.rlib" - libs += [ rlib ] - } - lib_dirs = [ out_dir ] - } - - source_set(target_name) { - forward_variables_from(invoker, - [ - "deps", - "libs", - "testonly", - ]) - if (!defined(deps)) { - deps = [] - } - if (!defined(libs)) { - libs = [] - } - libs += [ crate_obj ] - deps += [ rustc_label ] - all_dependent_configs = [ ":" + config_name ] - } -} - -template("rust_executable") { - bin_name = target_name + "_bin" - bin_label = ":" + bin_name - - rust_crate(bin_name) { - crate_type = "bin" - forward_variables_from(invoker, "*") - } - - executable(target_name) { - forward_variables_from(invoker, "*") - - if (defined(is_test) && is_test) { - ldflags = rust_test_ldflags - } else { - ldflags = rust_bin_ldflags - } - - if (!defined(deps)) { - deps = [] - } - - deps += [ bin_label ] - - if (defined(extern)) { - deps += extern - } - if (defined(extern_version)) { - foreach(info, extern_version) { - deps += [ info.label ] - } - } - } -} - -template("rust_test") { - rust_executable(target_name) { - forward_variables_from(invoker, "*") - is_test = true - testonly = true - } -} diff --git a/build_extra/toolchain/validate.gni b/build_extra/toolchain/validate.gni deleted file mode 100644 index 79c013e8dfe5da..00000000000000 --- a/build_extra/toolchain/validate.gni +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright 2018 the Deno authors. All rights reserved. MIT license. - -import("//build/toolchain/cc_wrapper.gni") - -# Verify that cc_wrapper is correctly set up on Windows. -if (is_win && cc_wrapper != "" && custom_toolchain == "") { - suggested_toolchain = "//build_extra/toolchain/win:win_clang_$target_cpu" - - # Use print instead of assert with message for readability. - print( - "The 'cc_wrapper' option isn't supported by the default Windows toolchain.") - print("To make it work, add the option:") - print(" custom_toolchain=\"$suggested_toolchain\"") - assert(custom_toolchain != "") -} diff --git a/build_extra/toolchain/win/BUILD.gn b/build_extra/toolchain/win/BUILD.gn deleted file mode 100644 index a225f4c6562a29..00000000000000 --- a/build_extra/toolchain/win/BUILD.gn +++ /dev/null @@ -1,494 +0,0 @@ -# Automatically generated. See mods.gni. - -# Copyright (c) 2013 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("mods.gni") -import("//build/config/clang/clang.gni") -import("//build/config/compiler/compiler.gni") -import("//build/config/sanitizers/sanitizers.gni") -import("//build/config/win/visual_studio_version.gni") -import("//build/toolchain/clang_static_analyzer.gni") -import("//build/toolchain/goma.gni") -import("//build/toolchain/toolchain.gni") - -# Should only be running on Windows. -assert(is_win) - -# Setup the Visual Studio state. -# -# Its arguments are the VS path and the compiler wrapper tool. It will write -# "environment.x86" and "environment.x64" to the build directory and return a -# list to us. - -# This tool will is used as a wrapper for various commands below. -tool_wrapper_path = rebase_path("tool_wrapper.py", root_build_dir) - -if (use_goma) { - if (host_os == "win") { - goma_prefix = "$goma_dir/gomacc.exe " - } else { - goma_prefix = "$goma_dir/gomacc " - } -} else { - goma_prefix = "" -} - -# Copy the VS runtime DLL for the default toolchain to the root build directory -# so things will run. -if (current_toolchain == default_toolchain) { - if (is_debug) { - configuration_name = "Debug" - } else { - configuration_name = "Release" - } - exec_script("$base_toolchain_dir/../../vs_toolchain.py", - [ - "copy_dlls", - rebase_path(root_build_dir), - configuration_name, - target_cpu, - ]) -} - -# Parameters: -# environment: File name of environment file. -# -# You would also define a toolchain_args variable with at least these set: -# current_cpu: current_cpu to pass as a build arg -# current_os: current_os to pass as a build arg -template("msvc_toolchain") { - toolchain(target_name) { - # When invoking this toolchain not as the default one, these args will be - # passed to the build. They are ignored when this is the default toolchain. - assert(defined(invoker.toolchain_args)) - toolchain_args = { - if (defined(invoker.toolchain_args)) { - forward_variables_from(invoker.toolchain_args, "*") - } - - # This value needs to be passed through unchanged. - host_toolchain = host_toolchain - } - - # Make these apply to all tools below. - lib_switch = "" - lib_dir_switch = "/LIBPATH:" - - # Object files go in this directory. - object_subdir = "{{target_out_dir}}/{{label_name}}" - - env = invoker.environment - - # When the invoker has explicitly overridden use_goma or cc_wrapper in the - # toolchain args, use those values, otherwise default to the global one. - # This works because the only reasonable override that toolchains might - # supply for these values are to force-disable them. - if (defined(toolchain_args.is_clang)) { - toolchain_uses_clang = toolchain_args.is_clang - } else { - toolchain_uses_clang = is_clang - } - - cl = invoker.cl - - if (toolchain_uses_clang && use_clang_static_analyzer) { - analyzer_prefix = - "$python_path " + - rebase_path("//build/toolchain/clang_static_analyzer_wrapper.py", - root_build_dir) + " --mode=cl" - cl = "${analyzer_prefix} ${cl}" - } - - if (use_lld) { - if (host_os == "win") { - lld_link = "lld-link.exe" - } else { - lld_link = "lld-link" - } - prefix = rebase_path("$clang_base_path/bin", root_build_dir) - - # lld-link includes a replacement for lib.exe that can produce thin - # archives and understands bitcode (for lto builds). - lib = "$prefix/$lld_link /lib /llvmlibthin" - link = "$prefix/$lld_link" - if (host_os != "win") { - # See comment adding --rsp-quoting to $cl above for more information. - link = "$link --rsp-quoting=posix" - } - } else { - lib = "lib.exe" - link = "link.exe" - } - - # If possible, pass system includes as flags to the compiler. When that's - # not possible, load a full environment file (containing %INCLUDE% and - # %PATH%) -- e.g. 32-bit MSVS builds require %PATH% to be set and just - # passing in a list of include directories isn't enough. - if (defined(invoker.sys_include_flags)) { - env_wrapper = "" - sys_include_flags = "${invoker.sys_include_flags} " # Note trailing space. - } else { - # clang-cl doesn't need this env hoop, so omit it there. - assert(!toolchain_uses_clang) - env_wrapper = "ninja -t msvc -e $env -- " # Note trailing space. - sys_include_flags = "" - } - - # ninja does not have -t msvc other than windows, and lld doesn't depend on - # mt.exe in PATH on non-Windows, so it's not needed there anyways. - if (defined(invoker.sys_lib_flags)) { - linker_wrapper = "" - sys_lib_flags = "${invoker.sys_lib_flags} " # Note trailing space - } else if (use_lld) { - # Invoke ninja as wrapper instead of tool wrapper, because python - # invocation requires higher cpu usage compared to ninja invocation, and - # the python wrapper is only needed to work around link.exe problems. - # TODO(thakis): Remove wrapper once lld-link can merge manifests without - # relying on mt.exe being in %PATH% on Windows, https://crbug.com/872740 - linker_wrapper = "ninja -t msvc -e $env -- " # Note trailing space. - sys_lib_flags = "" - } else { - linker_wrapper = - "$python_path $tool_wrapper_path link-wrapper $env False " # Note trailing space. - sys_lib_flags = "" - } - - clflags = "" - - # Pass /FC flag to the compiler if needed. - if (msvc_use_absolute_paths) { - clflags += "/FC " - } - - tool("cc") { - precompiled_header_type = "msvc" - pdbname = "{{target_out_dir}}/{{label_name}}_c.pdb" - - # Label names may have spaces in them so the pdbname must be quoted. The - # source and output don't need to be quoted because GN knows they're a - # full file name and will quote automatically when necessary. - depsformat = "msvc" - description = "CC {{output}}" - outputs = [ - "$object_subdir/{{source_name_part}}.obj", - ] - - command = "$env_wrapper$cl /nologo /showIncludes ${clflags} $sys_include_flags{{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} /c {{source}} /Fo{{output}} /Fd\"$pdbname\"" - } - - tool("cxx") { - precompiled_header_type = "msvc" - - # The PDB name needs to be different between C and C++ compiled files. - pdbname = "{{target_out_dir}}/{{label_name}}_cc.pdb" - - # See comment in CC tool about quoting. - depsformat = "msvc" - description = "CXX {{output}}" - outputs = [ - "$object_subdir/{{source_name_part}}.obj", - ] - - command = "$env_wrapper$cl /nologo /showIncludes ${clflags} $sys_include_flags{{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} /c {{source}} /Fo{{output}} /Fd\"$pdbname\"" - } - - tool("rc") { - command = "$python_path $tool_wrapper_path rc-wrapper $env rc.exe {{defines}} {{include_dirs}} /fo{{output}} {{source}}" - depsformat = "msvc" - outputs = [ - "$object_subdir/{{source_name_part}}.res", - ] - description = "RC {{output}}" - } - - tool("asm") { - if (toolchain_args.current_cpu == "x64") { - ml = "ml64.exe" - } else { - ml = "ml.exe" - } - command = "$python_path $tool_wrapper_path asm-wrapper $env $ml {{defines}} {{include_dirs}} {{asmflags}} /c /Fo{{output}} {{source}}" - description = "ASM {{output}}" - outputs = [ - "$object_subdir/{{source_name_part}}.obj", - ] - } - - tool("alink") { - rspfile = "{{output}}.rsp" - command = "$linker_wrapper$lib /nologo ${sys_lib_flags}{{arflags}} /OUT:{{output}} @$rspfile" - description = "LIB {{output}}" - outputs = [ - # Ignore {{output_extension}} and always use .lib, there's no reason to - # allow targets to override this extension on Windows. - "{{output_dir}}/{{target_output_name}}.lib", - ] - default_output_extension = ".lib" - default_output_dir = "{{target_out_dir}}" - - # The use of inputs_newline is to work around a fixed per-line buffer - # size in the linker. - rspfile_content = "{{inputs_newline}}" - } - - tool("solink") { - dllname = "{{output_dir}}/{{target_output_name}}{{output_extension}}" # e.g. foo.dll - libname = "${dllname}.lib" # e.g. foo.dll.lib - pdbname = "${dllname}.pdb" - rspfile = "${dllname}.rsp" - pool = "//build/toolchain:link_pool($default_toolchain)" - - command = "$linker_wrapper$link /nologo ${sys_lib_flags}/IMPLIB:$libname /DLL /OUT:$dllname /PDB:$pdbname @$rspfile" - - default_output_extension = ".dll" - default_output_dir = "{{root_out_dir}}" - description = "LINK(DLL) {{output}}" - outputs = [ - dllname, - libname, - ] - link_output = libname - depend_output = libname - runtime_outputs = [ dllname ] - if (symbol_level != 0) { - outputs += [ pdbname ] - runtime_outputs += [ pdbname ] - } - - # Since the above commands only updates the .lib file when it changes, ask - # Ninja to check if the timestamp actually changed to know if downstream - # dependencies should be recompiled. - restat = true - - # The use of inputs_newline is to work around a fixed per-line buffer - # size in the linker. - rspfile_content = "{{libs}} {{solibs}} {{inputs_newline}} {{ldflags}}" - } - - tool("solink_module") { - dllname = "{{output_dir}}/{{target_output_name}}{{output_extension}}" # e.g. foo.dll - pdbname = "${dllname}.pdb" - rspfile = "${dllname}.rsp" - pool = "//build/toolchain:link_pool($default_toolchain)" - - command = "$linker_wrapper$link /nologo ${sys_lib_flags}/DLL /OUT:$dllname /PDB:$pdbname @$rspfile" - - default_output_extension = ".dll" - default_output_dir = "{{root_out_dir}}" - description = "LINK_MODULE(DLL) {{output}}" - outputs = [ - dllname, - ] - if (symbol_level != 0) { - outputs += [ pdbname ] - } - runtime_outputs = outputs - - # The use of inputs_newline is to work around a fixed per-line buffer - # size in the linker. - rspfile_content = "{{libs}} {{solibs}} {{inputs_newline}} {{ldflags}}" - } - - tool("link") { - exename = "{{output_dir}}/{{target_output_name}}{{output_extension}}" - pdbname = "$exename.pdb" - rspfile = "$exename.rsp" - pool = "//build/toolchain:link_pool($default_toolchain)" - - command = "$linker_wrapper$link /nologo ${sys_lib_flags}/OUT:$exename /PDB:$pdbname @$rspfile" - - default_output_extension = ".exe" - default_output_dir = "{{root_out_dir}}" - description = "LINK {{output}}" - outputs = [ - exename, - ] - if (symbol_level != 0) { - outputs += [ pdbname ] - } - runtime_outputs = outputs - - # The use of inputs_newline is to work around a fixed per-line buffer - # size in the linker. - rspfile_content = "{{inputs_newline}} {{libs}} {{solibs}} {{ldflags}}" - } - - # These two are really entirely generic, but have to be repeated in - # each toolchain because GN doesn't allow a template to be used here. - # See //build/toolchain/toolchain.gni for details. - tool("stamp") { - command = stamp_command - description = stamp_description - pool = "//build/toolchain:action_pool($default_toolchain)" - } - tool("copy") { - command = copy_command - description = copy_description - pool = "//build/toolchain:action_pool($default_toolchain)" - } - - tool("action") { - pool = "//build/toolchain:action_pool($default_toolchain)" - } - } -} - -if (host_os == "win") { - clang_cl = "clang-cl.exe" -} else { - clang_cl = "clang-cl" -} - -if (target_cpu == "x86" || target_cpu == "x64") { - win_build_host_cpu = target_cpu -} else { - win_build_host_cpu = host_cpu -} - -# x86, arm and arm64 build cpu toolchains for Windows (not WinUWP). Only -# define when the build cpu is one of these architectures since we don't -# do any cross compiles when targeting x64-bit (the build does generate -# some 64-bit stuff from x86/arm/arm64 target builds). -if (win_build_host_cpu != "x64") { - build_cpu_toolchain_data = - exec_script("$base_toolchain_dir/setup_toolchain.py", - [ - visual_studio_path, - windows_sdk_path, - visual_studio_runtime_dirs, - host_os, - win_build_host_cpu, - "environment." + win_build_host_cpu, - ], - "scope") - - msvc_toolchain(win_build_host_cpu) { - environment = "environment." + win_build_host_cpu - cl = "${goma_prefix}${cc_wrapper_prefix}\"${build_cpu_toolchain_data.vc_bin_dir}/cl.exe\"" - if (host_os != "win") { - # For win cross build. - sys_lib_flags = "${build_cpu_toolchain_data.libpath_flags}" - } - toolchain_args = { - current_os = "win" - current_cpu = win_build_host_cpu - is_clang = false - } - } - - msvc_toolchain("win_clang_" + win_build_host_cpu) { - environment = "environment." + win_build_host_cpu - prefix = rebase_path("$clang_base_path/bin", root_build_dir) - cl = "${goma_prefix}${cc_wrapper_prefix}$prefix/${clang_cl}" - sys_include_flags = "${build_cpu_toolchain_data.include_flags_imsvc}" - if (host_os != "win") { - # For win cross build. - sys_lib_flags = "${build_cpu_toolchain_data.libpath_flags}" - } - - toolchain_args = { - current_os = "win" - current_cpu = win_build_host_cpu - is_clang = true - } - } -} - -# 64-bit toolchains. -x64_toolchain_data = exec_script("$base_toolchain_dir/setup_toolchain.py", - [ - visual_studio_path, - windows_sdk_path, - visual_studio_runtime_dirs, - "win", - "x64", - "environment.x64", - ], - "scope") - -template("win_x64_toolchains") { - msvc_toolchain(target_name) { - environment = "environment.x64" - cl = "${goma_prefix}${cc_wrapper_prefix}\"${x64_toolchain_data.vc_bin_dir}/cl.exe\"" - if (host_os != "win") { - # For win cross build - sys_lib_flags = "${x64_toolchain_data.libpath_flags}" - } - - toolchain_args = { - if (defined(invoker.toolchain_args)) { - forward_variables_from(invoker.toolchain_args, "*") - } - is_clang = false - current_os = "win" - current_cpu = "x64" - } - } - - msvc_toolchain("win_clang_" + target_name) { - environment = "environment.x64" - prefix = rebase_path("$clang_base_path/bin", root_build_dir) - cl = "${goma_prefix}${cc_wrapper_prefix}$prefix/${clang_cl}" - sys_include_flags = "${x64_toolchain_data.include_flags_imsvc}" - if (host_os != "win") { - # For win cross build - sys_lib_flags = "${x64_toolchain_data.libpath_flags}" - } - - toolchain_args = { - if (defined(invoker.toolchain_args)) { - forward_variables_from(invoker.toolchain_args, "*") - } - is_clang = true - current_os = "win" - current_cpu = "x64" - } - } -} - -win_x64_toolchains("x64") { - toolchain_args = { - # Use the defaults. - } -} - -# The nacl_win64 toolchain is nearly identical to the plain x64 toolchain. -# It's used solely for building nacl64.exe (//components/nacl/broker:nacl64). -# The only reason it's a separate toolchain is so that it can force -# is_component_build to false in the toolchain_args() block, because -# building nacl64.exe in component style does not work. -win_x64_toolchains("nacl_win64") { - toolchain_args = { - is_component_build = false - } -} - -# WinUWP toolchains. Only define these when targeting them. - -if (target_os == "winuwp") { - assert(target_cpu == "x64" || target_cpu == "x86" || target_cpu == "arm" || - target_cpu == "arm64") - store_cpu_toolchain_data = - exec_script("$base_toolchain_dir/setup_toolchain.py", - [ - visual_studio_path, - windows_sdk_path, - visual_studio_runtime_dirs, - target_os, - target_cpu, - "environment.store_" + target_cpu, - ], - "scope") - - msvc_toolchain("uwp_" + target_cpu) { - environment = "environment.store_" + target_cpu - cl = "${goma_prefix}${cc_wrapper_prefix}\"${store_cpu_toolchain_data.vc_bin_dir}/cl.exe\"" - toolchain_args = { - current_os = "winuwp" - current_cpu = target_cpu - is_clang = false - } - } -} diff --git a/build_extra/toolchain/win/mods.gni b/build_extra/toolchain/win/mods.gni deleted file mode 100644 index 5355d7f9aff087..00000000000000 --- a/build_extra/toolchain/win/mods.gni +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright 2018 the Deno authors. All rights reserved. MIT license. - -# The toolchain definitions in BUILD.gn are derived from Chromium's default -# Windows toolchain. The only difference is that the 'cc_wrapper' build option -# is honored, so we can use ccache or an equivalent tool. -# -# 'BUILD.gn' was generated as follows (using GNU sed): -# -# (echo -e '# Automatically generated. See mods.gni.\n' | -# cat - ../../../build/toolchain/win/BUILD.gn | -# sed '0,/import/s|import|import("mods.gni")\n&|' | -# sed 's|exec_script("|&$base_toolchain_dir/|' | -# sed 's|${goma_prefix}|&${cc_wrapper_prefix}|' ) > BUILD.gn -# gn format BUILD.gn - -# Ensure the 'cc_wrapper' variable is in scope. -import("//build/toolchain/cc_wrapper.gni") - -# Location of the original toolchain definition that this one is derived from. -# Some python scripts that are run by BUILD.gni live here. -base_toolchain_dir = "//build/toolchain/win" - -# If cc_wrapper if is set, wrap it in quotes and add a space to it. -if (cc_wrapper == "") { - cc_wrapper_prefix = "" -} else { - cc_wrapper_prefix = "\"$cc_wrapper\" " -} diff --git a/build_overrides b/build_overrides deleted file mode 120000 index 3e199c0e103e6f..00000000000000 --- a/build_overrides +++ /dev/null @@ -1 +0,0 @@ -third_party/v8/build_overrides \ No newline at end of file diff --git a/buildtools b/buildtools deleted file mode 120000 index 25713c88acefa8..00000000000000 --- a/buildtools +++ /dev/null @@ -1 +0,0 @@ -third_party/v8/buildtools \ No newline at end of file diff --git a/gclient_config.py b/gclient_config.py deleted file mode 100644 index 6b7b2976cdd73a..00000000000000 --- a/gclient_config.py +++ /dev/null @@ -1,44 +0,0 @@ -solutions = [{ - 'url': 'https://chromium.googlesource.com/v8/v8.git@7.0.247', - 'name': 'v8', - 'deps_file': 'DEPS', - 'custom_deps': { - 'v8/third_party/catapult': None, - 'v8/third_party/colorama/src': None, - 'v8/testing/gmock': None, - 'v8/tools/swarming_client': None, - 'v8/third_party/instrumented_libraries': None, - 'v8/third_party/android_tools': None, - 'v8/third_party/depot_tools': None, - 'v8/test/wasm-js': None, - 'v8/test/benchmarks/data': None, - 'v8/test/mozilla/data': None, - 'v8/third_party/icu': None, - 'v8/test/test262/data': None, - 'v8/test/test262/harness': None, - 'v8/tools/luci-go': None - } -}, { - 'url': - 'https://chromium.googlesource.com/chromium/tools/depot_tools@40bacee96a94600ad2179d69a8025469d119960f', - 'name': - 'depot_tools' -}, { - 'url': - 'https://chromium.googlesource.com/chromium/src/third_party/zlib@39b4a6260702da4c089eca57136abf40a39667e9', - 'name': - 'zlib' -}, { - 'url': - 'https://github.com/cpplint/cpplint.git@a33992f68f36fcaa6d0f531a25012a4c474d3542', - 'name': - 'cpplint' -}, { - # Tracking a bleeding-edge branch. Upgrade frequently. - # https://github.com/google/flatbuffers/pull/3894 - # https://github.com/rw/flatbuffers/tree/2018-08-12--all-tests-passing - 'url': - 'https://github.com/rw/flatbuffers.git@83a71543f8ccbf230ac27cb523831bfafb9c84d7', - 'name': - 'flatbuffers' -}] diff --git a/js/assets.ts b/js/assets.ts deleted file mode 100644 index 89b3e2645d734a..00000000000000 --- a/js/assets.ts +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. - -// tslint:disable-next-line:no-reference -/// - -// There is a rollup plugin that will inline any module ending with `!string` -// tslint:disable:max-line-length - -// Generated definitions -import compilerDts from "gen/js/compiler.d.ts!string"; -import consoleDts from "gen/js/console.d.ts!string"; -import denoDts from "gen/js/deno.d.ts!string"; -import libdenoDts from "gen/js/libdeno.d.ts!string"; -import globalsDts from "gen/js/globals.d.ts!string"; -import osDts from "gen/js/os.d.ts!string"; -import fetchDts from "gen/js/fetch.d.ts!string"; -import timersDts from "gen/js/timers.d.ts!string"; -import utilDts from "gen/js/util.d.ts!string"; - -// Static libraries -import libEs2015Dts from "/third_party/node_modules/typescript/lib/lib.es2015.d.ts!string"; -import libEs2015CollectionDts from "/third_party/node_modules/typescript/lib/lib.es2015.collection.d.ts!string"; -import libEs2015CoreDts from "/third_party/node_modules/typescript/lib/lib.es2015.core.d.ts!string"; -import libEs2015GeneratorDts from "/third_party/node_modules/typescript/lib/lib.es2015.generator.d.ts!string"; -import libEs2015IterableDts from "/third_party/node_modules/typescript/lib/lib.es2015.iterable.d.ts!string"; -import libEs2015PromiseDts from "/third_party/node_modules/typescript/lib/lib.es2015.promise.d.ts!string"; -import libEs2015ProxyDts from "/third_party/node_modules/typescript/lib/lib.es2015.proxy.d.ts!string"; -import libEs2015ReflectDts from "/third_party/node_modules/typescript/lib/lib.es2015.reflect.d.ts!string"; -import libEs2015SymbolDts from "/third_party/node_modules/typescript/lib/lib.es2015.symbol.d.ts!string"; -import libEs2015SymbolWellknownDts from "/third_party/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts!string"; -import libEs2016Dts from "/third_party/node_modules/typescript/lib/lib.es2016.d.ts!string"; -import libEs2016ArrayIncludeDts from "/third_party/node_modules/typescript/lib/lib.es2016.array.include.d.ts!string"; -import libEs2017Dts from "/third_party/node_modules/typescript/lib/lib.es2017.d.ts!string"; -import libEs2017IntlDts from "/third_party/node_modules/typescript/lib/lib.es2017.intl.d.ts!string"; -import libEs2017ObjectDts from "/third_party/node_modules/typescript/lib/lib.es2017.object.d.ts!string"; -import libEs2017SharedmemoryDts from "/third_party/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts!string"; -import libEs2017StringDts from "/third_party/node_modules/typescript/lib/lib.es2017.string.d.ts!string"; -import libEs2017TypedarraysDts from "/third_party/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts!string"; -import libEs2018Dts from "/third_party/node_modules/typescript/lib/lib.es2018.d.ts!string"; -import libEs2018IntlDts from "/third_party/node_modules/typescript/lib/lib.es2018.intl.d.ts!string"; -import libEs2018PromiseDts from "/third_party/node_modules/typescript/lib/lib.es2018.promise.d.ts!string"; -import libEs2018RegexpDts from "/third_party/node_modules/typescript/lib/lib.es2018.regexp.d.ts!string"; -import libEs5Dts from "/third_party/node_modules/typescript/lib/lib.es5.d.ts!string"; -import libEsnextArrayDts from "/third_party/node_modules/typescript/lib/lib.esnext.array.d.ts!string"; -import libEsnextAsynciterablesDts from "/third_party/node_modules/typescript/lib/lib.esnext.asynciterable.d.ts!string"; -import libEsnextDts from "/third_party/node_modules/typescript/lib/lib.esnext.d.ts!string"; -import libEsnextIntlDts from "/third_party/node_modules/typescript/lib/lib.esnext.intl.d.ts!string"; -import libEsnextSymbolDts from "/third_party/node_modules/typescript/lib/lib.esnext.symbol.d.ts!string"; -import libGlobalsDts from "/js/lib.globals.d.ts!string"; - -// Static definitions -import typescriptDts from "/third_party/node_modules/typescript/lib/typescript.d.ts!string"; -import typesDts from "/js/types.d.ts!string"; -import fetchTypesDts from "/js/fetch_types.d.ts!string"; -// tslint:enable:max-line-length - -// prettier-ignore -export const assetSourceCode: { [key: string]: string } = { - // Generated definitions - "compiler.d.ts": compilerDts, - "console.d.ts": consoleDts, - "deno.d.ts": denoDts, - "libdeno.d.ts": libdenoDts, - "globals.d.ts": globalsDts, - "os.d.ts": osDts, - "fetch.d.ts": fetchDts, - "fetch_types.d.ts": fetchTypesDts, - "timers.d.ts": timersDts, - "util.d.ts": utilDts, - - // Static libraries - "lib.es2015.collection.d.ts": libEs2015CollectionDts, - "lib.es2015.core.d.ts": libEs2015CoreDts, - "lib.es2015.d.ts": libEs2015Dts, - "lib.es2015.generator.d.ts": libEs2015GeneratorDts, - "lib.es2015.iterable.d.ts": libEs2015IterableDts, - "lib.es2015.promise.d.ts": libEs2015PromiseDts, - "lib.es2015.proxy.d.ts": libEs2015ProxyDts, - "lib.es2015.reflect.d.ts": libEs2015ReflectDts, - "lib.es2015.symbol.d.ts": libEs2015SymbolDts, - "lib.es2015.symbol.wellknown.d.ts": libEs2015SymbolWellknownDts, - "lib.es2016.array.include.d.ts": libEs2016ArrayIncludeDts, - "lib.es2016.d.ts": libEs2016Dts, - "lib.es2017.d.ts": libEs2017Dts, - "lib.es2017.intl.d.ts": libEs2017IntlDts, - "lib.es2017.object.d.ts": libEs2017ObjectDts, - "lib.es2017.sharedmemory.d.ts": libEs2017SharedmemoryDts, - "lib.es2017.string.d.ts": libEs2017StringDts, - "lib.es2017.typedarrays.d.ts": libEs2017TypedarraysDts, - "lib.es2018.d.ts": libEs2018Dts, - "lib.es2018.intl.d.ts": libEs2018IntlDts, - "lib.es2018.promise.d.ts": libEs2018PromiseDts, - "lib.es2018.regexp.d.ts": libEs2018RegexpDts, - "lib.es5.d.ts": libEs5Dts, - "lib.esnext.d.ts": libEsnextDts, - "lib.esnext.array.d.ts": libEsnextArrayDts, - "lib.esnext.asynciterable.d.ts": libEsnextAsynciterablesDts, - "lib.esnext.intl.d.ts": libEsnextIntlDts, - "lib.esnext.symbol.d.ts": libEsnextSymbolDts, - "lib.globals.d.ts": libGlobalsDts, - - // Static definitions - "typescript.d.ts": typescriptDts, - "types.d.ts": typesDts, - - // TODO Remove. - "msg_generated.d.ts": "", -}; diff --git a/js/compiler.ts b/js/compiler.ts deleted file mode 100644 index 2e8c525b861a2d..00000000000000 --- a/js/compiler.ts +++ /dev/null @@ -1,722 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -import * as ts from "typescript"; -import { assetSourceCode } from "./assets"; -import * as deno from "./deno"; -import { globalEval } from "./global-eval"; -import { libdeno } from "./libdeno"; -import { window } from "./globals"; -import * as os from "./os"; -import { RawSourceMap } from "./types"; -import { assert, log, notImplemented } from "./util"; -import * as sourceMaps from "./v8_source_maps"; - -const EOL = "\n"; -const ASSETS = "$asset$"; - -// tslint:disable:no-any -type AmdCallback = (...args: any[]) => void; -type AmdErrback = (err: any) => void; -export type AmdFactory = (...args: any[]) => object | void; -// tslint:enable:no-any -export type AmdDefine = (deps: ModuleSpecifier[], factory: AmdFactory) => void; -type AMDRequire = ( - deps: ModuleSpecifier[], - callback: AmdCallback, - errback: AmdErrback -) => void; - -/** - * The location that a module is being loaded from. This could be a directory, - * like `.`, or it could be a module specifier like - * `http://gist.github.com/somefile.ts` - */ -type ContainingFile = string; -/** - * The internal local filename of a compiled module. It will often be something - * like `/home/ry/.deno/gen/f7b4605dfbc4d3bb356e98fda6ceb1481e4a8df5.js` - */ -type ModuleFileName = string; -/** - * The external name of a module - could be a URL or could be a relative path. - * Examples `http://gist.github.com/somefile.ts` or `./somefile.ts` - */ -type ModuleSpecifier = string; -/** - * The compiled source code which is cached in `.deno/gen/` - */ -type OutputCode = string; - -/** - * Abstraction of the APIs required from the `os` module so they can be - * easily mocked. - */ -export interface Os { - codeCache: typeof os.codeCache; - codeFetch: typeof os.codeFetch; - exit: typeof os.exit; -} - -/** - * Abstraction of the APIs required from the `typescript` module so they can - * be easily mocked. - */ -export interface Ts { - createLanguageService: typeof ts.createLanguageService; - /* tslint:disable-next-line:max-line-length */ - formatDiagnosticsWithColorAndContext: typeof ts.formatDiagnosticsWithColorAndContext; -} - -/** - * A simple object structure for caching resolved modules and their contents. - * - * Named `ModuleMetaData` to clarify it is just a representation of meta data of - * the module, not the actual module instance. - */ -export class ModuleMetaData implements ts.IScriptSnapshot { - public deps?: ModuleFileName[]; - public readonly exports = {}; - public factory?: AmdFactory; - public hasRun = false; - public scriptVersion = ""; - - constructor( - public readonly fileName: ModuleFileName, - public readonly sourceCode = "", - public outputCode = "" - ) { - if (outputCode !== "" || fileName.endsWith(".d.ts")) { - this.scriptVersion = "1"; - } - } - - public getText(start: number, end: number): string { - return this.sourceCode.substring(start, end); - } - - public getLength(): number { - return this.sourceCode.length; - } - - public getChangeRange(): undefined { - // Required `IScriptSnapshot` API, but not implemented/needed in deno - return undefined; - } -} - -/** - * The required minimal API to allow formatting of TypeScript compiler - * diagnostics. - */ -const formatDiagnosticsHost: ts.FormatDiagnosticsHost = { - getCurrentDirectory: () => ".", - getCanonicalFileName: (fileName: string) => fileName, - getNewLine: () => EOL -}; - -/** - * Throw a module resolution error, when a module is unsuccessfully resolved. - */ -function throwResolutionError( - message: string, - moduleSpecifier: ModuleSpecifier, - containingFile: ContainingFile -): never { - throw new Error( - // tslint:disable-next-line:max-line-length - `Cannot resolve module "${moduleSpecifier}" from "${containingFile}".\n ${message}` - ); -} - -// ts.ScriptKind is not available at runtime, so local enum definition -enum ScriptKind { - JS = 1, - TS = 3, - JSON = 6 -} - -/** - * A singleton class that combines the TypeScript Language Service host API - * with Deno specific APIs to provide an interface for compiling and running - * TypeScript and JavaScript modules. - */ -export class DenoCompiler implements ts.LanguageServiceHost { - // Modules are usually referenced by their ModuleSpecifier and ContainingFile, - // and keeping a map of the resolved module file name allows more efficient - // future resolution - private readonly _fileNamesMap = new Map< - ContainingFile, - Map - >(); - // A reference to global eval, so it can be monkey patched during testing - private _globalEval = globalEval; - // A reference to the log utility, so it can be monkey patched during testing - private _log = log; - // A map of module file names to module meta data - private readonly _moduleMetaDataMap = new Map< - ModuleFileName, - ModuleMetaData - >(); - // TODO ideally this are not static and can be influenced by command line - // arguments - private readonly _options: Readonly = { - allowJs: true, - module: ts.ModuleKind.AMD, - outDir: "$deno$", - // TODO https://github.com/denoland/deno/issues/23 - inlineSourceMap: true, - inlineSources: true, - stripComments: true, - target: ts.ScriptTarget.ESNext - }; - // A reference to the `./os.ts` module, so it can be monkey patched during - // testing - private _os: Os = os; - // Contains a queue of modules that have been resolved, but not yet - // run - private _runQueue: ModuleMetaData[] = []; - // Used to contain the script file we are currently running - private _scriptFileNames: string[] = []; - // A reference to the TypeScript LanguageService instance so it can be - // monkey patched during testing - private _service: ts.LanguageService; - // A reference to `typescript` module so it can be monkey patched during - // testing - private _ts: Ts = ts; - // A reference to the global scope so it can be monkey patched during - // testing - private _window = window; - - /** - * Drain the run queue, retrieving the arguments for the module - * factory and calling the module's factory. - */ - private _drainRunQueue(): void { - this._log( - "compiler._drainRunQueue", - this._runQueue.map(metaData => metaData.fileName) - ); - let moduleMetaData: ModuleMetaData | undefined; - while ((moduleMetaData = this._runQueue.shift())) { - assert( - moduleMetaData.factory != null, - "Cannot run module without factory." - ); - assert(moduleMetaData.hasRun === false, "Module has already been run."); - // asserts not tracked by TypeScripts, so using not null operator - moduleMetaData.factory!(...this._getFactoryArguments(moduleMetaData)); - moduleMetaData.hasRun = true; - } - } - - /** - * Get the dependencies for a given module, but don't run the module, - * just add the module factory to the run queue. - */ - private _gatherDependencies(moduleMetaData: ModuleMetaData): void { - this._log("compiler._resolveDependencies", moduleMetaData.fileName); - - // if the module has already run, we can short circuit. - // it is intentional though that if we have already resolved dependencies, - // we won't short circuit, as something may have changed, or we might have - // only collected the dependencies to be able to able to obtain the graph of - // dependencies - if (moduleMetaData.hasRun) { - return; - } - - this._window.define = this.makeDefine(moduleMetaData); - this._globalEval(this.compile(moduleMetaData)); - this._window.define = undefined; - } - - /** - * Retrieve the arguments to pass a module's factory function. - */ - // tslint:disable-next-line:no-any - private _getFactoryArguments(moduleMetaData: ModuleMetaData): any[] { - if (!moduleMetaData.deps) { - throw new Error("Cannot get arguments until dependencies resolved."); - } - return moduleMetaData.deps.map(dep => { - if (dep === "require") { - return this._makeLocalRequire(moduleMetaData); - } - if (dep === "exports") { - return moduleMetaData.exports; - } - if (dep in DenoCompiler._builtins) { - return DenoCompiler._builtins[dep]; - } - const dependencyMetaData = this._getModuleMetaData(dep); - assert(dependencyMetaData != null, `Missing dependency "${dep}".`); - assert( - dependencyMetaData!.hasRun === true, - `Module "${dep}" was not run.` - ); - // TypeScript does not track assert, therefore using not null operator - return dependencyMetaData!.exports; - }); - } - - /** - * The TypeScript language service often refers to the resolved fileName of - * a module, this is a shortcut to avoid unnecessary module resolution logic - * for modules that may have been initially resolved by a `moduleSpecifier` - * and `containingFile`. Also, `resolveModule()` throws when the module - * cannot be resolved, which isn't always valid when dealing with the - * TypeScript compiler, but the TypeScript compiler shouldn't be asking about - * external modules that we haven't told it about yet. - */ - private _getModuleMetaData( - fileName: ModuleFileName - ): ModuleMetaData | undefined { - return this._moduleMetaDataMap.has(fileName) - ? this._moduleMetaDataMap.get(fileName) - : fileName.startsWith(ASSETS) - ? this.resolveModule(fileName, "") - : undefined; - } - - /** - * Returns a require that specifically handles the resolution of a transpiled - * emit of a dynamic ES `import()` from TypeScript. - */ - private _makeLocalRequire(moduleMetaData: ModuleMetaData): AMDRequire { - const localRequire = ( - deps: ModuleSpecifier[], - callback: AmdCallback, - errback: AmdErrback - ): void => { - log("localRequire", deps); - assert( - deps.length === 1, - "Local require requires exactly one dependency." - ); - const [moduleSpecifier] = deps; - try { - const requiredMetaData = this.run( - moduleSpecifier, - moduleMetaData.fileName - ); - callback(requiredMetaData.exports); - } catch (e) { - errback(e); - } - }; - return localRequire; - } - - /** - * Setup being able to map back source references back to their source - * - * TODO is this the best place for this? It is tightly coupled to how the - * compiler works, but it is also tightly coupled to how the whole runtime - * environment is bootstrapped. It also needs efficient access to the - * `outputCode` of the module information, which exists inside of the - * compiler instance. - */ - private _setupSourceMaps(): void { - sourceMaps.install({ - installPrepareStackTrace: true, - getGeneratedContents: (fileName: string): string | RawSourceMap => { - this._log("compiler.getGeneratedContents", fileName); - if (fileName === "gen/bundle/main.js") { - assert(libdeno.mainSource.length > 0); - return libdeno.mainSource; - } else if (fileName === "main.js.map") { - return libdeno.mainSourceMap; - } else if (fileName === "deno_main.js") { - return ""; - } else { - const moduleMetaData = this._moduleMetaDataMap.get(fileName); - if (!moduleMetaData) { - this._log("compiler.getGeneratedContents cannot find", fileName); - return ""; - } - return moduleMetaData.outputCode; - } - } - }); - } - - private constructor() { - if (DenoCompiler._instance) { - throw new TypeError("Attempt to create an additional compiler."); - } - this._service = this._ts.createLanguageService(this); - this._setupSourceMaps(); - } - - // Deno specific compiler API - - /** - * Retrieve the output of the TypeScript compiler for a given module and - * cache the result. - */ - compile(moduleMetaData: ModuleMetaData): OutputCode { - this._log("compiler.compile", moduleMetaData.fileName); - if (moduleMetaData.outputCode) { - return moduleMetaData.outputCode; - } - const { fileName, sourceCode } = moduleMetaData; - const service = this._service; - const output = service.getEmitOutput(fileName); - - // Get the relevant diagnostics - this is 3x faster than - // `getPreEmitDiagnostics`. - const diagnostics = [ - ...service.getCompilerOptionsDiagnostics(), - ...service.getSyntacticDiagnostics(fileName), - ...service.getSemanticDiagnostics(fileName) - ]; - if (diagnostics.length > 0) { - const errMsg = this._ts.formatDiagnosticsWithColorAndContext( - diagnostics, - formatDiagnosticsHost - ); - console.log(errMsg); - // All TypeScript errors are terminal for deno - this._os.exit(1); - } - - assert(!output.emitSkipped, "The emit was skipped for an unknown reason."); - - // Currently we are inlining source maps, there should be only 1 output file - // See: https://github.com/denoland/deno/issues/23 - assert( - output.outputFiles.length === 1, - "Only single file should be output." - ); - - const [outputFile] = output.outputFiles; - const outputCode = (moduleMetaData.outputCode = `${ - outputFile.text - }\n//# sourceURL=${fileName}`); - moduleMetaData.scriptVersion = "1"; - this._os.codeCache(fileName, sourceCode, outputCode); - return moduleMetaData.outputCode; - } - - /** - * For a given module specifier and containing file, return a list of absolute - * identifiers for dependent modules that are required by this module. - */ - getModuleDependencies( - moduleSpecifier: ModuleSpecifier, - containingFile: ContainingFile - ): ModuleFileName[] { - assert( - this._runQueue.length === 0, - "Cannot get dependencies with modules queued to be run." - ); - const moduleMetaData = this.resolveModule(moduleSpecifier, containingFile); - assert( - !moduleMetaData.hasRun, - "Cannot get dependencies for a module that has already been run." - ); - this._gatherDependencies(moduleMetaData); - const dependencies = this._runQueue.map( - moduleMetaData => moduleMetaData.fileName - ); - // empty the run queue, to free up references to factories we have collected - // and to ensure that if there is a further invocation of `.run()` the - // factories don't get called - this._runQueue = []; - return dependencies; - } - - /** - * Create a localized AMD `define` function and return it. - */ - makeDefine(moduleMetaData: ModuleMetaData): AmdDefine { - // TODO should this really be part of the public API of the compiler? - const localDefine: AmdDefine = ( - deps: ModuleSpecifier[], - factory: AmdFactory - ): void => { - this._log("compiler.localDefine", moduleMetaData.fileName); - moduleMetaData.factory = factory; - // we will recursively resolve the dependencies for any modules - moduleMetaData.deps = deps.map(dep => { - if ( - dep === "require" || - dep === "exports" || - dep in DenoCompiler._builtins - ) { - return dep; - } - const dependencyMetaData = this.resolveModule( - dep, - moduleMetaData.fileName - ); - this._gatherDependencies(dependencyMetaData); - return dependencyMetaData.fileName; - }); - if (!this._runQueue.includes(moduleMetaData)) { - this._runQueue.push(moduleMetaData); - } - }; - return localDefine; - } - - /** - * Given a `moduleSpecifier` and `containingFile` retrieve the cached - * `fileName` for a given module. If the module has yet to be resolved - * this will return `undefined`. - */ - resolveFileName( - moduleSpecifier: ModuleSpecifier, - containingFile: ContainingFile - ): ModuleFileName | undefined { - this._log("compiler.resolveFileName", { moduleSpecifier, containingFile }); - const innerMap = this._fileNamesMap.get(containingFile); - if (innerMap) { - return innerMap.get(moduleSpecifier); - } - return undefined; - } - - /** - * Given a `moduleSpecifier` and `containingFile`, resolve the module and - * return the `ModuleMetaData`. - */ - resolveModule( - moduleSpecifier: ModuleSpecifier, - containingFile: ContainingFile - ): ModuleMetaData { - this._log("compiler.resolveModule", { moduleSpecifier, containingFile }); - assert(moduleSpecifier != null && moduleSpecifier.length > 0); - let fileName = this.resolveFileName(moduleSpecifier, containingFile); - if (fileName && this._moduleMetaDataMap.has(fileName)) { - return this._moduleMetaDataMap.get(fileName)!; - } - let sourceCode: string | undefined; - let outputCode: string | undefined; - if ( - moduleSpecifier.startsWith(ASSETS) || - containingFile.startsWith(ASSETS) - ) { - // Assets are compiled into the runtime javascript bundle. - // we _know_ `.pop()` will return a string, but TypeScript doesn't so - // not null assertion - const moduleId = moduleSpecifier.split("/").pop()!; - const assetName = moduleId.includes(".") ? moduleId : `${moduleId}.d.ts`; - assert(assetName in assetSourceCode, `No such asset "${assetName}"`); - sourceCode = assetSourceCode[assetName]; - fileName = `${ASSETS}/${assetName}`; - } else { - // We query Rust with a CodeFetch message. It will load the sourceCode, - // and if there is any outputCode cached, will return that as well. - let fetchResponse; - try { - fetchResponse = this._os.codeFetch(moduleSpecifier, containingFile); - } catch (e) { - return throwResolutionError( - `os.codeFetch message: ${e.message}`, - moduleSpecifier, - containingFile - ); - } - fileName = fetchResponse.filename || undefined; - sourceCode = fetchResponse.sourceCode || undefined; - outputCode = fetchResponse.outputCode || undefined; - } - if (!sourceCode || sourceCode.length === 0 || !fileName) { - return throwResolutionError( - "Invalid source code or file name.", - moduleSpecifier, - containingFile - ); - } - this._log("resolveModule sourceCode length:", sourceCode.length); - this._log("resolveModule has outputCode:", !!outputCode); - this.setFileName(moduleSpecifier, containingFile, fileName); - if (fileName && this._moduleMetaDataMap.has(fileName)) { - return this._moduleMetaDataMap.get(fileName)!; - } - const moduleMetaData = new ModuleMetaData(fileName, sourceCode, outputCode); - this._moduleMetaDataMap.set(fileName, moduleMetaData); - return moduleMetaData; - } - - /** - * Resolve the `fileName` for a given `moduleSpecifier` and `containingFile` - */ - resolveModuleName( - moduleSpecifier: ModuleSpecifier, - containingFile: ContainingFile - ): ModuleFileName | undefined { - // TODO should this be part of the public API of the compiler? - const moduleMetaData = this.resolveModule(moduleSpecifier, containingFile); - return moduleMetaData ? moduleMetaData.fileName : undefined; - } - - /** - * Load and run a module and all of its dependencies based on a module - * specifier and a containing file - */ - run( - moduleSpecifier: ModuleSpecifier, - containingFile: ContainingFile - ): ModuleMetaData { - this._log("compiler.run", { moduleSpecifier, containingFile }); - const moduleMetaData = this.resolveModule(moduleSpecifier, containingFile); - this._scriptFileNames = [moduleMetaData.fileName]; - if (!moduleMetaData.deps) { - this._gatherDependencies(moduleMetaData); - } - this._drainRunQueue(); - return moduleMetaData; - } - - /** - * Caches the resolved `fileName` in relationship to the `moduleSpecifier` - * and `containingFile` in order to reduce calls to the privileged side - * to retrieve the contents of a module. - */ - setFileName( - moduleSpecifier: ModuleSpecifier, - containingFile: ContainingFile, - fileName: ModuleFileName - ): void { - // TODO should this be part of the public API of the compiler? - this._log("compiler.setFileName", { moduleSpecifier, containingFile }); - let innerMap = this._fileNamesMap.get(containingFile); - if (!innerMap) { - innerMap = new Map(); - this._fileNamesMap.set(containingFile, innerMap); - } - innerMap.set(moduleSpecifier, fileName); - } - - // TypeScript Language Service API - - getCompilationSettings(): ts.CompilerOptions { - this._log("getCompilationSettings()"); - return this._options; - } - - getNewLine(): string { - return EOL; - } - - getScriptFileNames(): string[] { - // This is equal to `"files"` in the `tsconfig.json`, therefore we only need - // to include the actual base source files we are evaluating at the moment, - // which would be what is set during the `.run()` - return this._scriptFileNames; - } - - getScriptKind(fileName: ModuleFileName): ts.ScriptKind { - this._log("getScriptKind()", fileName); - const suffix = fileName.substr(fileName.lastIndexOf(".") + 1); - switch (suffix) { - case "ts": - return ScriptKind.TS; - case "js": - return ScriptKind.JS; - case "json": - return ScriptKind.JSON; - default: - return this._options.allowJs ? ScriptKind.JS : ScriptKind.TS; - } - } - - getScriptVersion(fileName: ModuleFileName): string { - this._log("getScriptVersion()", fileName); - const moduleMetaData = this._getModuleMetaData(fileName); - return (moduleMetaData && moduleMetaData.scriptVersion) || ""; - } - - getScriptSnapshot(fileName: ModuleFileName): ts.IScriptSnapshot | undefined { - this._log("getScriptSnapshot()", fileName); - return this._getModuleMetaData(fileName); - } - - getCurrentDirectory(): string { - this._log("getCurrentDirectory()"); - return ""; - } - - getDefaultLibFileName(): string { - this._log("getDefaultLibFileName()"); - const moduleSpecifier = "lib.globals.d.ts"; - const moduleMetaData = this.resolveModule(moduleSpecifier, ASSETS); - return moduleMetaData.fileName; - } - - useCaseSensitiveFileNames(): boolean { - this._log("useCaseSensitiveFileNames()"); - return true; - } - - readFile(path: string): string | undefined { - this._log("readFile()", path); - return notImplemented(); - } - - fileExists(fileName: string): boolean { - const moduleMetaData = this._getModuleMetaData(fileName); - const exists = moduleMetaData != null; - this._log("fileExists()", fileName, exists); - return exists; - } - - resolveModuleNames( - moduleNames: ModuleSpecifier[], - containingFile: ContainingFile - ): ts.ResolvedModule[] { - this._log("resolveModuleNames()", { moduleNames, containingFile }); - return moduleNames.map(name => { - let resolvedFileName; - if (name === "deno") { - resolvedFileName = this.resolveModuleName("deno.d.ts", ASSETS); - } else if (name === "compiler") { - resolvedFileName = this.resolveModuleName("compiler.d.ts", ASSETS); - } else if (name === "typescript") { - resolvedFileName = this.resolveModuleName("typescript.d.ts", ASSETS); - } else { - resolvedFileName = this.resolveModuleName(name, containingFile); - } - // According to the interface we shouldn't return `undefined` but if we - // fail to return the same length of modules to those we cannot resolve - // then TypeScript fails on an assertion that the lengths can't be - // different, so we have to return an "empty" resolved module - // TODO: all this does is push the problem downstream, and TypeScript - // will complain it can't identify the type of the file and throw - // a runtime exception, so we need to handle missing modules better - resolvedFileName = resolvedFileName || ""; - // This flags to the compiler to not go looking to transpile functional - // code, anything that is in `/$asset$/` is just library code - const isExternalLibraryImport = resolvedFileName.startsWith(ASSETS); - // TODO: we should be returning a ts.ResolveModuleFull - return { resolvedFileName, isExternalLibraryImport }; - }); - } - - // Deno specific static properties and methods - - /** - * Built in modules which can be returned to external modules - * - * Placed as a private static otherwise we get use before - * declared with the `DenoCompiler` - */ - // tslint:disable-next-line:no-any - private static _builtins: { [mid: string]: any } = { - typescript: ts, - deno, - compiler: { DenoCompiler, ModuleMetaData } - }; - - private static _instance: DenoCompiler | undefined; - - /** - * Returns the instance of `DenoCompiler` or creates a new instance. - */ - static instance(): DenoCompiler { - return ( - DenoCompiler._instance || (DenoCompiler._instance = new DenoCompiler()) - ); - } -} diff --git a/js/compiler_test.ts b/js/compiler_test.ts deleted file mode 100644 index 2fb67ab3b4b97a..00000000000000 --- a/js/compiler_test.ts +++ /dev/null @@ -1,505 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -import { test, assert, assertEqual } from "./test_util.ts"; -import * as compiler from "compiler"; -import * as ts from "typescript"; - -// We use a silly amount of `any` in these tests... -// tslint:disable:no-any - -const { DenoCompiler } = compiler; - -// Enums like this don't exist at runtime, so local copy -enum ScriptKind { - JS = 1, - TS = 3, - JSON = 6 -} - -interface ModuleInfo { - moduleName: string | null; - filename: string | null; - sourceCode: string | null; - outputCode: string | null; -} - -const compilerInstance = DenoCompiler.instance(); - -// References to orignal items we are going to mock -const originals = { - _globalEval: (compilerInstance as any)._globalEval, - _log: (compilerInstance as any)._log, - _os: (compilerInstance as any)._os, - _ts: (compilerInstance as any)._ts, - _service: (compilerInstance as any)._service, - _window: (compilerInstance as any)._window -}; - -function mockModuleInfo( - moduleName: string | null, - filename: string | null, - sourceCode: string | null, - outputCode: string | null -): ModuleInfo { - return { - moduleName, - filename, - sourceCode, - outputCode - }; -} - -// Some fixtures we will us in testing -const fooBarTsSource = `import * as compiler from "compiler"; -console.log(compiler); -export const foo = "bar"; -`; - -const fooBazTsSource = `import { foo } from "./bar.ts"; -console.log(foo); -`; - -// TODO(#23) Remove source map strings from fooBarTsOutput. -// tslint:disable:max-line-length -const fooBarTsOutput = `define(["require", "exports", "compiler"], function (require, exports, compiler) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - console.log(compiler); - exports.foo = "bar"; -}); -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZmlsZTovLy9yb290L3Byb2plY3QvZm9vL2Jhci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7SUFDQSxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ1QsUUFBQSxHQUFHLEdBQUcsS0FBSyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgY29tcGlsZXIgZnJvbSBcImNvbXBpbGVyXCI7XG5jb25zb2xlLmxvZyhjb21waWxlcik7XG5leHBvcnQgY29uc3QgZm9vID0gXCJiYXJcIjtcbiJdfQ== -//# sourceURL=/root/project/foo/bar.ts`; - -// TODO(#23) Remove source map strings from fooBazTsOutput. -const fooBazTsOutput = `define(["require", "exports", "./bar.ts"], function (require, exports, bar_ts_1) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - console.log(bar_ts_1.foo); -}); -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmF6LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZmlsZTovLy9yb290L3Byb2plY3QvZm9vL2Jhei50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7SUFDQSxPQUFPLENBQUMsR0FBRyxDQUFDLFlBQUcsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZm9vIH0gZnJvbSBcIi4vYmFyLnRzXCI7XG5jb25zb2xlLmxvZyhmb28pO1xuIl19 -//# sourceURL=/root/project/foo/baz.ts`; -// tslint:enable:max-line-length - -const moduleMap: { - [containFile: string]: { [moduleSpecifier: string]: ModuleInfo }; -} = { - "/root/project": { - "foo/bar.ts": mockModuleInfo( - "foo/bar", - "/root/project/foo/bar.ts", - fooBarTsSource, - null - ), - "foo/baz.ts": mockModuleInfo( - "foo/baz", - "/root/project/foo/baz.ts", - fooBazTsSource, - fooBazTsOutput - ) - }, - "/root/project/foo/baz.ts": { - "./bar.ts": mockModuleInfo( - "foo/bar", - "/root/project/foo/bar.ts", - fooBarTsSource, - fooBarTsOutput - ) - } -}; - -const emittedFiles = { - "/root/project/foo/qat.ts": "console.log('foo');" -}; - -let globalEvalStack: string[] = []; -let getEmitOutputStack: string[] = []; -let logStack: any[][] = []; -let codeCacheStack: Array<{ - fileName: string; - sourceCode: string; - outputCode: string; -}> = []; -let codeFetchStack: Array<{ - moduleSpecifier: string; - containingFile: string; -}> = []; - -let mockDepsStack: string[][] = []; -let mockFactoryStack: compiler.AmdFactory[] = []; - -function globalEvalMock(x: string): void { - globalEvalStack.push(x); - if (windowMock.define && mockDepsStack.length && mockFactoryStack.length) { - windowMock.define(mockDepsStack.pop(), mockFactoryStack.pop()); - } -} -function logMock(...args: any[]): void { - logStack.push(args); -} -const osMock: compiler.Os = { - codeCache(fileName: string, sourceCode: string, outputCode: string): void { - codeCacheStack.push({ fileName, sourceCode, outputCode }); - }, - codeFetch(moduleSpecifier: string, containingFile: string): ModuleInfo { - codeFetchStack.push({ moduleSpecifier, containingFile }); - if (containingFile in moduleMap) { - if (moduleSpecifier in moduleMap[containingFile]) { - return moduleMap[containingFile][moduleSpecifier]; - } - } - return mockModuleInfo(null, null, null, null); - }, - exit(code: number): never { - throw new Error(`os.exit(${code})`); - } -}; -const tsMock: compiler.Ts = { - createLanguageService(host: ts.LanguageServiceHost): ts.LanguageService { - return {} as ts.LanguageService; - }, - formatDiagnosticsWithColorAndContext( - diagnostics: ReadonlyArray, - host: ts.FormatDiagnosticsHost - ): string { - return ""; - } -}; - -const getEmitOutputPassThrough = true; - -const serviceMock = { - getCompilerOptionsDiagnostics(): ts.Diagnostic[] { - return originals._service.getCompilerOptionsDiagnostics.call( - originals._service - ); - }, - getEmitOutput(fileName: string): ts.EmitOutput { - getEmitOutputStack.push(fileName); - if (getEmitOutputPassThrough) { - return originals._service.getEmitOutput.call( - originals._service, - fileName - ); - } - if (fileName in emittedFiles) { - return { - outputFiles: [{ text: emittedFiles[fileName] }] as any, - emitSkipped: false - }; - } - return { outputFiles: [], emitSkipped: false }; - }, - getSemanticDiagnostics(fileName: string): ts.Diagnostic[] { - return originals._service.getSemanticDiagnostics.call( - originals._service, - fileName - ); - }, - getSyntacticDiagnostics(fileName: string): ts.Diagnostic[] { - return originals._service.getSyntacticDiagnostics.call( - originals._service, - fileName - ); - } -}; -const windowMock: { define?: compiler.AmdDefine } = {}; -const mocks = { - _globalEval: globalEvalMock, - _log: logMock, - _os: osMock, - _ts: tsMock, - _service: serviceMock, - _window: windowMock -}; - -/** - * Setup the mocks for a test - */ -function setup() { - // monkey patch mocks on instance - Object.assign(compilerInstance, mocks); -} - -/** - * Teardown the mocks for a test - */ -function teardown() { - // reset compiler internal state - (compilerInstance as any)._moduleMetaDataMap.clear(); - (compilerInstance as any)._fileNamesMap.clear(); - - // reset mock states - codeFetchStack = []; - codeCacheStack = []; - logStack = []; - getEmitOutputStack = []; - globalEvalStack = []; - - assertEqual(mockDepsStack.length, 0); - assertEqual(mockFactoryStack.length, 0); - mockDepsStack = []; - mockFactoryStack = []; - - // restore original properties and methods - Object.assign(compilerInstance, originals); -} - -test(function compilerInstance() { - assert(DenoCompiler != null); - assert(DenoCompiler.instance() != null); -}); - -// Testing the internal APIs - -test(function compilerRun() { - // equal to `deno foo/bar.ts` - setup(); - let factoryRun = false; - mockDepsStack.push(["require", "exports", "compiler"]); - mockFactoryStack.push((_require, _exports, _compiler) => { - factoryRun = true; - assertEqual(typeof _require, "function"); - assertEqual(typeof _exports, "object"); - assert(_compiler === compiler); - _exports.foo = "bar"; - }); - const moduleMetaData = compilerInstance.run("foo/bar.ts", "/root/project"); - assert(factoryRun); - assert(moduleMetaData.hasRun); - assertEqual(moduleMetaData.sourceCode, fooBarTsSource); - assertEqual(moduleMetaData.outputCode, fooBarTsOutput); - assertEqual(moduleMetaData.exports, { foo: "bar" }); - - assertEqual( - codeFetchStack.length, - 1, - "Module should have only been fetched once." - ); - assertEqual( - codeCacheStack.length, - 1, - "Compiled code should have only been cached once." - ); - teardown(); -}); - -test(function compilerRunMultiModule() { - // equal to `deno foo/baz.ts` - setup(); - const factoryStack: string[] = []; - const bazDeps = ["require", "exports", "./bar.ts"]; - const bazFactory = (_require, _exports, _bar) => { - factoryStack.push("baz"); - assertEqual(_bar.foo, "bar"); - }; - const barDeps = ["require", "exports", "compiler"]; - const barFactory = (_require, _exports, _compiler) => { - factoryStack.push("bar"); - _exports.foo = "bar"; - }; - mockDepsStack.push(barDeps); - mockFactoryStack.push(barFactory); - mockDepsStack.push(bazDeps); - mockFactoryStack.push(bazFactory); - compilerInstance.run("foo/baz.ts", "/root/project"); - assertEqual(factoryStack, ["bar", "baz"]); - - assertEqual( - codeFetchStack.length, - 2, - "Modules should have only been fetched once." - ); - assertEqual(codeCacheStack.length, 0, "No code should have been cached."); - teardown(); -}); - -test(function compilerResolveModule() { - setup(); - const moduleMetaData = compilerInstance.resolveModule( - "foo/baz.ts", - "/root/project" - ); - assertEqual(moduleMetaData.sourceCode, fooBazTsSource); - assertEqual(moduleMetaData.outputCode, fooBazTsOutput); - assert(!moduleMetaData.hasRun); - assert(!moduleMetaData.deps); - assertEqual(moduleMetaData.exports, {}); - assertEqual(moduleMetaData.scriptVersion, "1"); - - assertEqual(codeFetchStack.length, 1, "Only initial module is resolved."); - teardown(); -}); - -test(function compilerGetModuleDependencies() { - setup(); - const bazDeps = ["require", "exports", "./bar.ts"]; - const bazFactory = () => { - throw new Error("Unexpected factory call"); - }; - const barDeps = ["require", "exports", "compiler"]; - const barFactory = () => { - throw new Error("Unexpected factory call"); - }; - mockDepsStack.push(barDeps); - mockFactoryStack.push(barFactory); - mockDepsStack.push(bazDeps); - mockFactoryStack.push(bazFactory); - const deps = compilerInstance.getModuleDependencies( - "foo/baz.ts", - "/root/project" - ); - assertEqual(deps, ["/root/project/foo/bar.ts", "/root/project/foo/baz.ts"]); - teardown(); -}); - -// TypeScript LanguageServiceHost APIs - -test(function compilerGetCompilationSettings() { - const result = compilerInstance.getCompilationSettings(); - for (const key of [ - "allowJs", - "module", - "outDir", - "inlineSourceMap", - "inlineSources", - "stripComments", - "target" - ]) { - assert(key in result, `Expected "${key}" in compiler options.`); - } -}); - -test(function compilerGetNewLine() { - const result = compilerInstance.getNewLine(); - assertEqual(result, "\n", "Expected newline value of '\\n'."); -}); - -test(function compilerGetScriptFileNames() { - setup(); - compilerInstance.run("foo/bar.ts", "/root/project"); - const result = compilerInstance.getScriptFileNames(); - assertEqual(result.length, 1, "Expected only a single filename."); - assertEqual(result[0], "/root/project/foo/bar.ts"); - teardown(); -}); - -test(function compilerGetScriptKind() { - assertEqual(compilerInstance.getScriptKind("foo.ts"), ScriptKind.TS); - assertEqual(compilerInstance.getScriptKind("foo.d.ts"), ScriptKind.TS); - assertEqual(compilerInstance.getScriptKind("foo.js"), ScriptKind.JS); - assertEqual(compilerInstance.getScriptKind("foo.json"), ScriptKind.JSON); - assertEqual(compilerInstance.getScriptKind("foo.txt"), ScriptKind.JS); -}); - -test(function compilerGetScriptVersion() { - setup(); - const moduleMetaData = compilerInstance.resolveModule( - "foo/bar.ts", - "/root/project" - ); - compilerInstance.compile(moduleMetaData); - assertEqual( - compilerInstance.getScriptVersion(moduleMetaData.fileName), - "1", - "Expected known module to have script version of 1" - ); - teardown(); -}); - -test(function compilerGetScriptVersionUnknown() { - assertEqual( - compilerInstance.getScriptVersion("/root/project/unknown_module.ts"), - "", - "Expected unknown module to have an empty script version" - ); -}); - -test(function compilerGetScriptSnapshot() { - setup(); - const moduleMetaData = compilerInstance.resolveModule( - "foo/bar.ts", - "/root/project" - ); - const result = compilerInstance.getScriptSnapshot(moduleMetaData.fileName); - assert(result != null, "Expected snapshot to be defined."); - assertEqual(result.getLength(), fooBarTsSource.length); - assertEqual( - result.getText(0, 6), - "import", - "Expected .getText() to equal 'import'" - ); - assertEqual(result.getChangeRange(result), undefined); - // This is and optional part of the `IScriptSnapshot` API which we don't - // define, os checking for the lack of this property. - assert(!("dispose" in result)); - - assert( - result === moduleMetaData, - "result should strictly equal moduleMetaData" - ); - teardown(); -}); - -test(function compilerGetCurrentDirectory() { - assertEqual(compilerInstance.getCurrentDirectory(), ""); -}); - -test(function compilerGetDefaultLibFileName() { - setup(); - assertEqual( - compilerInstance.getDefaultLibFileName(), - "$asset$/lib.globals.d.ts" - ); - teardown(); -}); - -test(function compilerUseCaseSensitiveFileNames() { - assertEqual(compilerInstance.useCaseSensitiveFileNames(), true); -}); - -test(function compilerReadFile() { - let doesThrow = false; - try { - compilerInstance.readFile("foobar.ts"); - } catch (e) { - doesThrow = true; - assert(e.message.includes("Not implemented") === true); - } - assert(doesThrow); -}); - -test(function compilerFileExists() { - setup(); - const moduleMetaData = compilerInstance.resolveModule( - "foo/bar.ts", - "/root/project" - ); - assert(compilerInstance.fileExists(moduleMetaData.fileName)); - assert(compilerInstance.fileExists("$asset$/compiler.d.ts")); - assertEqual( - compilerInstance.fileExists("/root/project/unknown-module.ts"), - false - ); - teardown(); -}); - -test(function compilerResolveModuleNames() { - setup(); - const results = compilerInstance.resolveModuleNames( - ["foo/bar.ts", "foo/baz.ts", "$asset$/lib.globals.d.ts", "deno"], - "/root/project" - ); - assertEqual(results.length, 4); - const fixtures: Array<[string, boolean]> = [ - ["/root/project/foo/bar.ts", false], - ["/root/project/foo/baz.ts", false], - ["$asset$/lib.globals.d.ts", true], - ["$asset$/deno.d.ts", true] - ]; - for (let i = 0; i < results.length; i++) { - const result = results[i]; - const [resolvedFileName, isExternalLibraryImport] = fixtures[i]; - assertEqual(result.resolvedFileName, resolvedFileName); - assertEqual(result.isExternalLibraryImport, isExternalLibraryImport); - } - teardown(); -}); diff --git a/js/console.ts b/js/console.ts deleted file mode 100644 index e08fc445e110f5..00000000000000 --- a/js/console.ts +++ /dev/null @@ -1,138 +0,0 @@ -// tslint:disable-next-line:no-any -type ConsoleContext = Set; - -// tslint:disable-next-line:no-any -function getClassInstanceName(instance: any): string { - if (typeof instance !== "object") { - return ""; - } - if (instance && instance.__proto__ && instance.__proto__.constructor) { - return instance.__proto__.constructor.name; // could be "Object" or "Array" - } - return ""; -} - -// tslint:disable-next-line:no-any -function stringify(ctx: ConsoleContext, value: any): string { - switch (typeof value) { - case "string": - return value; - case "number": - case "boolean": - case "undefined": - case "symbol": - return String(value); - case "function": - if (value.name && value.name !== "anonymous") { - // from MDN spec - return `[Function: ${value.name}]`; - } - return "[Function]"; - case "object": - if (value === null) { - return "null"; - } - - if (ctx.has(value)) { - return "[Circular]"; - } - - ctx.add(value); - const entries: string[] = []; - - if (Array.isArray(value)) { - for (const el of value) { - entries.push(stringifyWithQuotes(ctx, el)); - } - - ctx.delete(value); - - if (entries.length === 0) { - return "[]"; - } - return `[ ${entries.join(", ")} ]`; - } else { - let baseString = ""; - - const className = getClassInstanceName(value); - let shouldShowClassName = false; - if (className && className !== "Object" && className !== "anonymous") { - shouldShowClassName = true; - } - - for (const key of Object.keys(value)) { - entries.push(`${key}: ${stringifyWithQuotes(ctx, value[key])}`); - } - - ctx.delete(value); - - if (entries.length === 0) { - baseString = "{}"; - } else { - baseString = `{ ${entries.join(", ")} }`; - } - - if (shouldShowClassName) { - baseString = `${className} ${baseString}`; - } - - return baseString; - } - default: - return "[Not Implemented]"; - } -} - -// Print strings when they are inside of arrays or objects with quotes -// tslint:disable-next-line:no-any -function stringifyWithQuotes(ctx: ConsoleContext, value: any): string { - switch (typeof value) { - case "string": - return `"${value}"`; - default: - return stringify(ctx, value); - } -} - -// tslint:disable-next-line:no-any -export function stringifyArgs(args: any[]): string { - const out: string[] = []; - for (const a of args) { - if (typeof a === "string") { - out.push(a); - } else { - // tslint:disable-next-line:no-any - out.push(stringify(new Set(), a)); - } - } - return out.join(" "); -} - -type PrintFunc = (x: string) => void; - -export class Console { - constructor(private printFunc: PrintFunc) {} - - // tslint:disable-next-line:no-any - log(...args: any[]): void { - this.printFunc(stringifyArgs(args)); - } - - debug = this.log; - info = this.log; - - // tslint:disable-next-line:no-any - warn(...args: any[]): void { - // TODO Log to stderr. - this.printFunc(stringifyArgs(args)); - } - - error = this.warn; - - // tslint:disable-next-line:no-any - assert(condition: boolean, ...args: any[]): void { - if (!condition) { - throw new Error(`Assertion failed: ${stringifyArgs(args)}`); - } - } -} diff --git a/js/console_test.ts b/js/console_test.ts deleted file mode 100644 index 01345825d87aaa..00000000000000 --- a/js/console_test.ts +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. - -import { test, assert, assertEqual } from "./test_util.ts"; -import { stringifyArgs } from "./console.ts"; - -// tslint:disable-next-line:no-any -function stringify(...args: any[]): string { - return stringifyArgs(args); -} - -test(function consoleTestAssert() { - console.assert(true); - - let hasThrown = false; - try { - console.assert(false); - } catch { - hasThrown = true; - } - assertEqual(hasThrown, true); -}); - -test(function consoleTestStringifyComplexObjects() { - assertEqual(stringify("foo"), "foo"); - assertEqual(stringify(["foo", "bar"]), `[ "foo", "bar" ]`); - assertEqual(stringify({ foo: "bar" }), `{ foo: "bar" }`); -}); - -test(function consoleTestStringifyCircular() { - class Base { - a = 1; - m1() {} - } - - class Extended extends Base { - b = 2; - m2() {} - } - - // tslint:disable-next-line:no-any - const nestedObj: any = { - num: 1, - bool: true, - str: "a", - method() {}, - un: undefined, - nu: null, - arrowFunc: () => {}, - extendedClass: new Extended(), - nFunc: new Function(), - extendedCstr: Extended - }; - - const circularObj = { - num: 2, - bool: false, - str: "b", - method() {}, - un: undefined, - nu: null, - nested: nestedObj, - emptyObj: {}, - arr: [1, "s", false, null, nestedObj], - baseClass: new Base() - }; - - nestedObj.o = circularObj; - - const nestedObjExpected = `{ num: 1, bool: true, str: "a", method: [Function: method], un: undefined, nu: null, arrowFunc: [Function: arrowFunc], extendedClass: Extended { a: 1, b: 2 }, nFunc: [Function], extendedCstr: [Function: Extended], o: { num: 2, bool: false, str: "b", method: [Function: method], un: undefined, nu: null, nested: [Circular], emptyObj: {}, arr: [ 1, "s", false, null, [Circular] ], baseClass: Base { a: 1 } } }`; - - assertEqual(stringify(1), "1"); - assertEqual(stringify("s"), "s"); - assertEqual(stringify(false), "false"); - assertEqual(stringify(Symbol(1)), "Symbol(1)"); - assertEqual(stringify(null), "null"); - assertEqual(stringify(undefined), "undefined"); - assertEqual(stringify(new Extended()), "Extended { a: 1, b: 2 }"); - assertEqual(stringify(function f() {}), "[Function: f]"); - assertEqual(stringify(nestedObj), nestedObjExpected); - assertEqual(stringify(JSON), "{}"); - assertEqual( - stringify(console), - "Console { printFunc: [Function], debug: [Function: log], info: [Function: log], error: [Function: warn] }" - ); -}); diff --git a/js/deno.ts b/js/deno.ts deleted file mode 100644 index e24345ccde3fc2..00000000000000 --- a/js/deno.ts +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -// Public deno module. -export { - exit, - FileInfo, - makeTempDirSync, - readFileSync, - statSync, - lStatSync, - writeFileSync -} from "./os"; -export { libdeno } from "./libdeno"; -export const argv: string[] = []; diff --git a/js/errors.ts b/js/errors.ts deleted file mode 100644 index 2fca10eaf95d88..00000000000000 --- a/js/errors.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { deno as fbs } from "gen/msg_generated"; - -export class DenoError extends Error { - constructor(readonly kind: T, msg: string) { - super(msg); - this.name = `deno.${fbs.ErrorKind[kind]}`; - } -} - -export function maybeThrowError(base: fbs.Base): void { - const kind = base.errorKind(); - if (kind !== fbs.ErrorKind.NoError) { - throw new DenoError(kind, base.error()!); - } -} diff --git a/js/fetch.ts b/js/fetch.ts deleted file mode 100644 index 1c733e0669ff51..00000000000000 --- a/js/fetch.ts +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -import { - assert, - log, - createResolvable, - Resolvable, - typedArrayToArrayBuffer, - notImplemented -} from "./util"; -import { flatbuffers } from "flatbuffers"; -import { libdeno } from "./libdeno"; -import { deno as fbs } from "gen/msg_generated"; -import { - Headers, - Request, - Response, - Blob, - RequestInit, - FormData -} from "./fetch_types"; -import { TextDecoder } from "./text_encoding"; - -/** @internal */ -export function onFetchRes(base: fbs.Base, msg: fbs.FetchRes) { - const id = msg.id(); - const req = fetchRequests.get(id); - assert(req != null, `Couldn't find FetchRequest id ${id}`); - req!.onMsg(base, msg); -} - -const fetchRequests = new Map(); - -class DenoHeaders implements Headers { - append(name: string, value: string): void { - assert(false, "Implement me"); - } - delete(name: string): void { - assert(false, "Implement me"); - } - get(name: string): string | null { - assert(false, "Implement me"); - return null; - } - has(name: string): boolean { - assert(false, "Implement me"); - return false; - } - set(name: string, value: string): void { - assert(false, "Implement me"); - } - forEach( - callbackfn: (value: string, key: string, parent: Headers) => void, - // tslint:disable-next-line:no-any - thisArg?: any - ): void { - assert(false, "Implement me"); - } -} - -class FetchResponse implements Response { - readonly url: string; - body: null; - bodyUsed = false; // TODO - status = 0; - statusText = "FIXME"; // TODO - readonly type = "basic"; // TODO - redirected = false; // TODO - headers = new DenoHeaders(); - readonly trailer: Promise; - //private bodyChunks: Uint8Array[] = []; - private first = true; - private bodyWaiter: Resolvable; - - constructor(readonly req: FetchRequest) { - this.url = req.url; - this.bodyWaiter = createResolvable(); - this.trailer = createResolvable(); - } - - arrayBuffer(): Promise { - return this.bodyWaiter; - } - - async blob(): Promise { - notImplemented(); - return {} as Blob; - } - - async formData(): Promise { - notImplemented(); - return {} as FormData; - } - - async json(): Promise { - const text = await this.text(); - return JSON.parse(text); - } - - async text(): Promise { - const ab = await this.arrayBuffer(); - const decoder = new TextDecoder("utf-8"); - return decoder.decode(ab); - } - - get ok(): boolean { - return 200 <= this.status && this.status < 300; - } - - clone(): Response { - notImplemented(); - return {} as Response; - } - - onHeader?: (res: FetchResponse) => void; - onError?: (error: Error) => void; - - onMsg(base: fbs.Base, msg: fbs.FetchRes) { - const error = base.error(); - if (error != null) { - assert(this.onError != null); - this.onError!(new Error(error)); - return; - } - - if (this.first) { - this.first = false; - this.status = msg.status(); - assert(this.onHeader != null); - this.onHeader!(this); - } else { - // Body message. Assuming it all comes in one message now. - const bodyArray = msg.bodyArray(); - assert(bodyArray != null); - const ab = typedArrayToArrayBuffer(bodyArray!); - this.bodyWaiter.resolve(ab); - } - } -} - -let nextFetchId = 0; -//TODO implements Request -class FetchRequest { - private readonly id: number; - response: FetchResponse; - constructor(readonly url: string) { - this.id = nextFetchId++; - fetchRequests.set(this.id, this); - this.response = new FetchResponse(this); - } - - onMsg(base: fbs.Base, msg: fbs.FetchRes) { - this.response.onMsg(base, msg); - } - - destroy() { - fetchRequests.delete(this.id); - } - - start() { - log("dispatch FETCH_REQ", this.id, this.url); - - // Send FetchReq message - const builder = new flatbuffers.Builder(); - const url = builder.createString(this.url); - fbs.FetchReq.startFetchReq(builder); - fbs.FetchReq.addId(builder, this.id); - fbs.FetchReq.addUrl(builder, url); - const msg = fbs.FetchReq.endFetchReq(builder); - fbs.Base.startBase(builder); - fbs.Base.addMsg(builder, msg); - fbs.Base.addMsgType(builder, fbs.Any.FetchReq); - builder.finish(fbs.Base.endBase(builder)); - const resBuf = libdeno.send(builder.asUint8Array()); - assert(resBuf == null); - - //console.log("FetchReq sent", builder); - } -} - -export function fetch( - input?: Request | string, - init?: RequestInit -): Promise { - const fetchReq = new FetchRequest(input as string); - const response = fetchReq.response; - return new Promise((resolve, reject) => { - response.onHeader = (response: FetchResponse) => { - log("onHeader"); - resolve(response); - }; - response.onError = (error: Error) => { - log("onError", error); - reject(error); - }; - fetchReq.start(); - }); -} diff --git a/js/fetch_types.d.ts b/js/fetch_types.d.ts deleted file mode 100644 index ebe2c70be34e7f..00000000000000 --- a/js/fetch_types.d.ts +++ /dev/null @@ -1,452 +0,0 @@ -/*! **************************************************************************** -Copyright (c) Microsoft Corporation. All rights reserved. -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 - -THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF -ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED -WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, -MERCHANTABLITY OR NON-INFRINGEMENT. - -See the Apache Version 2.0 License for specific language governing permissions -and limitations under the License. -*******************************************************************************/ - -type HeadersInit = Headers | string[][] | Record; -type BodyInit = - | Blob - | BufferSource - | FormData - | URLSearchParams - | ReadableStream - | string; -type RequestInfo = Request | string; -type ReferrerPolicy = - | "" - | "no-referrer" - | "no-referrer-when-downgrade" - | "origin-only" - | "origin-when-cross-origin" - | "unsafe-url"; -type BlobPart = BufferSource | Blob | string; -type FormDataEntryValue = File | string; -declare type EventListenerOrEventListenerObject = - | EventListener - | EventListenerObject; - -interface Element { - // TODO -} - -interface HTMLFormElement { - // TODO -} - -interface BlobPropertyBag { - type?: string; -} - -interface AbortSignalEventMap { - abort: ProgressEvent; -} - -interface EventTarget { - addEventListener( - type: string, - listener: EventListenerOrEventListenerObject | null, - options?: boolean | AddEventListenerOptions - ): void; - dispatchEvent(evt: Event): boolean; - removeEventListener( - type: string, - listener?: EventListenerOrEventListenerObject | null, - options?: EventListenerOptions | boolean - ): void; -} - -interface ProgressEventInit extends EventInit { - lengthComputable?: boolean; - loaded?: number; - total?: number; -} - -interface URLSearchParams { - /** - * Appends a specified key/value pair as a new search parameter. - */ - append(name: string, value: string): void; - /** - * Deletes the given search parameter, and its associated value, from the list of all search parameters. - */ - delete(name: string): void; - /** - * Returns the first value associated to the given search parameter. - */ - get(name: string): string | null; - /** - * Returns all the values association with a given search parameter. - */ - getAll(name: string): string[]; - /** - * Returns a Boolean indicating if such a search parameter exists. - */ - has(name: string): boolean; - /** - * Sets the value associated to a given search parameter to the given value. If there were several values, delete the others. - */ - set(name: string, value: string): void; - sort(): void; - forEach( - callbackfn: (value: string, key: string, parent: URLSearchParams) => void, - thisArg?: any - ): void; -} - -interface EventListener { - (evt: Event): void; -} - -interface EventInit { - bubbles?: boolean; - cancelable?: boolean; - composed?: boolean; -} - -interface Event { - readonly bubbles: boolean; - cancelBubble: boolean; - readonly cancelable: boolean; - readonly composed: boolean; - readonly currentTarget: EventTarget | null; - readonly defaultPrevented: boolean; - readonly eventPhase: number; - readonly isTrusted: boolean; - returnValue: boolean; - readonly srcElement: Element | null; - readonly target: EventTarget | null; - readonly timeStamp: number; - readonly type: string; - deepPath(): EventTarget[]; - initEvent(type: string, bubbles?: boolean, cancelable?: boolean): void; - preventDefault(): void; - stopImmediatePropagation(): void; - stopPropagation(): void; - readonly AT_TARGET: number; - readonly BUBBLING_PHASE: number; - readonly CAPTURING_PHASE: number; - readonly NONE: number; -} - -interface File extends Blob { - readonly lastModified: number; - readonly name: string; -} - -declare var File: { - prototype: File; - new(fileBits: BlobPart[], fileName: string, options?: FilePropertyBag): File; -}; - -interface FilePropertyBag extends BlobPropertyBag { - lastModified?: number; -} - -interface ProgressEvent extends Event { - readonly lengthComputable: boolean; - readonly loaded: number; - readonly total: number; -} - -declare var ProgressEvent: { - prototype: ProgressEvent; - new (type: string, eventInitDict?: ProgressEventInit): ProgressEvent; -}; - -interface EventListenerOptions { - capture?: boolean; -} - -interface AddEventListenerOptions extends EventListenerOptions { - once?: boolean; - passive?: boolean; -} - -interface AbortSignal extends EventTarget { - readonly aborted: boolean; - onabort: ((this: AbortSignal, ev: ProgressEvent) => any) | null; - addEventListener( - type: K, - listener: (this: AbortSignal, ev: AbortSignalEventMap[K]) => any, - options?: boolean | AddEventListenerOptions - ): void; - addEventListener( - type: string, - listener: EventListenerOrEventListenerObject, - options?: boolean | AddEventListenerOptions - ): void; - removeEventListener( - type: K, - listener: (this: AbortSignal, ev: AbortSignalEventMap[K]) => any, - options?: boolean | EventListenerOptions - ): void; - removeEventListener( - type: string, - listener: EventListenerOrEventListenerObject, - options?: boolean | EventListenerOptions - ): void; -} - -declare var AbortSignal: { - prototype: AbortSignal; - new (): AbortSignal; -}; - -interface ReadableStream { - readonly locked: boolean; - cancel(): Promise; - getReader(): ReadableStreamReader; -} - -declare var ReadableStream: { - prototype: ReadableStream; - new (): ReadableStream; -}; - -interface EventListenerObject { - handleEvent(evt: Event): void; -} - -interface ReadableStreamReader { - cancel(): Promise; - read(): Promise; - releaseLock(): void; -} - -declare var ReadableStreamReader: { - prototype: ReadableStreamReader; - new (): ReadableStreamReader; -}; - -interface FormData { - append(name: string, value: string | Blob, fileName?: string): void; - delete(name: string): void; - get(name: string): FormDataEntryValue | null; - getAll(name: string): FormDataEntryValue[]; - has(name: string): boolean; - set(name: string, value: string | Blob, fileName?: string): void; - forEach( - callbackfn: ( - value: FormDataEntryValue, - key: string, - parent: FormData - ) => void, - thisArg?: any - ): void; -} - -declare var FormData: { - prototype: FormData; - new (form?: HTMLFormElement): FormData; -}; - -export interface Blob { - readonly size: number; - readonly type: string; - slice(start?: number, end?: number, contentType?: string): Blob; -} - -declare var Blob: { - prototype: Blob; - new (blobParts?: BlobPart[], options?: BlobPropertyBag): Blob; -}; - -interface Body { - readonly body: ReadableStream | null; - readonly bodyUsed: boolean; - arrayBuffer(): Promise; - blob(): Promise; - formData(): Promise; - json(): Promise; - text(): Promise; -} - -interface Headers { - append(name: string, value: string): void; - delete(name: string): void; - get(name: string): string | null; - has(name: string): boolean; - set(name: string, value: string): void; - forEach( - callbackfn: (value: string, key: string, parent: Headers) => void, - thisArg?: any - ): void; -} - -declare var Headers: { - prototype: Headers; - new (init?: HeadersInit): Headers; -}; - -type RequestCache = - | "default" - | "no-store" - | "reload" - | "no-cache" - | "force-cache" - | "only-if-cached"; -type RequestCredentials = "omit" | "same-origin" | "include"; -type RequestDestination = - | "" - | "audio" - | "audioworklet" - | "document" - | "embed" - | "font" - | "image" - | "manifest" - | "object" - | "paintworklet" - | "report" - | "script" - | "sharedworker" - | "style" - | "track" - | "video" - | "worker" - | "xslt"; -type RequestMode = "navigate" | "same-origin" | "no-cors" | "cors"; -type RequestRedirect = "follow" | "error" | "manual"; -type ResponseType = - | "basic" - | "cors" - | "default" - | "error" - | "opaque" - | "opaqueredirect"; - -export interface RequestInit { - body?: BodyInit | null; - cache?: RequestCache; - credentials?: RequestCredentials; - headers?: HeadersInit; - integrity?: string; - keepalive?: boolean; - method?: string; - mode?: RequestMode; - redirect?: RequestRedirect; - referrer?: string; - referrerPolicy?: ReferrerPolicy; - signal?: AbortSignal | null; - window?: any; -} - -export interface ResponseInit { - headers?: HeadersInit; - status?: number; - statusText?: string; -} - -export interface Request extends Body { - /** - * Returns the cache mode associated with request, which is a string indicating - * how the the request will interact with the browser's cache when fetching. - */ - readonly cache: RequestCache; - /** - * Returns the credentials mode associated with request, which is a string - * indicating whether credentials will be sent with the request always, never, or only when sent to a - * same-origin URL. - */ - readonly credentials: RequestCredentials; - /** - * Returns the kind of resource requested by request, e.g., "document" or - * "script". - */ - readonly destination: RequestDestination; - /** - * Returns a Headers object consisting of the headers associated with request. - * Note that headers added in the network layer by the user agent will not be accounted for in this - * object, e.g., the "Host" header. - */ - readonly headers: Headers; - /** - * Returns request's subresource integrity metadata, which is a cryptographic hash of - * the resource being fetched. Its value consists of multiple hashes separated by whitespace. [SRI] - */ - readonly integrity: string; - /** - * Returns a boolean indicating whether or not request is for a history - * navigation (a.k.a. back-foward navigation). - */ - readonly isHistoryNavigation: boolean; - /** - * Returns a boolean indicating whether or not request is for a reload navigation. - */ - readonly isReloadNavigation: boolean; - /** - * Returns a boolean indicating whether or not request can outlive the global in which - * it was created. - */ - readonly keepalive: boolean; - /** - * Returns request's HTTP method, which is "GET" by default. - */ - readonly method: string; - /** - * Returns the mode associated with request, which is a string indicating - * whether the request will use CORS, or will be restricted to same-origin URLs. - */ - readonly mode: RequestMode; - /** - * Returns the redirect mode associated with request, which is a string - * indicating how redirects for the request will be handled during fetching. A request will follow redirects by default. - */ - readonly redirect: RequestRedirect; - /** - * Returns the referrer of request. Its value can be a same-origin URL if - * explicitly set in init, the empty string to indicate no referrer, and - * "about:client" when defaulting to the global's default. This is used during - * fetching to determine the value of the `Referer` header of the request being made. - */ - readonly referrer: string; - /** - * Returns the referrer policy associated with request. This is used during - * fetching to compute the value of the request's referrer. - */ - readonly referrerPolicy: ReferrerPolicy; - /** - * Returns the signal associated with request, which is an AbortSignal object indicating whether or not request has been aborted, and its abort - * event handler. - */ - readonly signal: AbortSignal; - /** - * Returns the URL of request as a string. - */ - readonly url: string; - clone(): Request; -} - -declare var Request: { - prototype: Request; - new (input: RequestInfo, init?: RequestInit): Request; -}; - -export interface Response extends Body { - readonly headers: Headers; - readonly ok: boolean; - readonly redirected: boolean; - readonly status: number; - readonly statusText: string; - readonly trailer: Promise; - readonly type: ResponseType; - readonly url: string; - clone(): Response; -} - -declare var Response: { - prototype: Response; - new (body?: BodyInit | null, init?: ResponseInit): Response; - error(): Response; - redirect(url: string, status?: number): Response; -}; diff --git a/js/global-eval.ts b/js/global-eval.ts deleted file mode 100644 index ee37e6f2497f52..00000000000000 --- a/js/global-eval.ts +++ /dev/null @@ -1,6 +0,0 @@ -// If you use the eval function indirectly, by invoking it via a reference -// other than eval, as of ECMAScript 5 it works in the global scope rather than -// the local scope. This means, for instance, that function declarations create -// global functions, and that the code being evaluated doesn't have access to -// local variables within the scope where it's being called. -export const globalEval = eval; diff --git a/js/globals.ts b/js/globals.ts deleted file mode 100644 index 0364aaf986a181..00000000000000 --- a/js/globals.ts +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. - -import { Console } from "./console"; -import * as timers from "./timers"; -import { TextDecoder, TextEncoder } from "./text_encoding"; -import * as fetch_ from "./fetch"; -import { libdeno } from "./libdeno"; -import { globalEval } from "./global-eval"; - -declare global { - interface Window { - console: Console; - define: Readonly; - } - - const clearTimeout: typeof timers.clearTimer; - const clearInterval: typeof timers.clearTimer; - const setTimeout: typeof timers.setTimeout; - const setInterval: typeof timers.setInterval; - - const console: Console; - const window: Window; - - const fetch: typeof fetch_.fetch; - - // tslint:disable:variable-name - let TextEncoder: TextEncoder; - let TextDecoder: TextDecoder; - // tslint:enable:variable-name -} - -// A reference to the global object. -export const window = globalEval("this"); -window.window = window; - -window.libdeno = null; - -window.setTimeout = timers.setTimeout; -window.setInterval = timers.setInterval; -window.clearTimeout = timers.clearTimer; -window.clearInterval = timers.clearTimer; - -window.console = new Console(libdeno.print); -window.TextEncoder = TextEncoder; -window.TextDecoder = TextDecoder; - -window.fetch = fetch_.fetch; diff --git a/js/lib.globals.d.ts b/js/lib.globals.d.ts deleted file mode 100644 index a1526c573c2696..00000000000000 --- a/js/lib.globals.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -// This file contains the default TypeScript libraries for the deno runtime. -/// -/// -import "gen/js/globals"; diff --git a/js/libdeno.ts b/js/libdeno.ts deleted file mode 100644 index 142d779c2b8dce..00000000000000 --- a/js/libdeno.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { RawSourceMap } from "./types"; -import { globalEval } from "./global-eval"; - -// The libdeno functions are moved so that users can't access them. -type MessageCallback = (msg: Uint8Array) => void; -interface Libdeno { - recv(cb: MessageCallback): void; - - send(msg: ArrayBufferView): null | Uint8Array; - - print(x: string): void; - - setGlobalErrorHandler: ( - handler: ( - message: string, - source: string, - line: number, - col: number, - error: Error - ) => void - ) => void; - - mainSource: string; - mainSourceMap: RawSourceMap; -} - -const window = globalEval("this"); -export const libdeno = window.libdeno as Libdeno; diff --git a/js/main.ts b/js/main.ts deleted file mode 100644 index 133c477857e665..00000000000000 --- a/js/main.ts +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -import { flatbuffers } from "flatbuffers"; -import { deno as fbs } from "gen/msg_generated"; -import { assert, assignCmdId, log, setLogDebug } from "./util"; -import * as os from "./os"; -import { DenoCompiler } from "./compiler"; -import { libdeno } from "./libdeno"; -import * as timers from "./timers"; -import { onFetchRes } from "./fetch"; -import { argv } from "./deno"; - -function startMsg(cmdId: number): Uint8Array { - const builder = new flatbuffers.Builder(); - fbs.Start.startStart(builder); - const startOffset = fbs.Start.endStart(builder); - fbs.Base.startBase(builder); - fbs.Base.addCmdId(builder, cmdId); - fbs.Base.addMsg(builder, startOffset); - fbs.Base.addMsgType(builder, fbs.Any.Start); - builder.finish(fbs.Base.endBase(builder)); - return builder.asUint8Array(); -} - -function onMessage(ui8: Uint8Array) { - const bb = new flatbuffers.ByteBuffer(ui8); - const base = fbs.Base.getRootAsBase(bb); - switch (base.msgType()) { - case fbs.Any.FetchRes: { - const msg = new fbs.FetchRes(); - assert(base.msg(msg) != null); - onFetchRes(base, msg); - break; - } - case fbs.Any.TimerReady: { - const msg = new fbs.TimerReady(); - assert(base.msg(msg) != null); - timers.onMessage(msg); - break; - } - default: { - assert(false, "Unhandled message type"); - break; - } - } -} - -function onGlobalError( - message: string, - source: string, - lineno: number, - colno: number, - error: Error -) { - console.log(error.stack); - os.exit(1); -} - -/* tslint:disable-next-line:no-default-export */ -export default function denoMain() { - libdeno.recv(onMessage); - libdeno.setGlobalErrorHandler(onGlobalError); - const compiler = DenoCompiler.instance(); - - // First we send an empty "Start" message to let the privlaged side know we - // are ready. The response should be a "StartRes" message containing the CLI - // argv and other info. - const cmdId = assignCmdId(); - const res = libdeno.send(startMsg(cmdId)); - - // TODO(ry) Remove this conditional once main.rs gets up to speed. - if (res == null) { - console.log(`The 'Start' message got a null response. Normally this would - be an error but main.rs currently does this."); Exiting without error.`); - return; - } - - // Deserialize res into startResMsg. - const bb = new flatbuffers.ByteBuffer(res); - const base = fbs.Base.getRootAsBase(bb); - assert(fbs.Any.StartRes === base.msgType()); - const startResMsg = new fbs.StartRes(); - assert(base.msg(startResMsg) != null); - - setLogDebug(startResMsg.debugFlag()); - - const cwd = startResMsg.cwd(); - log("cwd", cwd); - - // TODO handle shebang. - for (let i = 1; i < startResMsg.argvLength(); i++) { - argv.push(startResMsg.argv(i)); - } - log("argv", argv); - Object.freeze(argv); - - const inputFn = argv[0]; - if (!inputFn) { - console.log("No input script specified."); - os.exit(1); - } - - compiler.run(inputFn, `${cwd}/`); -} diff --git a/js/mock_builtin.js b/js/mock_builtin.js deleted file mode 100644 index f237ddf58ed4ff..00000000000000 --- a/js/mock_builtin.js +++ /dev/null @@ -1 +0,0 @@ -export default undefined; diff --git a/js/os.ts b/js/os.ts deleted file mode 100644 index f0f8897cc7ee5b..00000000000000 --- a/js/os.ts +++ /dev/null @@ -1,278 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -import { ModuleInfo } from "./types"; -import { deno as fbs } from "gen/msg_generated"; -import { assert } from "./util"; -import * as util from "./util"; -import { maybeThrowError } from "./errors"; -import { flatbuffers } from "flatbuffers"; -import { libdeno } from "./libdeno"; - -export function exit(exitCode = 0): never { - const builder = new flatbuffers.Builder(); - fbs.Exit.startExit(builder); - fbs.Exit.addCode(builder, exitCode); - const msg = fbs.Exit.endExit(builder); - fbs.Base.startBase(builder); - fbs.Base.addMsg(builder, msg); - fbs.Base.addMsgType(builder, fbs.Any.Exit); - builder.finish(fbs.Base.endBase(builder)); - libdeno.send(builder.asUint8Array()); - return util.unreachable(); -} - -export function codeFetch( - moduleSpecifier: string, - containingFile: string -): ModuleInfo { - util.log("os.ts codeFetch", moduleSpecifier, containingFile); - // Send CodeFetch message - const builder = new flatbuffers.Builder(); - const moduleSpecifier_ = builder.createString(moduleSpecifier); - const containingFile_ = builder.createString(containingFile); - fbs.CodeFetch.startCodeFetch(builder); - fbs.CodeFetch.addModuleSpecifier(builder, moduleSpecifier_); - fbs.CodeFetch.addContainingFile(builder, containingFile_); - const msg = fbs.CodeFetch.endCodeFetch(builder); - fbs.Base.startBase(builder); - fbs.Base.addMsg(builder, msg); - fbs.Base.addMsgType(builder, fbs.Any.CodeFetch); - builder.finish(fbs.Base.endBase(builder)); - const resBuf = libdeno.send(builder.asUint8Array()); - assert(resBuf != null); - // Process CodeFetchRes - // TypeScript does not track `assert` from a CFA perspective, therefore not - // null assertion `!` - const bb = new flatbuffers.ByteBuffer(new Uint8Array(resBuf!)); - const baseRes = fbs.Base.getRootAsBase(bb); - maybeThrowError(baseRes); - assert(fbs.Any.CodeFetchRes === baseRes.msgType()); - const codeFetchRes = new fbs.CodeFetchRes(); - assert(baseRes.msg(codeFetchRes) != null); - const r = { - moduleName: codeFetchRes.moduleName(), - filename: codeFetchRes.filename(), - sourceCode: codeFetchRes.sourceCode(), - outputCode: codeFetchRes.outputCode() - }; - return r; -} - -export function codeCache( - filename: string, - sourceCode: string, - outputCode: string -): void { - util.log("os.ts codeCache", filename, sourceCode, outputCode); - const builder = new flatbuffers.Builder(); - const filename_ = builder.createString(filename); - const sourceCode_ = builder.createString(sourceCode); - const outputCode_ = builder.createString(outputCode); - fbs.CodeCache.startCodeCache(builder); - fbs.CodeCache.addFilename(builder, filename_); - fbs.CodeCache.addSourceCode(builder, sourceCode_); - fbs.CodeCache.addOutputCode(builder, outputCode_); - const msg = fbs.CodeCache.endCodeCache(builder); - fbs.Base.startBase(builder); - fbs.Base.addMsg(builder, msg); - fbs.Base.addMsgType(builder, fbs.Any.CodeCache); - builder.finish(fbs.Base.endBase(builder)); - const resBuf = libdeno.send(builder.asUint8Array()); - // Expect null or error. - if (resBuf != null) { - const bb = new flatbuffers.ByteBuffer(new Uint8Array(resBuf)); - const baseRes = fbs.Base.getRootAsBase(bb); - maybeThrowError(baseRes); - } -} - -/** - * makeTempDirSync creates a new temporary directory in the directory `dir`, its - * name beginning with `prefix` and ending with `suffix`. - * It returns the full path to the newly created directory. - * If `dir` is unspecified, tempDir uses the default directory for temporary - * files. Multiple programs calling tempDir simultaneously will not choose the - * same directory. It is the caller's responsibility to remove the directory - * when no longer needed. - */ -export interface MakeTempDirOptions { - dir?: string; - prefix?: string; - suffix?: string; -} -export function makeTempDirSync({ - dir, - prefix, - suffix -}: MakeTempDirOptions = {}): string { - const builder = new flatbuffers.Builder(); - const fbDir = dir == null ? -1 : builder.createString(dir); - const fbPrefix = prefix == null ? -1 : builder.createString(prefix); - const fbSuffix = suffix == null ? -1 : builder.createString(suffix); - fbs.MakeTempDir.startMakeTempDir(builder); - if (dir != null) { - fbs.MakeTempDir.addDir(builder, fbDir); - } - if (prefix != null) { - fbs.MakeTempDir.addPrefix(builder, fbPrefix); - } - if (suffix != null) { - fbs.MakeTempDir.addSuffix(builder, fbSuffix); - } - const msg = fbs.MakeTempDir.endMakeTempDir(builder); - fbs.Base.startBase(builder); - fbs.Base.addMsg(builder, msg); - fbs.Base.addMsgType(builder, fbs.Any.MakeTempDir); - builder.finish(fbs.Base.endBase(builder)); - const resBuf = libdeno.send(builder.asUint8Array()); - assert(resBuf != null); - const bb = new flatbuffers.ByteBuffer(new Uint8Array(resBuf!)); - const baseRes = fbs.Base.getRootAsBase(bb); - maybeThrowError(baseRes); - assert(fbs.Any.MakeTempDirRes === baseRes.msgType()); - const res = new fbs.MakeTempDirRes(); - assert(baseRes.msg(res) != null); - const path = res.path(); - assert(path != null); - return path!; -} - -export function readFileSync(filename: string): Uint8Array { - /* Ideally we could write - const res = send({ - command: fbs.Command.READ_FILE_SYNC, - readFileSyncFilename: filename - }); - return res.readFileSyncData; - */ - const builder = new flatbuffers.Builder(); - const filename_ = builder.createString(filename); - fbs.ReadFileSync.startReadFileSync(builder); - fbs.ReadFileSync.addFilename(builder, filename_); - const msg = fbs.ReadFileSync.endReadFileSync(builder); - fbs.Base.startBase(builder); - fbs.Base.addMsg(builder, msg); - fbs.Base.addMsgType(builder, fbs.Any.ReadFileSync); - builder.finish(fbs.Base.endBase(builder)); - const resBuf = libdeno.send(builder.asUint8Array()); - assert(resBuf != null); - // TypeScript does not track `assert` from a CFA perspective, therefore not - // null assertion `!` - const bb = new flatbuffers.ByteBuffer(new Uint8Array(resBuf!)); - const baseRes = fbs.Base.getRootAsBase(bb); - maybeThrowError(baseRes); - assert(fbs.Any.ReadFileSyncRes === baseRes.msgType()); - const res = new fbs.ReadFileSyncRes(); - assert(baseRes.msg(res) != null); - const dataArray = res.dataArray(); - assert(dataArray != null); - // TypeScript cannot track assertion above, therefore not null assertion - return new Uint8Array(dataArray!); -} - -export class FileInfo { - private _isFile: boolean; - private _isSymlink: boolean; - len: number; - modified: number; - accessed: number; - // Creation time is not available on all platforms. - created: number | null; - - /* @internal */ - constructor(private _msg: fbs.StatSyncRes) { - const created = this._msg.created().toFloat64(); - - this._isFile = this._msg.isFile(); - this._isSymlink = this._msg.isSymlink(); - this.len = this._msg.len().toFloat64(); - this.modified = this._msg.modified().toFloat64(); - this.accessed = this._msg.accessed().toFloat64(); - this.created = created ? created: null; - } - - isFile() { - return this._isFile; - } - - isDirectory() { - return !this._isFile && !this._isSymlink; - } - - isSymlink() { - return this._isSymlink; - } -} - -export function lStatSync(filename: string): FileInfo { - return statSyncInner(filename, true); -} - -export function statSync(filename: string): FileInfo { - return statSyncInner(filename, false); -} - -function statSyncInner(filename: string, lstat: boolean): FileInfo { - /* Ideally we could write - const res = send({ - command: fbs.Command.STAT_FILE_SYNC, - StatFilename: filename, - StatLStat: lstat, - }); - return new FileInfo(res); - */ - const builder = new flatbuffers.Builder(); - const filename_ = builder.createString(filename); - fbs.StatSync.startStatSync(builder); - fbs.StatSync.addFilename(builder, filename_); - fbs.StatSync.addLstat(builder, lstat); - const msg = fbs.StatSync.endStatSync(builder); - fbs.Base.startBase(builder); - fbs.Base.addMsg(builder, msg); - fbs.Base.addMsgType(builder, fbs.Any.StatSync); - builder.finish(fbs.Base.endBase(builder)); - const resBuf = libdeno.send(builder.asUint8Array()); - assert(resBuf != null); - // TypeScript does not track `assert` from a CFA perspective, therefore not - // null assertion `!` - const bb = new flatbuffers.ByteBuffer(new Uint8Array(resBuf!)); - const baseRes = fbs.Base.getRootAsBase(bb); - maybeThrowError(baseRes); - assert(fbs.Any.StatSyncRes === baseRes.msgType()); - const res = new fbs.StatSyncRes(); - assert(baseRes.msg(res) != null); - // TypeScript cannot track assertion above, therefore not null assertion - return new FileInfo(baseRes.msg(res)!); -} - -export function writeFileSync( - filename: string, - data: Uint8Array, - perm = 0o666 -): void { - /* Ideally we could write: - const res = send({ - command: fbs.Command.WRITE_FILE_SYNC, - writeFileSyncFilename: filename, - writeFileSyncData: data, - writeFileSyncPerm: perm - }); - */ - const builder = new flatbuffers.Builder(); - const filename_ = builder.createString(filename); - const dataOffset = fbs.WriteFileSync.createDataVector(builder, data); - fbs.WriteFileSync.startWriteFileSync(builder); - fbs.WriteFileSync.addFilename(builder, filename_); - fbs.WriteFileSync.addData(builder, dataOffset); - fbs.WriteFileSync.addPerm(builder, perm); - const msg = fbs.WriteFileSync.endWriteFileSync(builder); - fbs.Base.startBase(builder); - fbs.Base.addMsg(builder, msg); - fbs.Base.addMsgType(builder, fbs.Any.WriteFileSync); - builder.finish(fbs.Base.endBase(builder)); - const resBuf = libdeno.send(builder.asUint8Array()); - if (resBuf != null) { - const bb = new flatbuffers.ByteBuffer(new Uint8Array(resBuf!)); - const baseRes = fbs.Base.getRootAsBase(bb); - maybeThrowError(baseRes); - } -} diff --git a/js/plugins.d.ts b/js/plugins.d.ts deleted file mode 100644 index d1dae38852e88d..00000000000000 --- a/js/plugins.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -// This allows TypeScript to resolve any modules that end with `!string` -// as there is a rollup plugin that will take any mids ending with `!string` -// and return them as a string to rollup for inlining -declare module "*!string" { - const value: string; - export default value; -} diff --git a/js/test_util.ts b/js/test_util.ts deleted file mode 100644 index 116b96ff2e0fe0..00000000000000 --- a/js/test_util.ts +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -// -// We want to test many ops in deno which have different behavior depending on -// the permissions set. These tests can specify which permissions they expect, -// which appends a special string like "permW1N0" to the end of the test name. -// Here we run several copies of deno with different permissions, filtering the -// tests by the special string. permW0N0 means allow-write but not allow-net. -// See tools/unit_tests.py for more details. - -import * as deno from "deno"; -import * as testing from "./testing/testing.ts"; -export { assert, assertEqual } from "./testing/testing.ts"; - -// testing.setFilter must be run before any tests are defined. -testing.setFilter(deno.argv[1]); - -interface DenoPermissions { - write?: boolean; - net?: boolean; -} - -function permToString(perms: DenoPermissions): string { - const w = perms.write ? 1 : 0; - const n = perms.net ? 1 : 0; - return `permW${w}N${n}`; -} - -function permFromString(s: string): DenoPermissions { - const re = /^permW([01])N([01])$/; - const found = s.match(re); - if (!found) { - throw Error("Not a permission string"); - } - return { - write: Boolean(Number(found[1])), - net: Boolean(Number(found[2])) - }; -} - -export function testPerm(perms: DenoPermissions, fn: testing.TestFunction) { - const name = `${fn.name}_${permToString(perms)}`; - testing.test({ fn, name }); -} - -export function test(fn: testing.TestFunction) { - testPerm({ write: false, net: false }, fn); -} - -test(function permSerialization() { - for (let write of [true, false]) { - for (let net of [true, false]) { - let perms: DenoPermissions = { write, net }; - testing.assertEqual(perms, permFromString(permToString(perms))); - } - } -}); - -// To better catch internal errors, permFromString should throw if it gets an -// invalid permission string. -test(function permFromStringThrows() { - let threw = false; - try { - permFromString("bad"); - } catch (e) { - threw = true; - } - testing.assert(threw); -}); diff --git a/js/testing/testing.ts b/js/testing/testing.ts deleted file mode 100644 index b172688b7bd556..00000000000000 --- a/js/testing/testing.ts +++ /dev/null @@ -1,88 +0,0 @@ -/*! - Copyright 2018 Propel http://propel.site/. All rights reserved. - 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. -*/ - -export { assert, assertEqual, equal } from "./util.ts"; - -export type TestFunction = () => void | Promise; - -export interface TestDefinition { - fn: TestFunction; - name: string; -} - -export const exitOnFail = true; - -let filterRegExp: RegExp | null; -const tests: TestDefinition[] = []; - -// Must be called before any test() that needs to be filtered. -export function setFilter(s: string): void { - filterRegExp = new RegExp(s, "i"); -} - -export function test(t: TestDefinition | TestFunction): void { - const fn: TestFunction = typeof t === "function" ? t : t.fn; - const name: string = t.name; - - if (!name) { - throw new Error("Test function may not be anonymous"); - } - if (filter(name)) { - tests.push({ fn, name }); - } -} - -function filter(name: string): boolean { - if (filterRegExp) { - return filterRegExp.test(name); - } else { - return true; - } -} - -async function runTests() { - let passed = 0; - let failed = 0; - - for (let i = 0; i < tests.length; i++) { - const { fn, name } = tests[i]; - console.log(`${i + 1}/${tests.length} +${passed} -${failed}: ${name}`); - try { - await fn(); - passed++; - } catch (e) { - console.error("\nTest FAIL", name); - console.error((e && e.stack) || e); - failed++; - if (exitOnFail) { - break; - } - } - } - - console.log(`\nDONE. Test passed: ${passed}, failed: ${failed}`); - - if (failed === 0) { - // All good. - } else { - // Use setTimeout to avoid the error being ignored due to unhandled - // promise rejections being swallowed. - setTimeout(() => { - throw new Error(`There were ${failed} test failures.`); - }, 0); - } -} - -setTimeout(runTests, 0); diff --git a/js/testing/util.ts b/js/testing/util.ts deleted file mode 100644 index 1935403516c958..00000000000000 --- a/js/testing/util.ts +++ /dev/null @@ -1,64 +0,0 @@ -/*! - Copyright 2018 Propel http://propel.site/. All rights reserved. - 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. - */ - -// TODO(ry) Use unknown here for parameters types. -// tslint:disable-next-line:no-any -export function assertEqual(actual: any, expected: any, msg?: string) { - if (!msg) { - msg = `actual: ${actual} expected: ${expected}`; - } - if (!equal(actual, expected)) { - console.error( - "assertEqual failed. actual = ", - actual, - "expected =", - expected - ); - throw new Error(msg); - } -} - -export function assert(expr: boolean, msg = "") { - if (!expr) { - throw new Error(msg); - } -} - -// TODO(ry) Use unknown here for parameters types. -// tslint:disable-next-line:no-any -export function equal(c: any, d: any): boolean { - const seen = new Map(); - return (function compare(a, b) { - if (Object.is(a, b)) { - return true; - } - if (a && typeof a === "object" && b && typeof b === "object") { - if (seen.get(a) === b) { - return true; - } - if (Object.keys(a).length !== Object.keys(b).length) { - return false; - } - for (const key in { ...a, ...b }) { - if (!compare(a[key], b[key])) { - return false; - } - } - seen.set(a, b); - return true; - } - return false; - })(c, d); -} diff --git a/js/testing/util_test.ts b/js/testing/util_test.ts deleted file mode 100644 index 9ac3dfd71b3d3e..00000000000000 --- a/js/testing/util_test.ts +++ /dev/null @@ -1,40 +0,0 @@ -/*! - Copyright 2018 Propel http://propel.site/. All rights reserved. - 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. - */ - -import { test } from "./testing.ts"; -import { assert } from "./util.ts"; -import * as util from "./util.ts"; - -test(async function util_equal() { - assert(util.equal("world", "world")); - assert(!util.equal("hello", "world")); - assert(util.equal(5, 5)); - assert(!util.equal(5, 6)); - assert(util.equal(NaN, NaN)); - assert(util.equal({ hello: "world" }, { hello: "world" })); - assert(!util.equal({ world: "hello" }, { hello: "world" })); - assert( - util.equal( - { hello: "world", hi: { there: "everyone" } }, - { hello: "world", hi: { there: "everyone" } } - ) - ); - assert( - !util.equal( - { hello: "world", hi: { there: "everyone" } }, - { hello: "world", hi: { there: "everyone else" } } - ) - ); -}); diff --git a/js/text_encoding.ts b/js/text_encoding.ts deleted file mode 100644 index c8e262f5e9c0ad..00000000000000 --- a/js/text_encoding.ts +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. - -// @types/text-encoding relies on lib.dom.d.ts for some interfaces. We do not -// want to include lib.dom.d.ts (due to size) into deno's global type scope. -// Therefore this hack: add a few of the missing interfaces in -// @types/text-encoding to the global scope before importing. - -declare global { - type BufferSource = ArrayBufferView | ArrayBuffer; - - interface TextDecodeOptions { - stream?: boolean; - } - - interface TextDecoderOptions { - fatal?: boolean; - ignoreBOM?: boolean; - } - - interface TextDecoder { - readonly encoding: string; - readonly fatal: boolean; - readonly ignoreBOM: boolean; - decode(input?: BufferSource, options?: TextDecodeOptions): string; - } -} - -export { TextEncoder, TextDecoder } from "text-encoding"; diff --git a/js/timers.ts b/js/timers.ts deleted file mode 100644 index 43bd199b1a7c89..00000000000000 --- a/js/timers.ts +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -import { assert } from "./util"; -import * as util from "./util"; -import { deno as fbs } from "gen/msg_generated"; -import { flatbuffers } from "flatbuffers"; -import { libdeno } from "./libdeno"; - -let nextTimerId = 1; - -// tslint:disable-next-line:no-any -export type TimerCallback = (...args: any[]) => void; - -interface Timer { - id: number; - cb: TimerCallback; - interval: boolean; - // tslint:disable-next-line:no-any - args: any[]; - delay: number; // milliseconds -} - -const timers = new Map(); - -/** @internal */ -export function onMessage(msg: fbs.TimerReady) { - const timerReadyId = msg.id(); - const timerReadyDone = msg.done(); - const timer = timers.get(timerReadyId); - if (!timer) { - return; - } - timer.cb(...timer.args); - if (timerReadyDone) { - timers.delete(timerReadyId); - } -} - -function startTimer( - cb: TimerCallback, - delay: number, - interval: boolean, - // tslint:disable-next-line:no-any - args: any[] -): number { - const timer = { - id: nextTimerId++, - interval, - delay, - args, - cb - }; - timers.set(timer.id, timer); - - util.log("timers.ts startTimer"); - - // Send TimerStart message - const builder = new flatbuffers.Builder(); - fbs.TimerStart.startTimerStart(builder); - fbs.TimerStart.addId(builder, timer.id); - fbs.TimerStart.addInterval(builder, timer.interval); - fbs.TimerStart.addDelay(builder, timer.delay); - const msg = fbs.TimerStart.endTimerStart(builder); - fbs.Base.startBase(builder); - fbs.Base.addMsg(builder, msg); - fbs.Base.addMsgType(builder, fbs.Any.TimerStart); - builder.finish(fbs.Base.endBase(builder)); - const resBuf = libdeno.send(builder.asUint8Array()); - assert(resBuf == null); - - return timer.id; -} - -export function setTimeout( - cb: TimerCallback, - delay: number, - // tslint:disable-next-line:no-any - ...args: any[] -): number { - return startTimer(cb, delay, false, args); -} - -export function setInterval( - cb: TimerCallback, - delay: number, - // tslint:disable-next-line:no-any - ...args: any[] -): number { - return startTimer(cb, delay, true, args); -} - -export function clearTimer(id: number) { - timers.delete(id); - - const builder = new flatbuffers.Builder(); - fbs.TimerClear.startTimerClear(builder); - fbs.TimerClear.addId(builder, id); - const msg = fbs.TimerClear.endTimerClear(builder); - fbs.Base.startBase(builder); - fbs.Base.addMsg(builder, msg); - fbs.Base.addMsgType(builder, fbs.Any.TimerClear); - builder.finish(fbs.Base.endBase(builder)); - const resBuf = libdeno.send(builder.asUint8Array()); - assert(resBuf == null); -} diff --git a/js/tsconfig.generated.json b/js/tsconfig.generated.json deleted file mode 100644 index d3cacd73eb19d4..00000000000000 --- a/js/tsconfig.generated.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - // This configuration file provides the tsc configuration for generating - // definitions for the runtime, which are then inlined via the `js/assets.ts` - // module into the bundle to be available for type checking at runtime - // See also gen_declarations in //BUILD.gn - "extends": "../tsconfig.json", - "compilerOptions": { - "declaration": true, - "emitDeclarationOnly": true, - "stripInternal": true - }, - "files": [ - "../node_modules/typescript/lib/lib.esnext.d.ts", - "./compiler.ts", - "./deno.ts", - "./globals.ts" - ] -} diff --git a/js/types.d.ts b/js/types.d.ts deleted file mode 100644 index 110873c6b48fe8..00000000000000 --- a/js/types.d.ts +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -export type TypedArray = Uint8Array | Float32Array | Int32Array; - -export interface ModuleInfo { - moduleName: string | null; - filename: string | null; - sourceCode: string | null; - outputCode: string | null; -} - -// Following definitions adapted from: -// https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/node/index.d.ts -// Type definitions for Node.js 10.3.x -// Definitions by: Microsoft TypeScript -// DefinitelyTyped -// Parambir Singh -// Christian Vaagland Tellnes -// Wilco Bakker -// Nicolas Voigt -// Chigozirim C. -// Flarna -// Mariusz Wiktorczyk -// wwwy3y3 -// Deividas Bakanas -// Kelvin Jin -// Alvis HT Tang -// Sebastian Silbermann -// Hannes Magnusson -// Alberto Schiabel -// Klaus Meinhardt -// Huw -// Nicolas Even -// Bruno Scheufler -// Mohsen Azimi -// Hoàng Văn Khải -// Alexander T. -// Lishude -// Andrew Makarov - -export interface CallSite { - /** - * Value of "this" - */ - getThis(): any; - - /** - * Type of "this" as a string. - * This is the name of the function stored in the constructor field of - * "this", if available. Otherwise the object's [[Class]] internal - * property. - */ - getTypeName(): string | null; - - /** - * Current function - */ - getFunction(): Function | undefined; - - /** - * Name of the current function, typically its name property. - * If a name property is not available an attempt will be made to try - * to infer a name from the function's context. - */ - getFunctionName(): string | null; - - /** - * Name of the property [of "this" or one of its prototypes] that holds - * the current function - */ - getMethodName(): string | null; - - /** - * Name of the script [if this function was defined in a script] - */ - getFileName(): string | null; - - /** - * Get the script name or source URL for the source map - */ - getScriptNameOrSourceURL(): string; - - /** - * Current line number [if this function was defined in a script] - */ - getLineNumber(): number | null; - - /** - * Current column number [if this function was defined in a script] - */ - getColumnNumber(): number | null; - - /** - * A call site object representing the location where eval was called - * [if this function was created using a call to eval] - */ - getEvalOrigin(): string | undefined; - - /** - * Is this a toplevel invocation, that is, is "this" the global object? - */ - isToplevel(): boolean; - - /** - * Does this call take place in code defined by a call to eval? - */ - isEval(): boolean; - - /** - * Is this call in native V8 code? - */ - isNative(): boolean; - - /** - * Is this a constructor call? - */ - isConstructor(): boolean; -} - -export interface StartOfSourceMap { - file?: string; - sourceRoot?: string; -} - -export interface RawSourceMap extends StartOfSourceMap { - version: string; - sources: string[]; - names: string[]; - sourcesContent?: string[]; - mappings: string; -} - -declare global { - // Declare "static" methods in Error - interface ErrorConstructor { - /** Create .stack property on a target object */ - captureStackTrace(targetObject: Object, constructorOpt?: Function): void; - - /** - * Optional override for formatting stack traces - * - * @see https://github.com/v8/v8/wiki/Stack%20Trace%20API#customizing-stack-traces - */ - prepareStackTrace?: (err: Error, stackTraces: CallSite[]) => any; - - stackTraceLimit: number; - } -} diff --git a/js/unit_tests.ts b/js/unit_tests.ts deleted file mode 100644 index e1b04d4c4d21bc..00000000000000 --- a/js/unit_tests.ts +++ /dev/null @@ -1,181 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -// This test is executed as part of integration_test.go -// But it can also be run manually: -// ./deno tests.ts - -import { test, testPerm, assert, assertEqual } from "./test_util.ts"; -import * as deno from "deno"; - -import "./compiler_test.ts"; -import "./console_test.ts"; - -test(async function tests_test() { - assert(true); -}); - -// TODO Add tests for modified, accessed, and created fields once there is a way -// to create temp files. -test(async function statSyncSuccess() { - const packageInfo = deno.statSync("package.json"); - assert(packageInfo.isFile()); - assert(!packageInfo.isSymlink()); - - const testingInfo = deno.statSync("testing"); - assert(testingInfo.isDirectory()); - assert(!testingInfo.isSymlink()); - - const srcInfo = deno.statSync("src"); - assert(srcInfo.isDirectory()); - assert(!srcInfo.isSymlink()); -}) - -test(async function statSyncNotFound() { - let caughtError = false; - let badInfo; - - try { - badInfo = deno.statSync("bad_file_name"); - } catch (err) { - caughtError = true; - // TODO assert(err instanceof deno.NotFound). - assert(err); - assertEqual(err.name, "deno.NotFound"); - } - - assert(caughtError); - assertEqual(badInfo, undefined); -}); - -test(async function lStatSyncSuccess() { - const packageInfo = deno.lStatSync("package.json"); - assert(packageInfo.isFile()); - assert(!packageInfo.isSymlink()); - - const testingInfo = deno.lStatSync("testing"); - assert(!testingInfo.isDirectory()); - assert(testingInfo.isSymlink()); - - const srcInfo = deno.lStatSync("src"); - assert(srcInfo.isDirectory()); - assert(!srcInfo.isSymlink()); -}) - -test(async function lStatSyncNotFound() { - let caughtError = false; - let badInfo; - - try { - badInfo = deno.lStatSync("bad_file_name"); - } catch (err) { - caughtError = true; - // TODO assert(err instanceof deno.NotFound). - assert(err); - assertEqual(err.name, "deno.NotFound"); - } - - assert(caughtError); - assertEqual(badInfo, undefined); -}); - -test(async function tests_readFileSync() { - const data = deno.readFileSync("package.json"); - if (!data.byteLength) { - throw Error( - `Expected positive value for data.byteLength ${data.byteLength}` - ); - } - const decoder = new TextDecoder("utf-8"); - const json = decoder.decode(data); - const pkg = JSON.parse(json); - assertEqual(pkg.name, "deno"); -}); - -/* TODO We should be able to catch specific types. -test(function tests_readFileSync_NotFound() { - let caughtError = false; - let data; - try { - data = deno.readFileSync("bad_filename"); - } catch (e) { - caughtError = true; - assert(e instanceof deno.NotFound); - } - assert(caughtError); - assert(data === undefined); -}); -*/ - -testPerm({ write: true }, function writeFileSync() { - const enc = new TextEncoder(); - const data = enc.encode("Hello"); - const filename = deno.makeTempDirSync() + "/test.txt"; - deno.writeFileSync(filename, data, 0o666); - const dataRead = deno.readFileSync(filename); - const dec = new TextDecoder("utf-8"); - const actual = dec.decode(dataRead); - assertEqual("Hello", actual); -}); - -// For this test to pass we need --allow-write permission. -// Otherwise it will fail with deno.PermissionDenied instead of deno.NotFound. -testPerm({ write: true }, function writeFileSyncFail() { - const enc = new TextEncoder(); - const data = enc.encode("Hello"); - const filename = "/baddir/test.txt"; - // The following should fail because /baddir doesn't exist (hopefully). - let caughtError = false; - try { - deno.writeFileSync(filename, data); - } catch (e) { - caughtError = true; - // TODO assertEqual(e, deno.NotFound); - assertEqual(e.name, "deno.NotFound"); - } - assert(caughtError); -}); - -testPerm({ write: true }, function makeTempDirSync() { - const dir1 = deno.makeTempDirSync({ prefix: "hello", suffix: "world" }); - const dir2 = deno.makeTempDirSync({ prefix: "hello", suffix: "world" }); - // Check that both dirs are different. - assert(dir1 != dir2); - for (const dir of [dir1, dir2]) { - // Check that the prefix and suffix are applied. - const lastPart = dir.replace(/^.*[\\\/]/, ""); - assert(lastPart.startsWith("hello")); - assert(lastPart.endsWith("world")); - } - // Check that the `dir` option works. - const dir3 = deno.makeTempDirSync({ dir: dir1 }); - assert(dir3.startsWith(dir1)); - assert(/^[\\\/]/.test(dir3.slice(dir1.length))); - // Check that creating a temp dir inside a nonexisting directory fails. - let err; - try { - deno.makeTempDirSync({ dir: "/baddir" }); - } catch (err_) { - err = err_; - } - // TODO assert(err instanceof deno.NotFound). - assert(err); - assertEqual(err.name, "deno.NotFound"); -}); - -test(function makeTempDirSyncPerm() { - // makeTempDirSync should require write permissions (for now). - let err; - try { - deno.makeTempDirSync({ dir: "/baddir" }); - } catch (err_) { - err = err_; - } - // TODO assert(err instanceof deno.PermissionDenied). - assert(err); - assertEqual(err.name, "deno.PermissionDenied"); -}); - -testPerm({ net: true }, async function tests_fetch() { - const response = await fetch("http://localhost:4545/package.json"); - const json = await response.json(); - assertEqual(json.name, "deno"); -}); diff --git a/js/util.ts b/js/util.ts deleted file mode 100644 index 1754dc6639134d..00000000000000 --- a/js/util.ts +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -import { TypedArray } from "./types"; - -let logDebug = false; - -export function setLogDebug(debug: boolean): void { - logDebug = debug; -} - -// Debug logging for deno. Enable with the --DEBUG command line flag. -// tslint:disable-next-line:no-any -export function log(...args: any[]): void { - if (logDebug) { - console.log("DEBUG JS -", ...args); - } -} - -export function assert(cond: boolean, msg = "assert") { - if (!cond) { - throw Error(msg); - } -} - -let cmdIdCounter = 0; -export function assignCmdId(): number { - // TODO(piscisaureus) Safely re-use so they don't overflow. - const cmdId = ++cmdIdCounter; - assert(cmdId < 2 ** 32, "cmdId overflow"); - return cmdId; -} - -export function typedArrayToArrayBuffer(ta: TypedArray): ArrayBuffer { - const ab = ta.buffer.slice(ta.byteOffset, ta.byteOffset + ta.byteLength); - return ab as ArrayBuffer; -} - -export function arrayToStr(ui8: Uint8Array): string { - return String.fromCharCode(...ui8); -} - -// A `Resolvable` is a Promise with the `reject` and `resolve` functions -// placed as methods on the promise object itself. It allows you to do: -// -// const p = createResolvable(); -// ... -// p.resolve(42); -// -// It'd be prettier to make Resolvable a class that inherits from Promise, -// rather than an interface. This is possible in ES2016, however typescript -// produces broken code when targeting ES5 code. -// See https://github.com/Microsoft/TypeScript/issues/15202 -// At the time of writing, the github issue is closed but the problem remains. -export interface ResolvableMethods { - resolve: (value?: T | PromiseLike) => void; - // tslint:disable-next-line:no-any - reject: (reason?: any) => void; -} - -export type Resolvable = Promise & ResolvableMethods; - -export function createResolvable(): Resolvable { - let methods: ResolvableMethods; - const promise = new Promise((resolve, reject) => { - methods = { resolve, reject }; - }); - // TypeScript doesn't know that the Promise callback occurs synchronously - // therefore use of not null assertion (`!`) - return Object.assign(promise, methods!) as Resolvable; -} - -export function notImplemented(): never { - throw new Error("Not implemented"); -} - -export function unreachable(): never { - throw new Error("Code not reachable"); -} diff --git a/js/v8_source_maps.ts b/js/v8_source_maps.ts deleted file mode 100644 index 8d1691b233c912..00000000000000 --- a/js/v8_source_maps.ts +++ /dev/null @@ -1,276 +0,0 @@ -// Copyright 2014 Evan Wallace -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -// Originated from source-map-support but has been heavily modified for deno. - -import { SourceMapConsumer, MappedPosition } from "source-map"; -import * as base64 from "base64-js"; -import { arrayToStr } from "./util"; -import { CallSite, RawSourceMap } from "./types"; - -const consumers = new Map(); - -interface Options { - // A callback the returns generated file contents. - getGeneratedContents: GetGeneratedContentsCallback; - // Usually set the following to true. Set to false for testing. - installPrepareStackTrace: boolean; -} - -interface Position { - source: string; // Filename - column: number; - line: number; -} - -type GetGeneratedContentsCallback = (fileName: string) => string | RawSourceMap; - -let getGeneratedContents: GetGeneratedContentsCallback; - -export function install(options: Options) { - getGeneratedContents = options.getGeneratedContents; - if (options.installPrepareStackTrace) { - Error.prepareStackTrace = prepareStackTraceWrapper; - } -} - -export function prepareStackTraceWrapper( - error: Error, - stack: CallSite[] -): string { - try { - return prepareStackTrace(error, stack); - } catch (prepareStackError) { - Error.prepareStackTrace = undefined; - console.log("=====Error inside of prepareStackTrace===="); - console.log(prepareStackError.stack.toString()); - console.log("=====Original error======================="); - throw error; - } -} - -export function prepareStackTrace(error: Error, stack: CallSite[]): string { - const frames = stack.map( - (frame: CallSite) => `\n at ${wrapCallSite(frame).toString()}` - ); - return error.toString() + frames.join(""); -} - -export function wrapCallSite(frame: CallSite): CallSite { - if (frame.isNative()) { - return frame; - } - - // Most call sites will return the source file from getFileName(), but code - // passed to eval() ending in "//# sourceURL=..." will return the source file - // from getScriptNameOrSourceURL() instead - const source = frame.getFileName() || frame.getScriptNameOrSourceURL(); - - if (source) { - const line = frame.getLineNumber() || 0; - const column = (frame.getColumnNumber() || 1) - 1; - const position = mapSourcePosition({ source, line, column }); - frame = cloneCallSite(frame); - frame.getFileName = () => position.source; - frame.getLineNumber = () => position.line; - frame.getColumnNumber = () => Number(position.column) + 1; - frame.getScriptNameOrSourceURL = () => position.source; - frame.toString = () => CallSiteToString(frame); - return frame; - } - - // Code called using eval() needs special handling - let origin = (frame.isEval() && frame.getEvalOrigin()) || undefined; - if (origin) { - origin = mapEvalOrigin(origin); - frame = cloneCallSite(frame); - frame.getEvalOrigin = () => origin; - return frame; - } - - // If we get here then we were unable to change the source position - return frame; -} - -function cloneCallSite(frame: CallSite): CallSite { - // tslint:disable:no-any - const obj: any = {}; - const frame_ = frame as any; - const props = Object.getOwnPropertyNames(Object.getPrototypeOf(frame)); - props.forEach(name => { - obj[name] = /^(?:is|get)/.test(name) - ? () => frame_[name].call(frame) - : frame_[name]; - }); - return (obj as any) as CallSite; - // tslint:enable:no-any -} - -// Taken from source-map-support, original copied from V8's messages.js -// MIT License. Copyright (c) 2014 Evan Wallace -function CallSiteToString(frame: CallSite): string { - let fileName; - let fileLocation = ""; - if (frame.isNative()) { - fileLocation = "native"; - } else { - fileName = frame.getScriptNameOrSourceURL(); - if (!fileName && frame.isEval()) { - fileLocation = frame.getEvalOrigin() || ""; - fileLocation += ", "; // Expecting source position to follow. - } - - if (fileName) { - fileLocation += fileName; - } else { - // Source code does not originate from a file and is not native, but we - // can still get the source position inside the source string, e.g. in - // an eval string. - fileLocation += ""; - } - const lineNumber = frame.getLineNumber(); - if (lineNumber != null) { - fileLocation += ":" + String(lineNumber); - const columnNumber = frame.getColumnNumber(); - if (columnNumber) { - fileLocation += ":" + String(columnNumber); - } - } - } - - let line = ""; - const functionName = frame.getFunctionName(); - let addSuffix = true; - const isConstructor = frame.isConstructor(); - const isMethodCall = !(frame.isToplevel() || isConstructor); - if (isMethodCall) { - let typeName = frame.getTypeName(); - // Fixes shim to be backward compatable with Node v0 to v4 - if (typeName === "[object Object]") { - typeName = "null"; - } - const methodName = frame.getMethodName(); - if (functionName) { - if (typeName && functionName.indexOf(typeName) !== 0) { - line += typeName + "."; - } - line += functionName; - if ( - methodName && - functionName.indexOf("." + methodName) !== - functionName.length - methodName.length - 1 - ) { - line += ` [as ${methodName} ]`; - } - } else { - line += `${typeName}.${methodName || ""}`; - } - } else if (isConstructor) { - line += "new " + (functionName || ""); - } else if (functionName) { - line += functionName; - } else { - line += fileLocation; - addSuffix = false; - } - if (addSuffix) { - line += ` (${fileLocation})`; - } - return line; -} - -// Regex for detecting source maps -const reSourceMap = /^data:application\/json[^,]+base64,/; - -function loadConsumer(source: string): SourceMapConsumer | null { - let consumer = consumers.get(source); - if (consumer == null) { - const code = getGeneratedContents(source); - if (!code) { - return null; - } - if (typeof code !== "string") { - throw new Error("expected string"); - } - - let sourceMappingURL = retrieveSourceMapURL(code); - if (!sourceMappingURL) { - throw Error("No source map?"); - } - - let sourceMapData: string | RawSourceMap; - if (reSourceMap.test(sourceMappingURL)) { - // Support source map URL as a data url - const rawData = sourceMappingURL.slice(sourceMappingURL.indexOf(",") + 1); - const ui8 = base64.toByteArray(rawData); - sourceMapData = arrayToStr(ui8); - sourceMappingURL = source; - } else { - // Support source map URLs relative to the source URL - //sourceMappingURL = supportRelativeURL(source, sourceMappingURL); - sourceMapData = getGeneratedContents(sourceMappingURL); - } - - const rawSourceMap = - typeof sourceMapData === "string" - ? JSON.parse(sourceMapData) - : sourceMapData; - //console.log("sourceMapData", sourceMapData); - consumer = new SourceMapConsumer(rawSourceMap); - consumers.set(source, consumer); - } - return consumer; -} - -function retrieveSourceMapURL(fileData: string): string | null { - // Get the URL of the source map - // tslint:disable-next-line:max-line-length - const re = /(?:\/\/[@#][ \t]+sourceMappingURL=([^\s'"]+?)[ \t]*$)|(?:\/\*[@#][ \t]+sourceMappingURL=([^\*]+?)[ \t]*(?:\*\/)[ \t]*$)/gm; - // Keep executing the search to find the *last* sourceMappingURL to avoid - // picking up sourceMappingURLs from comments, strings, etc. - let lastMatch, match; - while ((match = re.exec(fileData))) { - lastMatch = match; - } - if (!lastMatch) { - return null; - } - return lastMatch[1]; -} - -function mapSourcePosition(position: Position): MappedPosition { - const consumer = loadConsumer(position.source); - if (consumer == null) { - return position; - } - const mapped = consumer.originalPositionFor(position); - return mapped; -} - -// Parses code generated by FormatEvalOrigin(), a function inside V8: -// https://code.google.com/p/v8/source/browse/trunk/src/messages.js -function mapEvalOrigin(origin: string): string { - // Most eval() calls are in this format - let match = /^eval at ([^(]+) \((.+):(\d+):(\d+)\)$/.exec(origin); - if (match) { - const position = mapSourcePosition({ - source: match[2], - line: Number(match[3]), - column: Number(match[4]) - 1 - }); - const pos = [ - position.source, - position.line, - Number(position.column) + 1 - ].join(":"); - return `eval at ${match[1]} (${pos})`; - } - - // Parse nested eval() calls using recursion - match = /^eval at ([^(]+) \((.+)\)$/.exec(origin); - if (match) { - return `eval at ${match[1]} (${mapEvalOrigin(match[2])})`; - } - - // Make sure we still return useful information if we didn't find anything - return origin; -} diff --git a/libdeno/binding.cc b/libdeno/binding.cc deleted file mode 100644 index 7a79bf1998e76e..00000000000000 --- a/libdeno/binding.cc +++ /dev/null @@ -1,443 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -#include -#include -#include -#include - -#include "third_party/v8/include/libplatform/libplatform.h" -#include "third_party/v8/include/v8.h" -#include "third_party/v8/src/base/logging.h" - -#include "deno.h" -#include "internal.h" - -namespace deno { - -Deno* FromIsolate(v8::Isolate* isolate) { - return static_cast(isolate->GetData(0)); -} - -// Extracts a C string from a v8::V8 Utf8Value. -const char* ToCString(const v8::String::Utf8Value& value) { - return *value ? *value : ""; -} - -static inline v8::Local v8_str(const char* x) { - return v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), x, - v8::NewStringType::kNormal) - .ToLocalChecked(); -} - -void HandleExceptionStr(v8::Local context, - v8::Local exception, - std::string* exception_str) { - auto* isolate = context->GetIsolate(); - Deno* d = FromIsolate(isolate); - - v8::HandleScope handle_scope(isolate); - v8::Context::Scope context_scope(context); - - auto message = v8::Exception::CreateMessage(isolate, exception); - auto stack_trace = message->GetStackTrace(); - auto line = - v8::Integer::New(isolate, message->GetLineNumber(context).FromJust()); - auto column = - v8::Integer::New(isolate, message->GetStartColumn(context).FromJust()); - - auto global_error_handler = d->global_error_handler.Get(isolate); - - if (!global_error_handler.IsEmpty()) { - // global_error_handler is set so we try to handle the exception in - // javascript. - v8::Local args[5]; - args[0] = exception->ToString(); - args[1] = message->GetScriptResourceName(); - args[2] = line; - args[3] = column; - args[4] = exception; - global_error_handler->Call(context->Global(), 5, args); - /* message, source, lineno, colno, error */ - - return; - } - - char buf[12 * 1024]; - if (!stack_trace.IsEmpty()) { - // No javascript error handler, but we do have a stack trace. Format it - // into a string and add to last_exception. - std::string msg; - v8::String::Utf8Value exceptionStr(isolate, exception); - msg += ToCString(exceptionStr); - msg += "\n"; - - for (int i = 0; i < stack_trace->GetFrameCount(); ++i) { - auto frame = stack_trace->GetFrame(i); - v8::String::Utf8Value script_name(isolate, frame->GetScriptName()); - int l = frame->GetLineNumber(); - int c = frame->GetColumn(); - snprintf(buf, sizeof(buf), "%s %d:%d\n", ToCString(script_name), l, c); - msg += buf; - } - *exception_str += msg; - } else { - // No javascript error handler, no stack trace. Format the little info we - // have into a string and add to last_exception. - v8::String::Utf8Value exceptionStr(isolate, exception); - v8::String::Utf8Value script_name(isolate, - message->GetScriptResourceName()); - v8::String::Utf8Value line_str(isolate, line); - v8::String::Utf8Value col_str(isolate, column); - snprintf(buf, sizeof(buf), "%s\n%s %s:%s\n", ToCString(exceptionStr), - ToCString(script_name), ToCString(line_str), ToCString(col_str)); - *exception_str += buf; - } -} - -void HandleException(v8::Local context, - v8::Local exception) { - v8::Isolate* isolate = context->GetIsolate(); - Deno* d = FromIsolate(isolate); - std::string exception_str; - HandleExceptionStr(context, exception, &exception_str); - if (d != nullptr) { - d->last_exception = exception_str; - } else { - printf("Pre-Deno Exception %s\n", exception_str.c_str()); - exit(1); - } -} - -/* -bool AbortOnUncaughtExceptionCallback(v8::Isolate* isolate) { - return true; -} - -void MessageCallback2(Local message, v8::Local data) { - printf("MessageCallback2\n\n"); -} - -void FatalErrorCallback2(const char* location, const char* message) { - printf("FatalErrorCallback2\n"); -} -*/ - -void ExitOnPromiseRejectCallback( - v8::PromiseRejectMessage promise_reject_message) { - auto* isolate = v8::Isolate::GetCurrent(); - Deno* d = static_cast(isolate->GetData(0)); - DCHECK_EQ(d->isolate, isolate); - v8::HandleScope handle_scope(d->isolate); - auto exception = promise_reject_message.GetValue(); - auto context = d->context.Get(d->isolate); - HandleException(context, exception); -} - -void Print(const v8::FunctionCallbackInfo& args) { - CHECK_EQ(args.Length(), 1); - auto* isolate = args.GetIsolate(); - v8::HandleScope handle_scope(isolate); - v8::String::Utf8Value str(isolate, args[0]); - const char* cstr = ToCString(str); - printf("%s\n", cstr); - fflush(stdout); -} - -static v8::Local ImportBuf(v8::Isolate* isolate, deno_buf buf) { - if (buf.alloc_ptr == nullptr) { - // If alloc_ptr isn't set, we memcpy. - // This is currently used for flatbuffers created in Rust. - auto ab = v8::ArrayBuffer::New(isolate, buf.data_len); - memcpy(ab->GetContents().Data(), buf.data_ptr, buf.data_len); - auto view = v8::Uint8Array::New(ab, 0, buf.data_len); - return view; - } else { - auto ab = v8::ArrayBuffer::New( - isolate, reinterpret_cast(buf.alloc_ptr), buf.alloc_len, - v8::ArrayBufferCreationMode::kInternalized); - auto view = - v8::Uint8Array::New(ab, buf.data_ptr - buf.alloc_ptr, buf.data_len); - return view; - } -} - -static deno_buf ExportBuf(v8::Isolate* isolate, - v8::Local view) { - auto ab = view->Buffer(); - auto contents = ab->Externalize(); - - deno_buf buf; - buf.alloc_ptr = reinterpret_cast(contents.Data()); - buf.alloc_len = contents.ByteLength(); - buf.data_ptr = buf.alloc_ptr + view->ByteOffset(); - buf.data_len = view->ByteLength(); - - // Prevent JS from modifying buffer contents after exporting. - ab->Neuter(); - - return buf; -} - -static void FreeBuf(deno_buf buf) { free(buf.alloc_ptr); } - -// Sets the recv callback. -void Recv(const v8::FunctionCallbackInfo& args) { - v8::Isolate* isolate = args.GetIsolate(); - Deno* d = reinterpret_cast(isolate->GetData(0)); - DCHECK_EQ(d->isolate, isolate); - - v8::HandleScope handle_scope(isolate); - - if (!d->recv.IsEmpty()) { - isolate->ThrowException(v8_str("libdeno.recv already called.")); - return; - } - - v8::Local v = args[0]; - CHECK(v->IsFunction()); - v8::Local func = v8::Local::Cast(v); - - d->recv.Reset(isolate, func); -} - -void Send(const v8::FunctionCallbackInfo& args) { - v8::Isolate* isolate = args.GetIsolate(); - Deno* d = static_cast(isolate->GetData(0)); - DCHECK_EQ(d->isolate, isolate); - - v8::Locker locker(d->isolate); - v8::EscapableHandleScope handle_scope(isolate); - - CHECK_EQ(args.Length(), 1); - v8::Local ab_v = args[0]; - CHECK(ab_v->IsArrayBufferView()); - auto buf = ExportBuf(isolate, v8::Local::Cast(ab_v)); - - DCHECK_EQ(d->currentArgs, nullptr); - d->currentArgs = &args; - - d->cb(d, buf); - - // Buffer is only valid until the end of the callback. - // TODO(piscisaureus): - // It's possible that data in the buffer is needed after the callback - // returns, e.g. when the handler offloads work to a thread pool, therefore - // make the callback responsible for releasing the buffer. - FreeBuf(buf); - - d->currentArgs = nullptr; -} - -// Sets the global error handler. -void SetGlobalErrorHandler(const v8::FunctionCallbackInfo& args) { - v8::Isolate* isolate = args.GetIsolate(); - Deno* d = reinterpret_cast(isolate->GetData(0)); - DCHECK_EQ(d->isolate, isolate); - - v8::HandleScope handle_scope(isolate); - - if (!d->global_error_handler.IsEmpty()) { - isolate->ThrowException( - v8_str("libdeno.setGlobalErrorHandler already called.")); - return; - } - - v8::Local v = args[0]; - CHECK(v->IsFunction()); - v8::Local func = v8::Local::Cast(v); - - d->global_error_handler.Reset(isolate, func); -} - -bool ExecuteV8StringSource(v8::Local context, - const char* js_filename, - v8::Local source) { - auto* isolate = context->GetIsolate(); - v8::Isolate::Scope isolate_scope(isolate); - v8::HandleScope handle_scope(isolate); - - v8::Context::Scope context_scope(context); - - v8::TryCatch try_catch(isolate); - - auto name = v8_str(js_filename); - - v8::ScriptOrigin origin(name); - - auto script = v8::Script::Compile(context, source, &origin); - - if (script.IsEmpty()) { - DCHECK(try_catch.HasCaught()); - HandleException(context, try_catch.Exception()); - return false; - } - - auto result = script.ToLocalChecked()->Run(context); - - if (result.IsEmpty()) { - DCHECK(try_catch.HasCaught()); - HandleException(context, try_catch.Exception()); - return false; - } - - return true; -} - -bool Execute(v8::Local context, const char* js_filename, - const char* js_source) { - auto* isolate = context->GetIsolate(); - v8::Isolate::Scope isolate_scope(isolate); - v8::HandleScope handle_scope(isolate); - auto source = v8_str(js_source); - return ExecuteV8StringSource(context, js_filename, source); -} - -void InitializeContext(v8::Isolate* isolate, v8::Local context, - const char* js_filename, const std::string& js_source, - const std::string* source_map) { - v8::HandleScope handle_scope(isolate); - v8::Context::Scope context_scope(context); - - auto global = context->Global(); - - auto deno_val = v8::Object::New(isolate); - CHECK(global->Set(context, deno::v8_str("libdeno"), deno_val).FromJust()); - - auto print_tmpl = v8::FunctionTemplate::New(isolate, Print); - auto print_val = print_tmpl->GetFunction(context).ToLocalChecked(); - CHECK(deno_val->Set(context, deno::v8_str("print"), print_val).FromJust()); - - auto recv_tmpl = v8::FunctionTemplate::New(isolate, Recv); - auto recv_val = recv_tmpl->GetFunction(context).ToLocalChecked(); - CHECK(deno_val->Set(context, deno::v8_str("recv"), recv_val).FromJust()); - - auto send_tmpl = v8::FunctionTemplate::New(isolate, Send); - auto send_val = send_tmpl->GetFunction(context).ToLocalChecked(); - CHECK(deno_val->Set(context, deno::v8_str("send"), send_val).FromJust()); - - auto set_global_error_handler_tmpl = - v8::FunctionTemplate::New(isolate, SetGlobalErrorHandler); - auto set_global_error_handler_val = - set_global_error_handler_tmpl->GetFunction(context).ToLocalChecked(); - CHECK(deno_val - ->Set(context, deno::v8_str("setGlobalErrorHandler"), - set_global_error_handler_val) - .FromJust()); - - { - auto source = deno::v8_str(js_source.c_str()); - CHECK( - deno_val->Set(context, deno::v8_str("mainSource"), source).FromJust()); - - bool r = deno::ExecuteV8StringSource(context, js_filename, source); - CHECK(r); - - if (source_map != nullptr) { - CHECK_GT(source_map->length(), 1u); - v8::TryCatch try_catch(isolate); - v8::ScriptOrigin origin(v8_str("set_source_map.js")); - std::string source_map_parens = "(" + *source_map + ")"; - auto source_map_v8_str = deno::v8_str(source_map_parens.c_str()); - auto script = v8::Script::Compile(context, source_map_v8_str, &origin); - if (script.IsEmpty()) { - DCHECK(try_catch.HasCaught()); - HandleException(context, try_catch.Exception()); - return; - } - auto source_map_obj = script.ToLocalChecked()->Run(context); - if (source_map_obj.IsEmpty()) { - DCHECK(try_catch.HasCaught()); - HandleException(context, try_catch.Exception()); - return; - } - CHECK(deno_val - ->Set(context, deno::v8_str("mainSourceMap"), - source_map_obj.ToLocalChecked()) - .FromJust()); - } - } -} - -void AddIsolate(Deno* d, v8::Isolate* isolate) { - d->isolate = isolate; - // Leaving this code here because it will probably be useful later on, but - // disabling it now as I haven't got tests for the desired behavior. - // d->isolate->SetCaptureStackTraceForUncaughtExceptions(true); - // d->isolate->SetAbortOnUncaughtExceptionCallback(AbortOnUncaughtExceptionCallback); - // d->isolate->AddMessageListener(MessageCallback2); - // d->isolate->SetFatalErrorHandler(FatalErrorCallback2); - d->isolate->SetPromiseRejectCallback(deno::ExitOnPromiseRejectCallback); - d->isolate->SetData(0, d); -} - -} // namespace deno - -extern "C" { - -void deno_init() { - // v8::V8::InitializeICUDefaultLocation(argv[0]); - // v8::V8::InitializeExternalStartupData(argv[0]); - auto* p = v8::platform::CreateDefaultPlatform(); - v8::V8::InitializePlatform(p); - v8::V8::Initialize(); -} - -void* deno_get_data(Deno* d) { return d->data; } - -const char* deno_v8_version() { return v8::V8::GetVersion(); } - -void deno_set_flags(int* argc, char** argv) { - v8::V8::SetFlagsFromCommandLine(argc, argv, true); -} - -const char* deno_last_exception(Deno* d) { return d->last_exception.c_str(); } - -int deno_execute(Deno* d, const char* js_filename, const char* js_source) { - auto* isolate = d->isolate; - v8::Locker locker(isolate); - v8::Isolate::Scope isolate_scope(isolate); - v8::HandleScope handle_scope(isolate); - auto context = d->context.Get(d->isolate); - return deno::Execute(context, js_filename, js_source) ? 1 : 0; -} - -int deno_send(Deno* d, deno_buf buf) { - v8::Locker locker(d->isolate); - v8::Isolate::Scope isolate_scope(d->isolate); - v8::HandleScope handle_scope(d->isolate); - - auto context = d->context.Get(d->isolate); - v8::Context::Scope context_scope(context); - - v8::TryCatch try_catch(d->isolate); - - auto recv = d->recv.Get(d->isolate); - if (recv.IsEmpty()) { - d->last_exception = "libdeno.recv has not been called."; - return 0; - } - - v8::Local args[1]; - args[0] = deno::ImportBuf(d->isolate, buf); - recv->Call(context->Global(), 1, args); - - if (try_catch.HasCaught()) { - deno::HandleException(context, try_catch.Exception()); - return 0; - } - - return 1; -} - -void deno_set_response(Deno* d, deno_buf buf) { - auto ab = deno::ImportBuf(d->isolate, buf); - d->currentArgs->GetReturnValue().Set(ab); -} - -void deno_delete(Deno* d) { - d->isolate->Dispose(); - delete d; -} - -void deno_terminate_execution(Deno* d) { d->isolate->TerminateExecution(); } - -} // extern "C" diff --git a/libdeno/deno.h b/libdeno/deno.h deleted file mode 100644 index 7bde5ab9d1873f..00000000000000 --- a/libdeno/deno.h +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -#ifndef DENO_H_ -#define DENO_H_ -#include -#include -// Neither Rust nor Go support calling directly into C++ functions, therefore -// the public interface to libdeno is done in C. -#ifdef __cplusplus -extern "C" { -#endif - -// Data that gets transmitted. -typedef struct { - uint8_t* alloc_ptr; // Start of memory allocation (returned from `malloc()`). - size_t alloc_len; // Length of the memory allocation. - uint8_t* data_ptr; // Start of logical contents (within the allocation). - size_t data_len; // Length of logical contents. -} deno_buf; - -struct deno_s; -typedef struct deno_s Deno; - -// A callback to receive a message from deno.send javascript call. -// buf is valid only for the lifetime of the call. -typedef void (*deno_recv_cb)(Deno* d, deno_buf buf); - -void deno_init(); -const char* deno_v8_version(); -void deno_set_flags(int* argc, char** argv); - -Deno* deno_new(void* data, deno_recv_cb cb); -void deno_delete(Deno* d); - -// Returns the void* data provided in deno_new. -void* deno_get_data(Deno*); - -// Returns false on error. -// Get error text with deno_last_exception(). -// 0 = fail, 1 = success -int deno_execute(Deno* d, const char* js_filename, const char* js_source); - -// Routes message to the javascript callback set with deno.recv(). A false -// return value indicates error. Check deno_last_exception() for exception text. -// 0 = fail, 1 = success -// After calling deno_send(), the caller no longer owns `buf` and must not use -// it; deno_send() is responsible for releasing it's memory. -// TODO(piscisaureus) In C++ and/or Rust, use a smart pointer or similar to -// enforce this rule. -int deno_send(Deno* d, deno_buf buf); - -// Call this inside a deno_recv_cb to respond synchronously to messages. -// If this is not called during the life time of a deno_recv_cb callback -// the deno.send() call in javascript will return null. -// After calling deno_set_response(), the caller no longer owns `buf` and must -// not access it; deno_set_response() is responsible for releasing it's memory. -void deno_set_response(Deno* d, deno_buf buf); - -const char* deno_last_exception(Deno* d); - -void deno_terminate_execution(Deno* d); - -#ifdef __cplusplus -} // extern "C" -#endif -#endif // DENO_H_ diff --git a/libdeno/file_util.cc b/libdeno/file_util.cc deleted file mode 100644 index 8df0dafea47676..00000000000000 --- a/libdeno/file_util.cc +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __APPLE__ -#include -#endif - -#ifdef _WIN32 -#include -#endif - -#include "file_util.h" - -namespace deno { - -bool ReadFileToString(const char* fn, std::string* contents) { - std::ifstream file(fn, std::ios::binary); - if (file.fail()) { - return false; - } - contents->assign(std::istreambuf_iterator{file}, {}); - return !file.fail(); -} - -std::string Basename(std::string const& filename) { - for (auto it = filename.rbegin(); it != filename.rend(); ++it) { - char ch = *it; - if (ch == '\\' || ch == '/') { - return std::string(it.base(), filename.end()); - } - } - return filename; -} - -// Returns the directory component from a filename. The returned path always -// ends with a slash. This function does not understand Windows drive letters. -std::string Dirname(std::string const& filename) { - for (auto it = filename.rbegin(); it != filename.rend(); ++it) { - char ch = *it; - if (ch == '\\' || ch == '/') { - return std::string(filename.begin(), it.base()); - } - } - return std::string("./"); -} - -// Returns the full path the currently running executable. -// This implementation is very basic. Caveats: -// * OS X: fails if buffer is too small, does not retry with a bigger buffer. -// * Windows: ANSI only, no unicode. Fails if path is longer than 260 chars. -bool ExePath(std::string* path) { -#ifdef _WIN32 - // Windows only. - char exe_buf[MAX_PATH]; - DWORD len = GetModuleFileNameA(NULL, exe_buf, sizeof exe_buf); - if (len == 0 || len == sizeof exe_buf) { - return false; - } -#else -#ifdef __APPLE__ - // OS X only. - char link_buf[PATH_MAX * 2]; // Exe may be longer than MAX_PATH, says Apple. - uint32_t len = sizeof link_buf; - if (_NSGetExecutablePath(link_buf, &len) < 0) { - return false; - } -#else - // Linux only. - static const char* link_buf = "/proc/self/exe"; -#endif - // Linux and OS X. - char exe_buf[PATH_MAX]; - char* r = realpath(link_buf, exe_buf); - if (r == NULL) { - return false; - } -#endif - // All platforms. - path->assign(exe_buf); - return true; -} - -} // namespace deno diff --git a/libdeno/file_util.h b/libdeno/file_util.h deleted file mode 100644 index 63ecef907a3b21..00000000000000 --- a/libdeno/file_util.h +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -#ifndef FILE_UTIL_H_ -#define FILE_UTIL_H_ - -#include - -namespace deno { -bool ReadFileToString(const char* fn, std::string* contents); -std::string Basename(std::string const& filename); -std::string Dirname(std::string const& filename); -bool ExePath(std::string* path); -} // namespace deno - -#endif // FILE_UTIL_H_ diff --git a/libdeno/file_util_test.cc b/libdeno/file_util_test.cc deleted file mode 100644 index ac854c52e123a2..00000000000000 --- a/libdeno/file_util_test.cc +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -#include "testing/gtest/include/gtest/gtest.h" - -#include "file_util.h" - -TEST(FileUtilTest, ReadFileToStringFileNotExist) { - std::string output; - EXPECT_FALSE(deno::ReadFileToString("/should_error_out.txt", &output)); -} - -TEST(FileUtilTest, Basename) { - EXPECT_EQ("foo.txt", deno::Basename("foo.txt")); - EXPECT_EQ("foo.txt", deno::Basename("/foo.txt")); - EXPECT_EQ("", deno::Basename("/foo/")); - EXPECT_EQ("", deno::Basename("foo/")); - EXPECT_EQ("", deno::Basename("/")); - EXPECT_EQ("foo.txt", deno::Basename(".\\foo.txt")); - EXPECT_EQ("foo.txt", deno::Basename("/home/ryan/foo.txt")); - EXPECT_EQ("foo.txt", deno::Basename("C:\\home\\ryan\\foo.txt")); -} - -TEST(FileUtilTest, Dirname) { - EXPECT_EQ("home/dank/", deno::Dirname("home/dank/memes.gif")); - EXPECT_EQ("/home/dank/", deno::Dirname("/home/dank/memes.gif")); - EXPECT_EQ("/home/dank/", deno::Dirname("/home/dank/")); - EXPECT_EQ("home/dank/", deno::Dirname("home/dank/memes.gif")); - EXPECT_EQ("/", deno::Dirname("/")); - EXPECT_EQ(".\\", deno::Dirname(".\\memes.gif")); - EXPECT_EQ("c:\\", deno::Dirname("c:\\stuff")); - EXPECT_EQ("./", deno::Dirname("nothing")); - EXPECT_EQ("./", deno::Dirname("")); -} - -TEST(FileUtilTest, ExePath) { - std::string exe_path; - EXPECT_TRUE(deno::ExePath(&exe_path)); - // Path is absolute. - EXPECT_TRUE(exe_path.find("/") == 0 || exe_path.find(":\\") == 1); - // FIlename is the name of the test binary. - std::string exe_filename = deno::Basename(exe_path); - EXPECT_EQ(exe_filename.find("test_cc"), 0u); - // Path exists (also tests ReadFileToString). - std::string contents; - EXPECT_TRUE(deno::ReadFileToString(exe_path.c_str(), &contents)); - EXPECT_NE(contents.find("Inception :)"), std::string::npos); -} diff --git a/libdeno/from_filesystem.cc b/libdeno/from_filesystem.cc deleted file mode 100644 index 0852f1558ba3d6..00000000000000 --- a/libdeno/from_filesystem.cc +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -// This file is used to load the bundle at start for deno_ns. -#include -#include -#include -#include - -#include "third_party/v8/include/v8.h" -#include "third_party/v8/src/base/logging.h" - -#include "deno.h" -#include "file_util.h" -#include "internal.h" - -namespace deno { - -Deno* NewFromFileSystem(void* data, deno_recv_cb cb) { - std::string exe_path; - CHECK(deno::ExePath(&exe_path)); - std::string exe_dir = deno::Dirname(exe_path); // Always ends with a slash. - - std::string js_source_path = exe_dir + BUNDLE_LOCATION; - std::string js_source; - CHECK(deno::ReadFileToString(js_source_path.c_str(), &js_source)); - - std::string js_source_map_path = exe_dir + BUNDLE_MAP_LOCATION; - std::string js_source_map; - CHECK(deno::ReadFileToString(js_source_map_path.c_str(), &js_source_map)); - - Deno* d = new Deno; - d->currentArgs = nullptr; - d->cb = cb; - d->data = data; - v8::Isolate::CreateParams params; - params.array_buffer_allocator = - v8::ArrayBuffer::Allocator::NewDefaultAllocator(); - v8::Isolate* isolate = v8::Isolate::New(params); - AddIsolate(d, isolate); - - v8::Locker locker(isolate); - v8::Isolate::Scope isolate_scope(isolate); - { - v8::HandleScope handle_scope(isolate); - auto context = v8::Context::New(isolate); - // For source maps to work, the bundle location that is passed to - // InitializeContext must be a relative path. - InitializeContext(isolate, context, BUNDLE_LOCATION, js_source, - &js_source_map); - d->context.Reset(d->isolate, context); - } - - return d; -} - -} // namespace deno - -extern "C" { -Deno* deno_new(void* data, deno_recv_cb cb) { - return deno::NewFromFileSystem(data, cb); -} -} diff --git a/libdeno/from_snapshot.cc b/libdeno/from_snapshot.cc deleted file mode 100644 index bcd215f82069a2..00000000000000 --- a/libdeno/from_snapshot.cc +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -#include -#include -#include -#include - -#include "third_party/v8/include/v8.h" -#include "third_party/v8/src/base/logging.h" - -#include "deno.h" -#include "internal.h" - -extern const char deno_snapshot_start asm("deno_snapshot_start"); -extern const char deno_snapshot_end asm("deno_snapshot_end"); -#ifdef LIBDENO_TEST -asm(".data\n" - "deno_snapshot_start: .incbin \"gen/snapshot_libdeno_test.bin\"\n" - "deno_snapshot_end:\n" - ".globl deno_snapshot_start;\n" - ".globl deno_snapshot_end;"); -#else -asm(".data\n" - "deno_snapshot_start: .incbin \"gen/snapshot_deno.bin\"\n" - "deno_snapshot_end:\n" - ".globl deno_snapshot_start;\n" - ".globl deno_snapshot_end;"); -#endif // LIBDENO_TEST - -namespace deno { - -std::vector deserialized_data; - -void DeserializeInternalFields(v8::Local holder, int index, - v8::StartupData payload, void* data) { - DCHECK_EQ(data, nullptr); - if (payload.raw_size == 0) { - holder->SetAlignedPointerInInternalField(index, nullptr); - return; - } - InternalFieldData* embedder_field = new InternalFieldData{0}; - memcpy(embedder_field, payload.data, payload.raw_size); - holder->SetAlignedPointerInInternalField(index, embedder_field); - deserialized_data.push_back(embedder_field); -} - -Deno* NewFromSnapshot(void* data, deno_recv_cb cb) { - Deno* d = new Deno; - d->currentArgs = nullptr; - d->cb = cb; - d->data = data; - v8::Isolate::CreateParams params; - params.array_buffer_allocator = - v8::ArrayBuffer::Allocator::NewDefaultAllocator(); - params.external_references = external_references; - - CHECK_NE(&deno_snapshot_start, nullptr); - int snapshot_len = - static_cast(&deno_snapshot_end - &deno_snapshot_start); - static v8::StartupData snapshot = {&deno_snapshot_start, snapshot_len}; - params.snapshot_blob = &snapshot; - - v8::Isolate* isolate = v8::Isolate::New(params); - AddIsolate(d, isolate); - - v8::Locker locker(isolate); - v8::Isolate::Scope isolate_scope(isolate); - { - v8::HandleScope handle_scope(isolate); - auto context = - v8::Context::New(isolate, nullptr, v8::MaybeLocal(), - v8::MaybeLocal(), - v8::DeserializeInternalFieldsCallback( - DeserializeInternalFields, nullptr)); - d->context.Reset(d->isolate, context); - } - - return d; -} - -} // namespace deno - -extern "C" { -Deno* deno_new(void* data, deno_recv_cb cb) { - return deno::NewFromSnapshot(data, cb); -} -} diff --git a/libdeno/internal.h b/libdeno/internal.h deleted file mode 100644 index 93fdea5db77195..00000000000000 --- a/libdeno/internal.h +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -#ifndef INTERNAL_H_ -#define INTERNAL_H_ - -#include -#include "deno.h" -#include "third_party/v8/include/v8.h" - -extern "C" { -// deno_s = Wrapped Isolate. -struct deno_s { - v8::Isolate* isolate; - const v8::FunctionCallbackInfo* currentArgs; - std::string last_exception; - v8::Persistent recv; - v8::Persistent global_error_handler; - v8::Persistent context; - deno_recv_cb cb; - void* data; -}; -} - -namespace deno { - -struct InternalFieldData { - uint32_t data; -}; - -void Print(const v8::FunctionCallbackInfo& args); -void Recv(const v8::FunctionCallbackInfo& args); -void Send(const v8::FunctionCallbackInfo& args); -void SetGlobalErrorHandler(const v8::FunctionCallbackInfo& args); -static intptr_t external_references[] = { - reinterpret_cast(Print), reinterpret_cast(Recv), - reinterpret_cast(Send), - reinterpret_cast(SetGlobalErrorHandler), 0}; - -Deno* NewFromSnapshot(void* data, deno_recv_cb cb); - -void InitializeContext(v8::Isolate* isolate, v8::Local context, - const char* js_filename, const std::string& js_source, - const std::string* source_map); - -void AddIsolate(Deno* d, v8::Isolate* isolate); - -} // namespace deno -#endif // INTERNAL_H_ diff --git a/libdeno/libdeno_test.cc b/libdeno/libdeno_test.cc deleted file mode 100644 index d3650788fd41de..00000000000000 --- a/libdeno/libdeno_test.cc +++ /dev/null @@ -1,207 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -#include "testing/gtest/include/gtest/gtest.h" - -#include "deno.h" - -TEST(LibDenoTest, InitializesCorrectly) { - Deno* d = deno_new(nullptr, nullptr); - EXPECT_TRUE(deno_execute(d, "a.js", "1 + 2")); - deno_delete(d); -} - -TEST(LibDenoTest, CanCallFunction) { - Deno* d = deno_new(nullptr, nullptr); - EXPECT_TRUE(deno_execute(d, "a.js", - "if (CanCallFunction() != 'foo') throw Error();")); - deno_delete(d); -} - -TEST(LibDenoTest, ErrorsCorrectly) { - Deno* d = deno_new(nullptr, nullptr); - EXPECT_FALSE(deno_execute(d, "a.js", "throw Error()")); - deno_delete(d); -} - -deno_buf strbuf(const char* str) { - auto len = strlen(str); - - deno_buf buf; - buf.alloc_ptr = reinterpret_cast(strdup(str)); - buf.alloc_len = len + 1; - buf.data_ptr = buf.alloc_ptr; - buf.data_len = len; - - return buf; -} - -// Same as strbuf but with null alloc_ptr. -deno_buf StrBufNullAllocPtr(const char* str) { - auto len = strlen(str); - deno_buf buf; - buf.alloc_ptr = nullptr; - buf.alloc_len = 0; - buf.data_ptr = reinterpret_cast(strdup(str)); - buf.data_len = len; - return buf; -} - -TEST(LibDenoTest, SendSuccess) { - Deno* d = deno_new(nullptr, nullptr); - EXPECT_TRUE(deno_execute(d, "a.js", "SendSuccess()")); - EXPECT_TRUE(deno_send(d, strbuf("abc"))); - deno_delete(d); -} - -TEST(LibDenoTest, SendWrongByteLength) { - Deno* d = deno_new(nullptr, nullptr); - EXPECT_TRUE(deno_execute(d, "a.js", "SendWrongByteLength()")); - // deno_send the wrong sized message, it should throw. - EXPECT_FALSE(deno_send(d, strbuf("abcd"))); - std::string exception = deno_last_exception(d); - EXPECT_GT(exception.length(), 1u); - EXPECT_NE(exception.find("assert"), std::string::npos); - deno_delete(d); -} - -TEST(LibDenoTest, SendNoCallback) { - Deno* d = deno_new(nullptr, nullptr); - // We didn't call deno.recv() in JS, should fail. - EXPECT_FALSE(deno_send(d, strbuf("abc"))); - deno_delete(d); -} - -TEST(LibDenoTest, RecvReturnEmpty) { - static int count = 0; - Deno* d = deno_new(nullptr, [](auto _, auto buf) { - count++; - EXPECT_EQ(static_cast(3), buf.data_len); - EXPECT_EQ(buf.data_ptr[0], 'a'); - EXPECT_EQ(buf.data_ptr[1], 'b'); - EXPECT_EQ(buf.data_ptr[2], 'c'); - }); - EXPECT_TRUE(deno_execute(d, "a.js", "RecvReturnEmpty()")); - EXPECT_EQ(count, 2); - deno_delete(d); -} - -TEST(LibDenoTest, RecvReturnBar) { - static int count = 0; - Deno* d = deno_new(nullptr, [](auto deno, auto buf) { - count++; - EXPECT_EQ(static_cast(3), buf.data_len); - EXPECT_EQ(buf.data_ptr[0], 'a'); - EXPECT_EQ(buf.data_ptr[1], 'b'); - EXPECT_EQ(buf.data_ptr[2], 'c'); - deno_set_response(deno, strbuf("bar")); - }); - EXPECT_TRUE(deno_execute(d, "a.js", "RecvReturnBar()")); - EXPECT_EQ(count, 1); - deno_delete(d); -} - -TEST(LibDenoTest, DoubleRecvFails) { - Deno* d = deno_new(nullptr, nullptr); - EXPECT_FALSE(deno_execute(d, "a.js", "DoubleRecvFails()")); - deno_delete(d); -} - -TEST(LibDenoTest, SendRecvSlice) { - static int count = 0; - Deno* d = deno_new(nullptr, [](auto deno, auto buf) { - static const size_t alloc_len = 1024; - size_t i = count++; - // Check the size and offset of the slice. - size_t data_offset = buf.data_ptr - buf.alloc_ptr; - EXPECT_EQ(data_offset, i * 11); - EXPECT_EQ(buf.data_len, alloc_len - i * 30); - EXPECT_EQ(buf.alloc_len, alloc_len); - // Check values written by the JS side. - EXPECT_EQ(buf.data_ptr[0], 100 + i); - EXPECT_EQ(buf.data_ptr[buf.data_len - 1], 100 - i); - // Make copy of the backing buffer -- this is currently necessary because - // deno_set_response() takes ownership over the buffer, but we are not given - // ownership of `buf` by our caller. - uint8_t* alloc_ptr = reinterpret_cast(malloc(alloc_len)); - memcpy(alloc_ptr, buf.alloc_ptr, alloc_len); - // Make a slice that is a bit shorter than the original. - deno_buf buf2{alloc_ptr, alloc_len, alloc_ptr + data_offset, - buf.data_len - 19}; - // Place some values into the buffer for the JS side to verify. - buf2.data_ptr[0] = 200 + i; - buf2.data_ptr[buf2.data_len - 1] = 200 - i; - // Send back. - deno_set_response(deno, buf2); - }); - EXPECT_TRUE(deno_execute(d, "a.js", "SendRecvSlice()")); - EXPECT_EQ(count, 5); - deno_delete(d); -} - -TEST(LibDenoTest, JSSendArrayBufferViewTypes) { - static int count = 0; - Deno* d = deno_new(nullptr, [](auto _, auto buf) { - count++; - size_t data_offset = buf.data_ptr - buf.alloc_ptr; - EXPECT_EQ(data_offset, 2468u); - EXPECT_EQ(buf.data_len, 1000u); - EXPECT_EQ(buf.alloc_len, 4321u); - EXPECT_EQ(buf.data_ptr[0], count); - }); - EXPECT_TRUE(deno_execute(d, "a.js", "JSSendArrayBufferViewTypes()")); - EXPECT_EQ(count, 3); - deno_delete(d); -} - -TEST(LibDenoTest, JSSendNeutersBuffer) { - static int count = 0; - Deno* d = deno_new(nullptr, [](auto _, auto buf) { - count++; - EXPECT_EQ(buf.data_len, 1u); - EXPECT_EQ(buf.data_ptr[0], 42); - }); - EXPECT_TRUE(deno_execute(d, "a.js", "JSSendNeutersBuffer()")); - EXPECT_EQ(count, 1); - deno_delete(d); -} - -TEST(LibDenoTest, TypedArraySnapshots) { - Deno* d = deno_new(nullptr, nullptr); - EXPECT_TRUE(deno_execute(d, "a.js", "TypedArraySnapshots()")); - deno_delete(d); -} - -TEST(LibDenoTest, SnapshotBug) { - Deno* d = deno_new(nullptr, nullptr); - EXPECT_TRUE(deno_execute(d, "a.js", "SnapshotBug()")); - deno_delete(d); -} - -TEST(LibDenoTest, GlobalErrorHandling) { - static int count = 0; - Deno* d = deno_new(nullptr, [](auto _, auto buf) { - count++; - EXPECT_EQ(static_cast(1), buf.data_len); - EXPECT_EQ(buf.data_ptr[0], 42); - }); - EXPECT_FALSE(deno_execute(d, "a.js", "GlobalErrorHandling()")); - EXPECT_EQ(count, 1); - deno_delete(d); -} - -TEST(LibDenoTest, DoubleGlobalErrorHandlingFails) { - Deno* d = deno_new(nullptr, nullptr); - EXPECT_FALSE(deno_execute(d, "a.js", "DoubleGlobalErrorHandlingFails()")); - deno_delete(d); -} - -TEST(LibDenoTest, SendNullAllocPtr) { - static int count = 0; - Deno* d = deno_new(nullptr, [](auto _, auto buf) { count++; }); - EXPECT_TRUE(deno_execute(d, "a.js", "SendNullAllocPtr()")); - deno_buf buf = StrBufNullAllocPtr("abcd"); - EXPECT_EQ(buf.alloc_ptr, nullptr); - EXPECT_EQ(buf.data_len, 4u); - EXPECT_TRUE(deno_send(d, buf)); - EXPECT_EQ(count, 0); - deno_delete(d); -} diff --git a/libdeno/libdeno_test.js b/libdeno/libdeno_test.js deleted file mode 100644 index d51973ef00e786..00000000000000 --- a/libdeno/libdeno_test.js +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. - -// A simple runtime that doesn't involve typescript or protobufs to test -// libdeno. Invoked by libdeno_test.cc - -const global = this; - -function assert(cond) { - if (!cond) throw Error("libdeno_test.js assert failed"); -} - -global.CanCallFunction = () => { - libdeno.print("Hello world from foo"); - return "foo"; -}; - -// This object is created to test snapshotting. -// See DeserializeInternalFieldsCallback and SerializeInternalFieldsCallback. -const snapshotted = new Uint8Array([1, 3, 3, 7]); - -global.TypedArraySnapshots = () => { - assert(snapshotted[0] === 1); - assert(snapshotted[1] === 3); - assert(snapshotted[2] === 3); - assert(snapshotted[3] === 7); -}; - -global.SendSuccess = () => { - libdeno.recv(msg => { - libdeno.print("SendSuccess: ok"); - }); -}; - -global.SendWrongByteLength = () => { - libdeno.recv(msg => { - assert(msg.byteLength === 3); - }); -}; - -global.RecvReturnEmpty = () => { - const m1 = new Uint8Array("abc".split("").map(c => c.charCodeAt(0))); - const m2 = m1.slice(); - const r1 = libdeno.send(m1); - assert(r1 == null); - const r2 = libdeno.send(m2); - assert(r2 == null); -}; - -global.RecvReturnBar = () => { - const m = new Uint8Array("abc".split("").map(c => c.charCodeAt(0))); - const r = libdeno.send(m); - assert(r instanceof Uint8Array); - assert(r.byteLength === 3); - const rstr = String.fromCharCode(...r); - assert(rstr === "bar"); -}; - -global.DoubleRecvFails = () => { - // libdeno.recv is an internal function and should only be called once from the - // runtime. - libdeno.recv((channel, msg) => assert(false)); - libdeno.recv((channel, msg) => assert(false)); -}; - -global.SendRecvSlice = () => { - const abLen = 1024; - let buf = new Uint8Array(abLen); - for (let i = 0; i < 5; i++) { - // Set first and last byte, for verification by the native side. - buf[0] = 100 + i; - buf[buf.length - 1] = 100 - i; - // On the native side, the slice is shortened by 19 bytes. - buf = libdeno.send(buf); - assert(buf.byteOffset === i * 11); - assert(buf.byteLength === abLen - i * 30 - 19); - assert(buf.buffer.byteLength == abLen); - // Look for values written by the backend. - assert(buf[0] === 200 + i); - assert(buf[buf.length - 1] === 200 - i); - // On the JS side, the start of the slice is moved up by 11 bytes. - buf = buf.subarray(11); - assert(buf.byteOffset === (i + 1) * 11); - assert(buf.byteLength === abLen - (i + 1) * 30); - } -}; - -global.JSSendArrayBufferViewTypes = () => { - // Test that ArrayBufferView slices are transferred correctly. - // Send Uint8Array. - const ab1 = new ArrayBuffer(4321); - const u8 = new Uint8Array(ab1, 2468, 1000); - u8[0] = 1; - libdeno.send(u8); - // Send Uint32Array. - const ab2 = new ArrayBuffer(4321); - const u32 = new Uint32Array(ab2, 2468, 1000 / Uint32Array.BYTES_PER_ELEMENT); - u32[0] = 0x02020202; - libdeno.send(u32); - // Send DataView. - const ab3 = new ArrayBuffer(4321); - const dv = new DataView(ab3, 2468, 1000); - dv.setUint8(0, 3); - libdeno.send(dv); -}; - -global.JSSendNeutersBuffer = () => { - // Buffer should be neutered after transferring it to the native side. - const u8 = new Uint8Array([42]); - assert(u8.byteLength === 1); - assert(u8.buffer.byteLength === 1); - assert(u8[0] === 42); - const r = libdeno.send(u8); - assert(u8.byteLength === 0); - assert(u8.buffer.byteLength === 0); - assert(u8[0] === undefined); -}; - -// The following join has caused SnapshotBug to segfault when using kKeep. -[].join(""); - -global.SnapshotBug = () => { - assert("1,2,3" === String([1, 2, 3])); -}; - -global.GlobalErrorHandling = () => { - libdeno.setGlobalErrorHandler((message, source, line, col, error) => { - libdeno.print(`line ${line} col ${col}`); - assert("ReferenceError: notdefined is not defined" === message); - assert(source === "helloworld.js"); - assert(line === 3); - assert(col === 1); - assert(error instanceof Error); - libdeno.send(new Uint8Array([42])); - }); - eval("\n\n notdefined()\n//# sourceURL=helloworld.js"); -}; - -global.DoubleGlobalErrorHandlingFails = () => { - libdeno.setGlobalErrorHandler((message, source, line, col, error) => {}); - libdeno.setGlobalErrorHandler((message, source, line, col, error) => {}); -}; - -global.SendNullAllocPtr = () => { - libdeno.recv(msg => { - assert(msg instanceof Uint8Array); - assert(msg.byteLength === 4); - assert(msg[0] === "a".charCodeAt(0)); - assert(msg[1] === "b".charCodeAt(0)); - assert(msg[2] === "c".charCodeAt(0)); - assert(msg[3] === "d".charCodeAt(0)); - }); -}; diff --git a/libdeno/snapshot_creator.cc b/libdeno/snapshot_creator.cc deleted file mode 100644 index 8038c9b13edbdd..00000000000000 --- a/libdeno/snapshot_creator.cc +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -// Hint: --trace_serializer is a useful debugging flag. -#include -#include "deno.h" -#include "file_util.h" -#include "internal.h" -#include "third_party/v8/include/v8.h" -#include "third_party/v8/src/base/logging.h" - -namespace deno { - -v8::StartupData SerializeInternalFields(v8::Local holder, int index, - void* data) { - DCHECK_EQ(data, nullptr); - InternalFieldData* embedder_field = static_cast( - holder->GetAlignedPointerFromInternalField(index)); - if (embedder_field == nullptr) return {nullptr, 0}; - int size = sizeof(*embedder_field); - char* payload = new char[size]; - // We simply use memcpy to serialize the content. - memcpy(payload, embedder_field, size); - return {payload, size}; -} - -v8::StartupData MakeSnapshot(const char* js_filename, - const std::string& js_source, - const std::string* source_map) { - auto* creator = new v8::SnapshotCreator(external_references); - auto* isolate = creator->GetIsolate(); - v8::Isolate::Scope isolate_scope(isolate); - { - v8::HandleScope handle_scope(isolate); - auto context = v8::Context::New(isolate); - InitializeContext(isolate, context, js_filename, js_source, source_map); - creator->SetDefaultContext(context, v8::SerializeInternalFieldsCallback( - SerializeInternalFields, nullptr)); - } - - auto snapshot_blob = - creator->CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear); - - return snapshot_blob; -} - -} // namespace deno - -int main(int argc, char** argv) { - const char* snapshot_out_bin = argv[1]; - const char* js_fn = argv[2]; - const char* source_map_fn = argv[3]; // Optional. - - v8::V8::SetFlagsFromCommandLine(&argc, argv, true); - - CHECK_NE(js_fn, nullptr); - CHECK_NE(snapshot_out_bin, nullptr); - - std::string js_source; - CHECK(deno::ReadFileToString(js_fn, &js_source)); - - std::string source_map; - if (source_map_fn != nullptr) { - CHECK_EQ(argc, 4); - CHECK(deno::ReadFileToString(source_map_fn, &source_map)); - } - - deno_init(); - auto snapshot_blob = deno::MakeSnapshot( - js_fn, js_source, source_map_fn != nullptr ? &source_map : nullptr); - std::string snapshot_str(snapshot_blob.data, snapshot_blob.raw_size); - - std::ofstream file_(snapshot_out_bin, std::ios::binary); - file_ << snapshot_str; - file_.close(); - return file_.bad(); -} diff --git a/libdeno/test.cc b/libdeno/test.cc deleted file mode 100644 index 9638dba609653d..00000000000000 --- a/libdeno/test.cc +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -#include "deno.h" -#include "testing/gtest/include/gtest/gtest.h" - -int main(int argc, char** argv) { - testing::InitGoogleTest(&argc, argv); - deno_init(); - deno_set_flags(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/node_modules b/node_modules deleted file mode 120000 index 25d92e47eb6757..00000000000000 --- a/node_modules +++ /dev/null @@ -1 +0,0 @@ -third_party/node_modules \ No newline at end of file diff --git a/package.json b/package.json deleted file mode 100644 index fe00a29165199e..00000000000000 --- a/package.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "name": "deno", - "devDependencies": { - "@types/base64-js": "^1.2.5", - "@types/flatbuffers": "^1.9.0", - "@types/source-map-support": "^0.4.1", - "@types/text-encoding": "0.0.33", - "base64-js": "^1.3.0", - "flatbuffers": "^1.9.0", - "prettier": "^1.14.0", - "rollup": "^0.63.2", - "rollup-plugin-alias": "^1.4.0", - "rollup-plugin-analyzer": "^2.1.0", - "rollup-plugin-commonjs": "^9.1.3", - "rollup-plugin-node-globals": "^1.2.1", - "rollup-plugin-node-resolve": "^3.3.0", - "rollup-plugin-string": "^2.0.2", - "rollup-plugin-typescript2": "^0.16.1", - "rollup-pluginutils": "^2.3.0", - "source-map-support": "^0.5.6", - "text-encoding": "0.6.4", - "tslint": "^5.10.0", - "tslint-eslint-rules": "^5.3.1", - "tslint-no-circular-imports": "^0.5.0", - "typescript": "3.0.1" - } -} diff --git a/rollup.config.js b/rollup.config.js deleted file mode 100644 index 0f0e5a3e1dda9f..00000000000000 --- a/rollup.config.js +++ /dev/null @@ -1,217 +0,0 @@ -import path from "path"; -import alias from "rollup-plugin-alias"; -import { plugin as analyze } from "rollup-plugin-analyzer"; -import commonjs from "rollup-plugin-commonjs"; -import globals from "rollup-plugin-node-globals"; -import nodeResolve from "rollup-plugin-node-resolve"; -import typescriptPlugin from "rollup-plugin-typescript2"; -import { createFilter } from "rollup-pluginutils"; -import typescript from "typescript"; - -const mockPath = path.join(__dirname, "js", "mock_builtin.js"); -const tsconfig = path.join(__dirname, "tsconfig.json"); -const typescriptPath = `${ - process.env.BASEPATH -}/third_party/node_modules/typescript/lib/typescript.js`; - -// We will allow generated modules to be resolvable by TypeScript based on -// the current build path -const tsconfigOverride = { - compilerOptions: { - paths: { - "*": ["*", path.join(process.cwd(), "*")] - } - } -}; - -// when the build path is not a child of the root of the project path -// TypeScript will output resources following the same path structure, -// `BASEPATH` will be a relative path to the root of the source project which -// we can use to determine what TypeScript would have output -const basePathParts = process.env.BASEPATH.split("/"); -while (basePathParts[0] === "..") { - basePathParts.shift(); -} - -// this is a rollup plugin which will look for imports ending with `!string` and resolve -// them with a module that will inline the contents of the file as a string. Needed to -// support `js/assets.ts`. -function strings({ include, exclude } = {}) { - if (!include) { - throw new Error("include option must be passed"); - } - - const filter = createFilter(include, exclude); - - return { - name: "strings", - - /** - * @param {string} importee - */ - resolveId(importee) { - if (importee.endsWith("!string")) { - // strip the `!string` from `importee` - importee = importee.slice(0, importee.lastIndexOf("!string")); - if (!importee.startsWith("gen/")) { - // this is a static asset which is located relative to the root of the source project - return path.resolve(path.join(process.env.BASEPATH, importee)); - } - // ignoring the first part, which is "gen" - const [, ...importeeParts] = importee.split("/"); - // generated assets will be output by TypeScript relative between the build path and the - // root of the project. For example on Travis, the project path is: - // /home/travis/build/denoland/deno/ - // and the build path is: - // /home/travis/out/Default/ - // TypeScript will then output `globals.d.ts` from `js/globals.ts` to: - // /home/travis/out/Default/gen/build/denoland/deno/js/globals.d.ts - // therefore we need to insert any non relative BASEPATH parts into - // the final module ID - return path.resolve( - path.join(process.cwd(), "gen", ...basePathParts, ...importeeParts) - ); - } - }, - - /** - * @param {any} code - * @param {string} id - */ - transform(code, id) { - if (filter(id)) { - return { - code: `export default ${JSON.stringify(code)};`, - map: { mappings: "" } - }; - } - } - }; -} - -// This plugin resolves at bundle time any generated resources that are -// in the build path under `gen` and specified with a MID starting with `gen/`. -// The plugin assumes that the MID needs to have the `.ts` extension appended. -function resolveGenerated() { - return { - name: "resolve-msg-generated", - resolveId(importee) { - if (importee.startsWith("gen/")) { - const resolved = path.resolve( - path.join(process.cwd(), `${importee}.ts`) - ); - return resolved; - } - } - }; -} - -export default function makeConfig(commandOptions) { - return { - output: { - format: "iife", - name: "denoMain", - sourcemap: true - }, - - plugins: [ - // would prefer to use `rollup-plugin-virtual` to inject the empty module, but there - // is an issue with `rollup-plugin-commonjs` which causes errors when using the - // virtual plugin (see: rollup/rollup-plugin-commonjs#315), this means we have to use - // a physical module to substitute - alias({ - fs: mockPath, - path: mockPath, - os: mockPath, - crypto: mockPath, - buffer: mockPath, - module: mockPath - }), - - // Provides inlining of file contents for `js/assets.ts` - strings({ - include: [ - "*.d.ts", - `${__dirname}/**/*.d.ts`, - `${process.cwd()}/**/*.d.ts` - ] - }), - - // Resolves any resources that have been generated at build time - resolveGenerated(), - - // Allows rollup to resolve modules based on Node.js resolution - nodeResolve({ - jsnext: true, - main: true - }), - - // Allows rollup to import CommonJS modules - commonjs({ - namedExports: { - // Static analysis of `typescript.js` does detect the exports properly, therefore - // rollup requires them to be explicitly defined to avoid generating warnings - [typescriptPath]: [ - "createLanguageService", - "formatDiagnosticsWithColorAndContext", - "ModuleKind", - "ScriptSnapshot", - "ScriptTarget", - "version" - ] - } - }), - - typescriptPlugin({ - // The build script is invoked from `out/:target` so passing an absolute file path is needed - tsconfig, - - // This provides any overrides to the `tsconfig.json` that are needed to bundle - tsconfigOverride, - - // This provides the locally configured version of TypeScript instead of the plugins - // default version - typescript, - - // By default, the include path only includes the cwd and below, need to include the root of the project - // and build path to be passed to this plugin. This is different front tsconfig.json include - include: ["*.ts", `${__dirname}/**/*.ts`, `${process.cwd()}/**/*.ts`], - - // d.ts files are not bundled and by default like include, it only includes the cwd and below - exclude: [ - "*.d.ts", - `${__dirname}/**/*.d.ts`, - `${process.cwd()}/**/*.d.ts` - ] - }), - - // Provide some concise information about the bundle - analyze({ - skipFormatted: true, - onAnalysis({ - bundleSize, - bundleOrigSize, - bundleReduction, - moduleCount - }) { - if (!commandOptions.silent) { - console.log( - `Bundle size: ${Math.round((bundleSize / 1000000) * 100) / 100}Mb` - ); - console.log( - `Original size: ${Math.round((bundleOrigSize / 1000000) * 100) / - 100}Mb` - ); - console.log(`Reduction: ${bundleReduction}%`); - console.log(`Module count: ${moduleCount}`); - } - } - }), - - // source-map-support, which is required by TypeScript to support source maps, requires Node.js Buffer - // implementation. This needs to come at the end of the plugins because of the impact it has on - // the existing runtime environment, which breaks other plugins and features of the bundler. - globals() - ] - }; -} diff --git a/src/binding.rs b/src/binding.rs deleted file mode 100644 index 9789fc4e09df6b..00000000000000 --- a/src/binding.rs +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -#![allow(dead_code)] -extern crate libc; -use libc::c_char; -use libc::c_int; -use libc::c_void; - -#[repr(C)] -pub struct DenoC { - _unused: [u8; 0], -} - -#[repr(C)] -#[derive(PartialEq)] -pub struct deno_buf { - pub alloc_ptr: *mut u8, - pub alloc_len: usize, - pub data_ptr: *mut u8, - pub data_len: usize, -} - -type DenoRecvCb = unsafe extern "C" fn(d: *const DenoC, buf: deno_buf); - -extern "C" { - pub fn deno_init(); - pub fn deno_v8_version() -> *const c_char; - pub fn deno_set_flags(argc: *mut c_int, argv: *mut *mut c_char); - pub fn deno_new(data: *const c_void, cb: DenoRecvCb) -> *const DenoC; - pub fn deno_delete(d: *const DenoC); - pub fn deno_last_exception(d: *const DenoC) -> *const c_char; - pub fn deno_get_data(d: *const DenoC) -> *const c_void; - pub fn deno_set_response(d: *const DenoC, buf: deno_buf); - pub fn deno_send(d: *const DenoC, buf: deno_buf); - pub fn deno_execute( - d: *const DenoC, - js_filename: *const c_char, - js_source: *const c_char, - ) -> c_int; -} diff --git a/src/deno_dir.rs b/src/deno_dir.rs deleted file mode 100644 index 0a3557d5b3c192..00000000000000 --- a/src/deno_dir.rs +++ /dev/null @@ -1,488 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -use errors::DenoError; -use errors::DenoResult; -use fs as deno_fs; -use net; -use ring; -use std; -use std::fmt::Write; -use std::fs; -use std::path::Path; -use std::path::PathBuf; -use std::result::Result; -#[cfg(test)] -use tempfile::TempDir; -use url; -use url::Url; - -pub struct DenoDir { - // Example: /Users/rld/.deno/ - pub root: PathBuf, - // In the Go code this was called SrcDir. - // This is where we cache http resources. Example: - // /Users/rld/.deno/deps/github.com/ry/blah.js - pub gen: PathBuf, - // In the Go code this was called CacheDir. - // This is where we cache compilation outputs. Example: - // /Users/rld/.deno/gen/f39a473452321cacd7c346a870efb0e3e1264b43.js - pub deps: PathBuf, - // If remote resources should be reloaded. - reload: bool, -} - -impl DenoDir { - // Must be called before using any function from this module. - // https://github.com/denoland/deno/blob/golang/deno_dir.go#L99-L111 - pub fn new( - reload: bool, - custom_root: Option<&Path>, - ) -> std::io::Result { - // Only setup once. - let home_dir = std::env::home_dir().expect("Could not get home directory."); - let default = home_dir.join(".deno"); - - let root: PathBuf = match custom_root { - None => default, - Some(path) => path.to_path_buf(), - }; - let gen = root.as_path().join("gen"); - let deps = root.as_path().join("deps"); - - let deno_dir = DenoDir { - root, - gen, - deps, - reload, - }; - deno_fs::mkdir(deno_dir.gen.as_ref())?; - deno_fs::mkdir(deno_dir.deps.as_ref())?; - - debug!("root {}", deno_dir.root.display()); - debug!("gen {}", deno_dir.gen.display()); - debug!("deps {}", deno_dir.deps.display()); - - Ok(deno_dir) - } - - // https://github.com/denoland/deno/blob/golang/deno_dir.go#L32-L35 - pub fn cache_path( - self: &DenoDir, - filename: &str, - source_code: &str, - ) -> PathBuf { - let cache_key = source_code_hash(filename, source_code); - self.gen.join(cache_key + ".js") - } - - fn load_cache( - self: &DenoDir, - filename: &str, - source_code: &str, - ) -> std::io::Result { - let path = self.cache_path(filename, source_code); - debug!("load_cache {}", path.display()); - fs::read_to_string(&path) - } - - pub fn code_cache( - self: &DenoDir, - filename: &str, - source_code: &str, - output_code: &str, - ) -> std::io::Result<()> { - let cache_path = self.cache_path(filename, source_code); - // TODO(ry) This is a race condition w.r.t to exists() -- probably should - // create the file in exclusive mode. A worry is what might happen is there - // are two processes and one reads the cache file while the other is in the - // midst of writing it. - if cache_path.exists() { - Ok(()) - } else { - fs::write(cache_path, output_code.as_bytes()) - } - } - - // Prototype https://github.com/denoland/deno/blob/golang/deno_dir.go#L37-L73 - fn fetch_remote_source( - self: &DenoDir, - module_name: &str, - filename: &str, - ) -> DenoResult { - let p = Path::new(filename); - - let src = if self.reload || !p.exists() { - println!("Downloading {}", module_name); - let source = net::fetch_sync_string(module_name)?; - match p.parent() { - Some(ref parent) => fs::create_dir_all(parent), - None => Ok(()), - }?; - deno_fs::write_file_sync(&p, source.as_bytes())?; - source - } else { - let source = fs::read_to_string(&p)?; - source - }; - Ok(src) - } - - // Prototype: https://github.com/denoland/deno/blob/golang/os.go#L122-L138 - fn get_source_code( - self: &DenoDir, - module_name: &str, - filename: &str, - ) -> DenoResult { - if is_remote(module_name) { - self.fetch_remote_source(module_name, filename) - } else if module_name.starts_with(ASSET_PREFIX) { - panic!("Asset resolution should be done in JS, not Rust."); - } else { - assert!( - module_name == filename, - "if a module isn't remote, it should have the same filename" - ); - let src = fs::read_to_string(Path::new(filename))?; - Ok(src) - } - } - - pub fn code_fetch( - self: &DenoDir, - module_specifier: &str, - containing_file: &str, - ) -> Result { - let (module_name, filename) = - self.resolve_module(module_specifier, containing_file)?; - - debug!( - "code_fetch. module_name = {} module_specifier = {} containing_file = {} filename = {}", - module_name, module_specifier, containing_file, filename - ); - - let out = self - .get_source_code(module_name.as_str(), filename.as_str()) - .and_then(|source_code| { - Ok(CodeFetchOutput { - module_name, - filename, - source_code, - maybe_output_code: None, - }) - })?; - - let result = - self.load_cache(out.filename.as_str(), out.source_code.as_str()); - match result { - Err(err) => { - if err.kind() == std::io::ErrorKind::NotFound { - Ok(out) - } else { - Err(err.into()) - } - } - Ok(output_code) => Ok(CodeFetchOutput { - module_name: out.module_name, - filename: out.filename, - source_code: out.source_code, - maybe_output_code: Some(output_code), - }), - } - } - - // Prototype: https://github.com/denoland/deno/blob/golang/os.go#L56-L68 - #[allow(dead_code)] - fn src_file_to_url>(self: &DenoDir, filename: P) -> String { - let filename = filename.as_ref().to_path_buf(); - if filename.starts_with(&self.deps) { - let rest = filename.strip_prefix(&self.deps).unwrap(); - "http://".to_string() + rest.to_str().unwrap() - } else { - String::from(filename.to_str().unwrap()) - } - } - - // Prototype: https://github.com/denoland/deno/blob/golang/os.go#L70-L98 - // Returns (module name, local filename) - fn resolve_module( - self: &DenoDir, - module_specifier: &str, - containing_file: &str, - ) -> Result<(String, String), url::ParseError> { - let module_name; - let filename; - - debug!( - "resolve_module before module_specifier {} containing_file {}", - module_specifier, containing_file - ); - - //let module_specifier = src_file_to_url(module_specifier); - //let containing_file = src_file_to_url(containing_file); - //let base_url = Url::parse(&containing_file)?; - - let j: Url = - if containing_file == "." || Path::new(module_specifier).is_absolute() { - if module_specifier.starts_with("http://") { - Url::parse(module_specifier)? - } else { - Url::from_file_path(module_specifier).unwrap() - } - } else if containing_file.ends_with("/") { - let r = Url::from_directory_path(&containing_file); - // TODO(ry) Properly handle error. - if r.is_err() { - error!("Url::from_directory_path error {}", containing_file); - } - let base = r.unwrap(); - base.join(module_specifier)? - } else { - let r = Url::from_file_path(&containing_file); - // TODO(ry) Properly handle error. - if r.is_err() { - error!("Url::from_file_path error {}", containing_file); - } - let base = r.unwrap(); - base.join(module_specifier)? - }; - - match j.scheme() { - "file" => { - let mut p = deno_fs::normalize_path(j.to_file_path().unwrap().as_ref()); - module_name = p.clone(); - filename = p; - } - _ => { - module_name = module_specifier.to_string(); - filename = deno_fs::normalize_path( - get_cache_filename(self.deps.as_path(), j).as_ref(), - ) - } - } - - debug!("module_name: {}, filename: {}", module_name, filename); - Ok((module_name, filename)) - } -} - -fn get_cache_filename(basedir: &Path, url: Url) -> PathBuf { - let mut out = basedir.to_path_buf(); - out.push(url.host_str().unwrap()); - for path_seg in url.path_segments().unwrap() { - out.push(path_seg); - } - out -} - -#[test] -fn test_get_cache_filename() { - let url = Url::parse("http://example.com:1234/path/to/file.ts").unwrap(); - let basedir = Path::new("/cache/dir/"); - let cache_file = get_cache_filename(&basedir, url); - assert_eq!( - cache_file, - Path::new("/cache/dir/example.com/path/to/file.ts") - ); -} - -#[derive(Debug)] -pub struct CodeFetchOutput { - pub module_name: String, - pub filename: String, - pub source_code: String, - pub maybe_output_code: Option, -} - -#[cfg(test)] -pub fn test_setup() -> (TempDir, DenoDir) { - let temp_dir = TempDir::new().expect("tempdir fail"); - let deno_dir = - DenoDir::new(false, Some(temp_dir.path())).expect("setup fail"); - (temp_dir, deno_dir) -} - -#[test] -fn test_cache_path() { - let (temp_dir, deno_dir) = test_setup(); - assert_eq!( - temp_dir - .path() - .join("gen/a3e29aece8d35a19bf9da2bb1c086af71fb36ed5.js"), - deno_dir.cache_path("hello.ts", "1+2") - ); -} - -#[test] -fn test_code_cache() { - let (_temp_dir, deno_dir) = test_setup(); - - let filename = "hello.js"; - let source_code = "1+2"; - let output_code = "1+2 // output code"; - let cache_path = deno_dir.cache_path(filename, source_code); - assert!( - cache_path.ends_with("gen/e8e3ee6bee4aef2ec63f6ec3db7fc5fdfae910ae.js") - ); - - let r = deno_dir.code_cache(filename, source_code, output_code); - r.expect("code_cache error"); - assert!(cache_path.exists()); - assert_eq!(output_code, fs::read_to_string(&cache_path).unwrap()); -} - -// https://github.com/denoland/deno/blob/golang/deno_dir.go#L25-L30 -fn source_code_hash(filename: &str, source_code: &str) -> String { - let mut ctx = ring::digest::Context::new(&ring::digest::SHA1); - ctx.update(filename.as_bytes()); - ctx.update(source_code.as_bytes()); - let digest = ctx.finish(); - let mut out = String::new(); - // TODO There must be a better way to do this... - for byte in digest.as_ref() { - write!(&mut out, "{:02x}", byte).unwrap(); - } - out -} - -#[test] -fn test_source_code_hash() { - assert_eq!( - "a3e29aece8d35a19bf9da2bb1c086af71fb36ed5", - source_code_hash("hello.ts", "1+2") - ); - // Different source_code should result in different hash. - assert_eq!( - "914352911fc9c85170908ede3df1128d690dda41", - source_code_hash("hello.ts", "1") - ); - // Different filename should result in different hash. - assert_eq!( - "2e396bc66101ecc642db27507048376d972b1b70", - source_code_hash("hi.ts", "1+2") - ); -} - -// The `add_root` macro prepends "C:" to a string if on windows; on posix -// systems it returns the input string untouched. This is necessary because -// `Url::from_file_path()` fails if the input path isn't an absolute path. -#[cfg(test)] -macro_rules! add_root { - ($path:expr) => { - if cfg!(target_os = "windows") { - concat!("C:", $path) - } else { - $path - } - }; -} - -#[test] -fn test_code_fetch() { - let (_temp_dir, deno_dir) = test_setup(); - - let cwd = std::env::current_dir().unwrap(); - let cwd_string = String::from(cwd.to_str().unwrap()) + "/"; - - // Test failure case. - let module_specifier = "hello.ts"; - let containing_file = add_root!("/baddir/badfile.ts"); - let r = deno_dir.code_fetch(module_specifier, containing_file); - assert!(r.is_err()); - - // Assuming cwd is the deno repo root. - let module_specifier = "./js/main.ts"; - let containing_file = cwd_string.as_str(); - let r = deno_dir.code_fetch(module_specifier, containing_file); - assert!(r.is_ok()); - //let code_fetch_output = r.unwrap(); - //println!("code_fetch_output {:?}", code_fetch_output); -} - -#[test] -fn test_src_file_to_url() { - let (_temp_dir, deno_dir) = test_setup(); - assert_eq!("hello", deno_dir.src_file_to_url("hello")); - assert_eq!("/hello", deno_dir.src_file_to_url("/hello")); - let x = String::from(deno_dir.deps.join("hello/world.txt").to_str().unwrap()); - assert_eq!("http://hello/world.txt", deno_dir.src_file_to_url(x)); -} - -// https://github.com/denoland/deno/blob/golang/os_test.go#L16-L87 -#[test] -fn test_resolve_module() { - let (_temp_dir, deno_dir) = test_setup(); - - let d = deno_fs::normalize_path( - deno_dir - .deps - .join("localhost/testdata/subdir/print_hello.ts") - .as_ref(), - ); - - let test_cases = [ - ( - "./subdir/print_hello.ts", - add_root!( - "/Users/rld/go/src/github.com/denoland/deno/testdata/006_url_imports.ts" - ), - add_root!( - "/Users/rld/go/src/github.com/denoland/deno/testdata/subdir/print_hello.ts" - ), - add_root!( - "/Users/rld/go/src/github.com/denoland/deno/testdata/subdir/print_hello.ts" - ), - ), - ( - "testdata/001_hello.js", - add_root!("/Users/rld/go/src/github.com/denoland/deno/"), - add_root!("/Users/rld/go/src/github.com/denoland/deno/testdata/001_hello.js"), - add_root!("/Users/rld/go/src/github.com/denoland/deno/testdata/001_hello.js"), - ), - ( - add_root!("/Users/rld/src/deno/hello.js"), - ".", - add_root!("/Users/rld/src/deno/hello.js"), - add_root!("/Users/rld/src/deno/hello.js"), - ), - ( - add_root!("/this/module/got/imported.js"), - add_root!("/that/module/did/it.js"), - add_root!("/this/module/got/imported.js"), - add_root!("/this/module/got/imported.js"), - ), - ( - "http://localhost:4545/testdata/subdir/print_hello.ts", - add_root!("/Users/rld/go/src/github.com/denoland/deno/testdata/006_url_imports.ts"), - "http://localhost:4545/testdata/subdir/print_hello.ts", - d.as_ref(), - ), - /* - ( - path.Join(SrcDir, "unpkg.com/liltest@0.0.5/index.ts"), - ".", - "http://unpkg.com/liltest@0.0.5/index.ts", - path.Join(SrcDir, "unpkg.com/liltest@0.0.5/index.ts"), - ), - ( - "./util", - path.Join(SrcDir, "unpkg.com/liltest@0.0.5/index.ts"), - "http://unpkg.com/liltest@0.0.5/util", - path.Join(SrcDir, "unpkg.com/liltest@0.0.5/util"), - ), - */ - ]; - for &test in test_cases.iter() { - let module_specifier = String::from(test.0); - let containing_file = String::from(test.1); - let (module_name, filename) = deno_dir - .resolve_module(&module_specifier, &containing_file) - .unwrap(); - assert_eq!(module_name, test.2); - assert_eq!(filename, test.3); - } -} - -const ASSET_PREFIX: &str = "/$asset$/"; - -fn is_remote(module_name: &str) -> bool { - module_name.starts_with("http") -} diff --git a/src/errors.rs b/src/errors.rs deleted file mode 100644 index 2fcb2619329adb..00000000000000 --- a/src/errors.rs +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -use hyper; -use msg_generated::deno as msg; -use std; -use std::fmt; -use std::io; -use url; - -pub use self::msg::ErrorKind; - -pub type DenoResult = std::result::Result; - -#[derive(Debug)] -pub struct DenoError { - repr: Repr, -} - -#[derive(Debug)] -enum Repr { - // Simple(ErrorKind), - IoErr(io::Error), - UrlErr(url::ParseError), - HyperErr(hyper::Error), -} - -impl DenoError { - pub fn kind(&self) -> ErrorKind { - match self.repr { - // Repr::Simple(kind) => kind, - Repr::IoErr(ref err) => { - use std::io::ErrorKind::*; - match err.kind() { - NotFound => ErrorKind::NotFound, - PermissionDenied => ErrorKind::PermissionDenied, - ConnectionRefused => ErrorKind::ConnectionRefused, - ConnectionReset => ErrorKind::ConnectionReset, - ConnectionAborted => ErrorKind::ConnectionAborted, - NotConnected => ErrorKind::NotConnected, - AddrInUse => ErrorKind::AddrInUse, - AddrNotAvailable => ErrorKind::AddrNotAvailable, - BrokenPipe => ErrorKind::BrokenPipe, - AlreadyExists => ErrorKind::AlreadyExists, - WouldBlock => ErrorKind::WouldBlock, - InvalidInput => ErrorKind::InvalidInput, - InvalidData => ErrorKind::InvalidData, - TimedOut => ErrorKind::TimedOut, - Interrupted => ErrorKind::Interrupted, - WriteZero => ErrorKind::WriteZero, - Other => ErrorKind::Other, - UnexpectedEof => ErrorKind::UnexpectedEof, - _ => unreachable!(), - } - } - Repr::UrlErr(ref err) => { - use url::ParseError::*; - match err { - EmptyHost => ErrorKind::EmptyHost, - IdnaError => ErrorKind::IdnaError, - InvalidPort => ErrorKind::InvalidPort, - InvalidIpv4Address => ErrorKind::InvalidIpv4Address, - InvalidIpv6Address => ErrorKind::InvalidIpv6Address, - InvalidDomainCharacter => ErrorKind::InvalidDomainCharacter, - RelativeUrlWithoutBase => ErrorKind::RelativeUrlWithoutBase, - RelativeUrlWithCannotBeABaseBase => { - ErrorKind::RelativeUrlWithCannotBeABaseBase - } - SetHostOnCannotBeABaseUrl => ErrorKind::SetHostOnCannotBeABaseUrl, - Overflow => ErrorKind::Overflow, - } - } - Repr::HyperErr(ref err) => { - // For some reason hyper::errors::Kind is private. - if err.is_parse() { - ErrorKind::HttpParse - } else if err.is_user() { - ErrorKind::HttpUser - } else if err.is_canceled() { - ErrorKind::HttpCanceled - } else if err.is_closed() { - ErrorKind::HttpClosed - } else { - ErrorKind::HttpOther - } - } - } - } -} - -impl fmt::Display for DenoError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self.repr { - Repr::IoErr(ref err) => err.fmt(f), - Repr::UrlErr(ref err) => err.fmt(f), - Repr::HyperErr(ref err) => err.fmt(f), - // Repr::Simple(..) => Ok(()), - } - } -} - -impl std::error::Error for DenoError { - fn description(&self) -> &str { - match self.repr { - Repr::IoErr(ref err) => err.description(), - Repr::UrlErr(ref err) => err.description(), - Repr::HyperErr(ref err) => err.description(), - // Repr::Simple(..) => "FIXME", - } - } - - fn cause(&self) -> Option<&std::error::Error> { - match self.repr { - Repr::IoErr(ref err) => Some(err), - Repr::UrlErr(ref err) => Some(err), - Repr::HyperErr(ref err) => Some(err), - // Repr::Simple(..) => None, - } - } -} - -impl From for DenoError { - #[inline] - fn from(err: io::Error) -> DenoError { - DenoError { - repr: Repr::IoErr(err), - } - } -} - -impl From for DenoError { - #[inline] - fn from(err: url::ParseError) -> DenoError { - DenoError { - repr: Repr::UrlErr(err), - } - } -} - -impl From for DenoError { - #[inline] - fn from(err: hyper::Error) -> DenoError { - DenoError { - repr: Repr::HyperErr(err), - } - } -} diff --git a/src/flags.rs b/src/flags.rs deleted file mode 100644 index 7149ab19f82f52..00000000000000 --- a/src/flags.rs +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -use binding; -use libc::c_int; -use std::ffi::CStr; -use std::ffi::CString; -use std::mem; - -// Creates vector of strings, Vec -#[cfg(test)] -macro_rules! svec { - ($($x:expr),*) => (vec![$($x.to_string()),*]); -} - -#[derive(Debug, PartialEq)] -pub struct DenoFlags { - pub help: bool, - pub log_debug: bool, - pub version: bool, - pub reload: bool, - pub allow_write: bool, - pub allow_net: bool, -} - -pub fn print_usage() { - println!( - "Usage: deno script.ts - ---allow-write Allow file system write access. ---allow-net Allow network access. --v or --version Print the version. --r or --reload Reload cached remote resources. --D or --log-debug Log debug output. ---help Print this message. ---v8-options Print V8 command line options." - ); -} - -// Parses flags for deno. This does not do v8_set_flags() - call that separately. -pub fn set_flags(args: Vec) -> (DenoFlags, Vec) { - let mut flags = DenoFlags { - help: false, - version: false, - reload: false, - log_debug: false, - allow_write: false, - allow_net: false, - }; - let mut rest = Vec::new(); - for a in &args { - match a.as_str() { - "-h" | "--help" => flags.help = true, - "-D" | "--log-debug" => flags.log_debug = true, - "-v" | "--version" => flags.version = true, - "-r" | "--reload" => flags.reload = true, - "--allow-write" => flags.allow_write = true, - "--allow-net" => flags.allow_net = true, - _ => rest.push(a.clone()), - } - } - - return (flags, rest); -} - -#[test] -fn test_set_flags_1() { - let (flags, rest) = set_flags(svec!["deno", "--version"]); - assert!(rest == svec!["deno"]); - assert!( - flags == DenoFlags { - help: false, - log_debug: false, - version: true, - reload: false, - allow_write: false, - allow_net: false, - } - ); -} - -#[test] -fn test_set_flags_2() { - let (flags, rest) = set_flags(svec!["deno", "-r", "-D", "script.ts"]); - assert!(rest == svec!["deno", "script.ts"]); - assert!( - flags == DenoFlags { - help: false, - log_debug: true, - version: false, - reload: true, - allow_write: false, - allow_net: false, - } - ); -} - -#[test] -fn test_set_flags_3() { - let (flags, rest) = - set_flags(svec!["deno", "-r", "script.ts", "--allow-write"]); - assert!(rest == svec!["deno", "script.ts"]); - assert!( - flags == DenoFlags { - help: false, - log_debug: false, - version: false, - reload: true, - allow_write: true, - allow_net: false, - } - ); -} - -// Returns args passed to V8, followed by args passed to JS -// TODO Rename to v8_set_flags_preprocess -fn parse_core_args(args: Vec) -> (Vec, Vec) { - let mut rest = vec![]; - - // Filter out args that shouldn't be passed to V8 - let mut args: Vec = args - .into_iter() - .filter(|arg| { - if arg.as_str() == "--help" { - rest.push(arg.clone()); - return false; - } - - true - }) - .collect(); - - // Replace args being sent to V8 - for idx in 0..args.len() { - if args[idx] == "--v8-options" { - mem::swap(args.get_mut(idx).unwrap(), &mut String::from("--help")); - } - } - - (args, rest) -} - -#[test] -fn test_parse_core_args_1() { - let js_args = - parse_core_args(vec!["deno".to_string(), "--v8-options".to_string()]); - assert!(js_args == (vec!["deno".to_string(), "--help".to_string()], vec![])); -} - -#[test] -fn test_parse_core_args_2() { - let js_args = parse_core_args(vec!["deno".to_string(), "--help".to_string()]); - assert!(js_args == (vec!["deno".to_string()], vec!["--help".to_string()])); -} - -// Pass the command line arguments to v8. -// Returns a vector of command line arguments that v8 did not understand. -pub fn v8_set_flags(args: Vec) -> Vec { - // deno_set_flags(int* argc, char** argv) mutates argc and argv to remove - // flags that v8 understands. - // First parse core args, then converto to a vector of C strings. - let (argv, rest) = parse_core_args(args); - let mut argv = argv - .iter() - .map(|arg| CString::new(arg.as_str()).unwrap().into_bytes_with_nul()) - .collect::>(); - - // Make a new array, that can be modified by V8::SetFlagsFromCommandLine(), - // containing mutable raw pointers to the individual command line args. - let mut c_argv = argv - .iter_mut() - .map(|arg| arg.as_mut_ptr() as *mut i8) - .collect::>(); - // Store the length of the argv array in a local variable. We'll pass a - // pointer to this local variable to deno_set_flags(), which then - // updates its value. - let mut c_argc = c_argv.len() as c_int; - // Let v8 parse the arguments it recognizes and remove them from c_argv. - unsafe { - // TODO(ry) Rename deno_set_flags to deno_set_v8_flags(). - binding::deno_set_flags(&mut c_argc, c_argv.as_mut_ptr()); - }; - // If c_argc was updated we have to change the length of c_argv to match. - c_argv.truncate(c_argc as usize); - // Copy the modified arguments list into a proper rust vec and return it. - c_argv - .iter() - .map(|ptr| unsafe { - let cstr = CStr::from_ptr(*ptr as *const i8); - let slice = cstr.to_str().unwrap(); - slice.to_string() - }) - .chain(rest.into_iter()) - .collect() -} diff --git a/src/fs.rs b/src/fs.rs deleted file mode 100644 index 9290d94e5b55b6..00000000000000 --- a/src/fs.rs +++ /dev/null @@ -1,60 +0,0 @@ -use std; -use std::fs::{create_dir, File}; -use std::io::ErrorKind; -use std::io::Write; -use std::path::{Path, PathBuf}; - -use rand; -use rand::Rng; - -pub fn write_file_sync(path: &Path, content: &[u8]) -> std::io::Result<()> { - let mut f = File::create(path)?; - f.write_all(content) -} - -pub fn make_temp_dir( - dir: Option<&Path>, - prefix: Option<&str>, - suffix: Option<&str>, -) -> std::io::Result { - let prefix_ = prefix.unwrap_or(""); - let suffix_ = suffix.unwrap_or(""); - let mut buf: PathBuf = match dir { - Some(ref p) => p.to_path_buf(), - None => std::env::temp_dir(), - }.join("_"); - let mut rng = rand::thread_rng(); - loop { - let unique = rng.gen::(); - buf.set_file_name(format!("{}{:08x}{}", prefix_, unique, suffix_)); - // TODO: on posix, set mode flags to 0o700. - let r = create_dir(buf.as_path()); - match r { - Err(ref e) if e.kind() == ErrorKind::AlreadyExists => continue, - Ok(_) => return Ok(buf), - Err(e) => return Err(e), - } - } -} - -pub fn mkdir(path: &Path) -> std::io::Result<()> { - debug!("mkdir -p {}", path.display()); - assert!(path.has_root(), "non-has_root not yet implemented"); - std::fs::create_dir_all(path).or_else(|err| { - if err.kind() == std::io::ErrorKind::AlreadyExists { - Ok(()) - } else { - Err(err) - } - }) -} - -pub fn normalize_path(path: &Path) -> String { - let s = String::from(path.to_str().unwrap()); - if cfg!(windows) { - // TODO This isn't correct. Probbly should iterate over components. - s.replace("\\", "/") - } else { - s - } -} diff --git a/src/handlers.rs b/src/handlers.rs deleted file mode 100644 index 564f5e5be8ee56..00000000000000 --- a/src/handlers.rs +++ /dev/null @@ -1,598 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -use binding; -use binding::{deno_buf, DenoC}; -use errors::DenoResult; -use flatbuffers; -use flatbuffers::FlatBufferBuilder; -use from_c; -use fs as deno_fs; -use futures; -use futures::sync::oneshot; -use hyper; -use hyper::rt::{Future, Stream}; -use hyper::Client; -use msg_generated::deno as msg; -use std; -use std::fs; -use std::time::UNIX_EPOCH; -use std::path::Path; -use std::time::{Duration, Instant}; -use tokio::prelude::future; -use tokio::prelude::*; -use tokio::timer::{Delay, Interval}; - -type HandlerResult = DenoResult; - -pub extern "C" fn msg_from_js(d: *const DenoC, buf: deno_buf) { - let bytes = unsafe { std::slice::from_raw_parts(buf.data_ptr, buf.data_len) }; - let base = msg::get_root_as_base(bytes); - let mut builder = FlatBufferBuilder::new(); - let msg_type = base.msg_type(); - let result: HandlerResult = match msg_type { - msg::Any::Start => handle_start(d, &mut builder), - msg::Any::CodeFetch => { - // TODO base.msg_as_CodeFetch(); - let msg = msg::CodeFetch::init_from_table(base.msg().unwrap()); - let module_specifier = msg.module_specifier().unwrap(); - let containing_file = msg.containing_file().unwrap(); - handle_code_fetch(d, &mut builder, module_specifier, containing_file) - } - msg::Any::CodeCache => { - // TODO base.msg_as_CodeCache(); - let msg = msg::CodeCache::init_from_table(base.msg().unwrap()); - let filename = msg.filename().unwrap(); - let source_code = msg.source_code().unwrap(); - let output_code = msg.output_code().unwrap(); - handle_code_cache(d, &mut builder, filename, source_code, output_code) - } - msg::Any::FetchReq => { - // TODO base.msg_as_FetchReq(); - let msg = msg::FetchReq::init_from_table(base.msg().unwrap()); - let url = msg.url().unwrap(); - handle_fetch_req(d, &mut builder, msg.id(), url) - } - msg::Any::TimerStart => { - // TODO base.msg_as_TimerStart(); - let msg = msg::TimerStart::init_from_table(base.msg().unwrap()); - handle_timer_start(d, &mut builder, msg.id(), msg.interval(), msg.delay()) - } - msg::Any::TimerClear => { - // TODO base.msg_as_TimerClear(); - let msg = msg::TimerClear::init_from_table(base.msg().unwrap()); - handle_timer_clear(d, &mut builder, msg.id()) - } - msg::Any::Exit => { - // TODO base.msg_as_Exit(); - let msg = msg::Exit::init_from_table(base.msg().unwrap()); - std::process::exit(msg.code()) - } - msg::Any::MakeTempDir => { - let msg = msg::MakeTempDir::init_from_table(base.msg().unwrap()); - let dir = msg.dir(); - let prefix = msg.prefix(); - let suffix = msg.suffix(); - handle_make_temp_dir(d, &mut builder, dir, prefix, suffix) - } - msg::Any::ReadFileSync => { - // TODO base.msg_as_ReadFileSync(); - let msg = msg::ReadFileSync::init_from_table(base.msg().unwrap()); - let filename = msg.filename().unwrap(); - handle_read_file_sync(d, &mut builder, filename) - } - msg::Any::StatSync => { - // TODO base.msg_as_StatSync(); - let msg = msg::StatSync::init_from_table(base.msg().unwrap()); - let filename = msg.filename().unwrap(); - let lstat = msg.lstat(); - handle_stat_sync(d, &mut builder, filename, lstat) - } - msg::Any::WriteFileSync => { - // TODO base.msg_as_WriteFileSync(); - let msg = msg::WriteFileSync::init_from_table(base.msg().unwrap()); - let filename = msg.filename().unwrap(); - let data = msg.data().unwrap(); - let perm = msg.perm(); - handle_write_file_sync(d, &mut builder, filename, data, perm) - } - _ => panic!(format!( - "Unhandled message {}", - msg::enum_name_any(msg_type) - )), - }; - - // No matter whether we got an Err or Ok, we want a serialized message to - // send back. So transform the DenoError into a deno_buf. - let buf = match result { - Err(ref err) => { - let errmsg_offset = builder.create_string(&format!("{}", err)); - create_msg( - &mut builder, - &msg::BaseArgs { - error: Some(errmsg_offset), - error_kind: err.kind(), - ..Default::default() - }, - ) - } - Ok(buf) => buf, - }; - - // Set the synchronous response, the value returned from deno.send(). - // null_buf is a special case that indicates success. - if buf != null_buf() { - unsafe { binding::deno_set_response(d, buf) } - } -} - -fn null_buf() -> deno_buf { - deno_buf { - alloc_ptr: 0 as *mut u8, - alloc_len: 0, - data_ptr: 0 as *mut u8, - data_len: 0, - } -} - -fn handle_start( - d: *const DenoC, - builder: &mut FlatBufferBuilder, -) -> HandlerResult { - let deno = from_c(d); - - let argv = deno.argv.iter().map(|s| s.as_str()).collect::>(); - let argv_off = builder.create_vector_of_strings(argv.as_slice()); - - let cwd_path = std::env::current_dir().unwrap(); - let cwd_off = - builder.create_string(deno_fs::normalize_path(cwd_path.as_ref()).as_ref()); - - let msg = msg::StartRes::create( - builder, - &msg::StartResArgs { - cwd: Some(cwd_off), - argv: Some(argv_off), - debug_flag: deno.flags.log_debug, - ..Default::default() - }, - ); - - Ok(create_msg( - builder, - &msg::BaseArgs { - msg: Some(flatbuffers::Offset::new(msg.value())), - msg_type: msg::Any::StartRes, - ..Default::default() - }, - )) -} - -fn create_msg( - builder: &mut FlatBufferBuilder, - args: &msg::BaseArgs, -) -> deno_buf { - let base = msg::Base::create(builder, &args); - msg::finish_base_buffer(builder, base); - let data = builder.get_active_buf_slice(); - deno_buf { - // TODO(ry) - // The deno_buf / ImportBuf / ExportBuf semantics should be such that we do not need to yield - // ownership. Temporarally there is a hack in ImportBuf that when alloc_ptr is null, it will - // memcpy the deno_buf into V8 instead of doing zero copy. - alloc_ptr: 0 as *mut u8, - alloc_len: 0, - data_ptr: data.as_ptr() as *mut u8, - data_len: data.len(), - } -} - -// TODO(ry) Use Deno instead of DenoC as first arg. -fn send_base( - d: *const DenoC, - builder: &mut FlatBufferBuilder, - args: &msg::BaseArgs, -) { - let buf = create_msg(builder, args); - unsafe { binding::deno_send(d, buf) } -} - -// https://github.com/denoland/deno/blob/golang/os.go#L100-L154 -fn handle_code_fetch( - d: *const DenoC, - builder: &mut FlatBufferBuilder, - module_specifier: &str, - containing_file: &str, -) -> HandlerResult { - let deno = from_c(d); - - assert!(deno.dir.root.join("gen") == deno.dir.gen, "Sanity check"); - - let out = deno.dir.code_fetch(module_specifier, containing_file)?; - // reply_code_fetch - let mut msg_args = msg::CodeFetchResArgs { - module_name: Some(builder.create_string(&out.module_name)), - filename: Some(builder.create_string(&out.filename)), - source_code: Some(builder.create_string(&out.source_code)), - ..Default::default() - }; - match out.maybe_output_code { - Some(ref output_code) => { - msg_args.output_code = Some(builder.create_string(output_code)); - } - _ => (), - }; - let msg = msg::CodeFetchRes::create(builder, &msg_args); - Ok(create_msg( - builder, - &msg::BaseArgs { - msg: Some(flatbuffers::Offset::new(msg.value())), - msg_type: msg::Any::CodeFetchRes, - ..Default::default() - }, - )) -} - -// https://github.com/denoland/deno/blob/golang/os.go#L156-L169 -fn handle_code_cache( - d: *const DenoC, - _builder: &mut FlatBufferBuilder, - filename: &str, - source_code: &str, - output_code: &str, -) -> HandlerResult { - let deno = from_c(d); - deno.dir.code_cache(filename, source_code, output_code)?; - Ok(null_buf()) // null response indicates success. -} - -fn handle_fetch_req( - d: *const DenoC, - _builder: &mut FlatBufferBuilder, - id: u32, - url: &str, -) -> HandlerResult { - let deno = from_c(d); - let url = url.parse::().unwrap(); - let client = Client::new(); - - deno.rt.spawn( - client - .get(url) - .map(move |res| { - let status = res.status().as_u16() as i32; - - // Send the first message without a body. This is just to indicate - // what status code. - let mut builder = flatbuffers::FlatBufferBuilder::new(); - let msg = msg::FetchRes::create( - &mut builder, - &msg::FetchResArgs { - id, - status, - ..Default::default() - }, - ); - send_base( - d, - &mut builder, - &msg::BaseArgs { - msg: Some(flatbuffers::Offset::new(msg.value())), - msg_type: msg::Any::FetchRes, - ..Default::default() - }, - ); - res - }) - .and_then(move |res| { - // Send the body as a FetchRes message. - res.into_body().concat2().map(move |body_buffer| { - let mut builder = flatbuffers::FlatBufferBuilder::new(); - let data_off = builder.create_byte_vector(body_buffer.as_ref()); - let msg = msg::FetchRes::create( - &mut builder, - &msg::FetchResArgs { - id, - body: Some(data_off), - ..Default::default() - }, - ); - send_base( - d, - &mut builder, - &msg::BaseArgs { - msg: Some(flatbuffers::Offset::new(msg.value())), - msg_type: msg::Any::FetchRes, - ..Default::default() - }, - ); - }) - }) - .map_err(move |err| { - let errmsg = format!("{}", err); - - // TODO This is obviously a lot of duplicated code from the success case. - // Leaving it here now jsut to get a first pass implementation, but this - // needs to be cleaned up. - let mut builder = flatbuffers::FlatBufferBuilder::new(); - let err_off = builder.create_string(errmsg.as_str()); - let msg = msg::FetchRes::create( - &mut builder, - &msg::FetchResArgs { - id, - ..Default::default() - }, - ); - send_base( - d, - &mut builder, - &msg::BaseArgs { - msg: Some(flatbuffers::Offset::new(msg.value())), - msg_type: msg::Any::FetchRes, - error: Some(err_off), - ..Default::default() - }, - ); - }), - ); - Ok(null_buf()) // null response indicates success. -} - -fn set_timeout( - cb: F, - delay: u32, -) -> ( - impl Future, - futures::sync::oneshot::Sender<()>, -) -where - F: FnOnce() -> (), -{ - let (cancel_tx, cancel_rx) = oneshot::channel::<()>(); - let when = Instant::now() + Duration::from_millis(delay.into()); - let delay_task = Delay::new(when) - .map_err(|e| panic!("timer failed; err={:?}", e)) - .and_then(|_| { - cb(); - Ok(()) - }) - .select(cancel_rx) - .map(|_| ()) - .map_err(|_| ()); - - (delay_task, cancel_tx) -} - -fn set_interval( - cb: F, - delay: u32, -) -> ( - impl Future, - futures::sync::oneshot::Sender<()>, -) -where - F: Fn() -> (), -{ - let (cancel_tx, cancel_rx) = oneshot::channel::<()>(); - let delay = Duration::from_millis(delay.into()); - let interval_task = future::lazy(move || { - Interval::new(Instant::now() + delay, delay) - .for_each(move |_| { - cb(); - future::ok(()) - }) - .into_future() - .map_err(|_| panic!()) - }).select(cancel_rx) - .map(|_| ()) - .map_err(|_| ()); - - (interval_task, cancel_tx) -} - -// TODO(ry) Use Deno instead of DenoC as first arg. -fn send_timer_ready(d: *const DenoC, timer_id: u32, done: bool) { - let mut builder = FlatBufferBuilder::new(); - let msg = msg::TimerReady::create( - &mut builder, - &msg::TimerReadyArgs { - id: timer_id, - done, - ..Default::default() - }, - ); - send_base( - d, - &mut builder, - &msg::BaseArgs { - msg: Some(flatbuffers::Offset::new(msg.value())), - msg_type: msg::Any::TimerReady, - ..Default::default() - }, - ); -} - -fn handle_make_temp_dir( - d: *const DenoC, - builder: &mut FlatBufferBuilder, - dir: Option<&str>, - prefix: Option<&str>, - suffix: Option<&str>, -) -> HandlerResult { - let deno = from_c(d); - if !deno.flags.allow_write { - let err = std::io::Error::new( - std::io::ErrorKind::PermissionDenied, - "allow_write is off.", - ); - return Err(err.into()); - } - // TODO(piscisaureus): use byte vector for paths, not a string. - // See https://github.com/denoland/deno/issues/627. - // We can't assume that paths are always valid utf8 strings. - let path = deno_fs::make_temp_dir(dir.map(Path::new), prefix, suffix)?; - let path_off = builder.create_string(path.to_str().unwrap()); - let msg = msg::MakeTempDirRes::create( - builder, - &msg::MakeTempDirResArgs { - path: Some(path_off), - ..Default::default() - }, - ); - Ok(create_msg( - builder, - &msg::BaseArgs { - msg: Some(flatbuffers::Offset::new(msg.value())), - msg_type: msg::Any::MakeTempDirRes, - ..Default::default() - }, - )) -} - -// Prototype https://github.com/denoland/deno/blob/golang/os.go#L171-L184 -fn handle_read_file_sync( - _d: *const DenoC, - builder: &mut FlatBufferBuilder, - filename: &str, -) -> HandlerResult { - debug!("handle_read_file_sync {}", filename); - let vec = fs::read(Path::new(filename))?; - // Build the response message. memcpy data into msg. - // TODO(ry) zero-copy. - let data_off = builder.create_byte_vector(vec.as_slice()); - let msg = msg::ReadFileSyncRes::create( - builder, - &msg::ReadFileSyncResArgs { - data: Some(data_off), - ..Default::default() - }, - ); - Ok(create_msg( - builder, - &msg::BaseArgs { - msg: Some(flatbuffers::Offset::new(msg.value())), - msg_type: msg::Any::ReadFileSyncRes, - ..Default::default() - }, - )) -} - -macro_rules! to_seconds { - ($time:expr) => {{ - // Unwrap is safe here as if the file is before the unix epoch - // something is very wrong. - $time.and_then(|t| Ok(t.duration_since(UNIX_EPOCH).unwrap().as_secs())) - .unwrap_or(0) - }} -} - - -fn handle_stat_sync( - _d: *const DenoC, - builder: &mut FlatBufferBuilder, - filename: &str, - lstat: bool, -) -> HandlerResult { - debug!("handle_stat_sync {} {}", filename, lstat); - let path = Path::new(filename); - let metadata = if lstat { - fs::symlink_metadata(path)? - } else { - fs::metadata(path)? - }; - - let msg = msg::StatSyncRes::create( - builder, - &msg::StatSyncResArgs { - is_file: metadata.is_file(), - is_symlink: metadata.file_type().is_symlink(), - len: metadata.len(), - modified: to_seconds!(metadata.modified()), - accessed: to_seconds!(metadata.accessed()), - created: to_seconds!(metadata.created()), - ..Default::default() - }, - ); - - Ok(create_msg( - builder, - &msg::BaseArgs { - msg: Some(flatbuffers::Offset::new(msg.value())), - msg_type: msg::Any::StatSyncRes, - ..Default::default() - }, - )) -} - -fn handle_write_file_sync( - d: *const DenoC, - _builder: &mut FlatBufferBuilder, - filename: &str, - data: &[u8], - _perm: u32, -) -> HandlerResult { - debug!("handle_write_file_sync {}", filename); - let deno = from_c(d); - if deno.flags.allow_write { - // TODO(ry) Use perm. - deno_fs::write_file_sync(Path::new(filename), data)?; - Ok(null_buf()) - } else { - let err = std::io::Error::new( - std::io::ErrorKind::PermissionDenied, - "allow_write is off.", - ); - Err(err.into()) - } -} - -// TODO(ry) Use Deno instead of DenoC as first arg. -fn remove_timer(d: *const DenoC, timer_id: u32) { - let deno = from_c(d); - deno.timers.remove(&timer_id); -} - -// Prototype: https://github.com/ry/deno/blob/golang/timers.go#L25-L39 -fn handle_timer_start( - d: *const DenoC, - _builder: &mut FlatBufferBuilder, - timer_id: u32, - interval: bool, - delay: u32, -) -> HandlerResult { - debug!("handle_timer_start"); - let deno = from_c(d); - - if interval { - let (interval_task, cancel_interval) = set_interval( - move || { - send_timer_ready(d, timer_id, false); - }, - delay, - ); - - deno.timers.insert(timer_id, cancel_interval); - deno.rt.spawn(interval_task); - } else { - let (delay_task, cancel_delay) = set_timeout( - move || { - remove_timer(d, timer_id); - send_timer_ready(d, timer_id, true); - }, - delay, - ); - - deno.timers.insert(timer_id, cancel_delay); - deno.rt.spawn(delay_task); - } - Ok(null_buf()) -} - -// Prototype: https://github.com/ry/deno/blob/golang/timers.go#L40-L43 -fn handle_timer_clear( - d: *const DenoC, - _builder: &mut FlatBufferBuilder, - timer_id: u32, -) -> HandlerResult { - debug!("handle_timer_clear"); - remove_timer(d, timer_id); - Ok(null_buf()) -} diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index e4a7566548fce2..00000000000000 --- a/src/main.rs +++ /dev/null @@ -1,159 +0,0 @@ -extern crate flatbuffers; -extern crate futures; -extern crate hyper; -extern crate libc; -extern crate msg_rs as msg_generated; -extern crate rand; -extern crate tempfile; -extern crate tokio; -extern crate url; -#[macro_use] -extern crate log; -extern crate hyper_rustls; -extern crate ring; - -mod binding; -mod deno_dir; -mod errors; -mod flags; -mod fs; -pub mod handlers; -mod net; -mod version; - -use libc::c_void; -use std::collections::HashMap; -use std::env; -use std::ffi::CStr; -use std::ffi::CString; - -type DenoException<'a> = &'a str; - -pub struct Deno { - ptr: *const binding::DenoC, - dir: deno_dir::DenoDir, - rt: tokio::runtime::current_thread::Runtime, - timers: HashMap>, - argv: Vec, - flags: flags::DenoFlags, -} - -static DENO_INIT: std::sync::Once = std::sync::ONCE_INIT; - -impl Deno { - fn new(argv: Vec) -> Box { - DENO_INIT.call_once(|| { - unsafe { binding::deno_init() }; - }); - - let (flags, argv_rest) = flags::set_flags(argv); - - let mut deno_box = Box::new(Deno { - ptr: 0 as *const binding::DenoC, - dir: deno_dir::DenoDir::new(flags.reload, None).unwrap(), - rt: tokio::runtime::current_thread::Runtime::new().unwrap(), - timers: HashMap::new(), - argv: argv_rest, - flags, - }); - - (*deno_box).ptr = unsafe { - binding::deno_new( - deno_box.as_ref() as *const _ as *const c_void, - handlers::msg_from_js, - ) - }; - - deno_box - } - - fn execute( - &mut self, - js_filename: &str, - js_source: &str, - ) -> Result<(), DenoException> { - let filename = CString::new(js_filename).unwrap(); - let source = CString::new(js_source).unwrap(); - let r = unsafe { - binding::deno_execute(self.ptr, filename.as_ptr(), source.as_ptr()) - }; - if r == 0 { - let ptr = unsafe { binding::deno_last_exception(self.ptr) }; - let cstr = unsafe { CStr::from_ptr(ptr) }; - return Err(cstr.to_str().unwrap()); - } - Ok(()) - } -} - -impl Drop for Deno { - fn drop(&mut self) { - unsafe { binding::deno_delete(self.ptr) } - } -} - -pub fn from_c<'a>(d: *const binding::DenoC) -> &'a mut Deno { - let ptr = unsafe { binding::deno_get_data(d) }; - let deno_ptr = ptr as *mut Deno; - let deno_box = unsafe { Box::from_raw(deno_ptr) }; - Box::leak(deno_box) -} - -#[test] -fn test_c_to_rust() { - let argv = vec![String::from("./deno"), String::from("hello.js")]; - let d = Deno::new(argv); - let d2 = from_c(d.ptr); - assert!(d.ptr == d2.ptr); - assert!(d.dir.root.join("gen") == d.dir.gen, "Sanity check"); -} - -static LOGGER: Logger = Logger; - -struct Logger; - -impl log::Log for Logger { - fn enabled(&self, metadata: &log::Metadata) -> bool { - metadata.level() <= log::max_level() - } - - fn log(&self, record: &log::Record) { - if self.enabled(record.metadata()) { - println!("{} RS - {}", record.level(), record.args()); - } - } - fn flush(&self) {} -} - -fn main() { - log::set_logger(&LOGGER).unwrap(); - - let js_args = flags::v8_set_flags(env::args().collect()); - - let mut d = Deno::new(js_args); - - if d.flags.help { - flags::print_usage(); - std::process::exit(0); - } - - if d.flags.version { - version::print_version(); - std::process::exit(0); - } - - log::set_max_level(if d.flags.log_debug { - log::LevelFilter::Debug - } else { - log::LevelFilter::Info - }); - - d.execute("deno_main.js", "denoMain();") - .unwrap_or_else(|err| { - error!("{}", err); - std::process::exit(1); - }); - - // Start the Tokio event loop - d.rt.run().expect("err"); -} diff --git a/src/msg.fbs b/src/msg.fbs deleted file mode 100644 index eb3753d75418ea..00000000000000 --- a/src/msg.fbs +++ /dev/null @@ -1,179 +0,0 @@ -namespace deno; - -union Any { - Start, - StartRes, - CodeFetch, - CodeFetchRes, - CodeCache, - Exit, - TimerStart, - TimerReady, - TimerClear, - FetchReq, - FetchRes, - MakeTempDir, - MakeTempDirRes, - ReadFileSync, - ReadFileSyncRes, - StatSync, - StatSyncRes, - WriteFileSync, -} - -enum ErrorKind: byte { - NoError = 0, - - // io errors - - NotFound, - PermissionDenied, - ConnectionRefused, - ConnectionReset, - ConnectionAborted, - NotConnected, - AddrInUse, - AddrNotAvailable, - BrokenPipe, - AlreadyExists, - WouldBlock, - InvalidInput, - InvalidData, - TimedOut, - Interrupted, - WriteZero, - Other, - UnexpectedEof, - - // url errors - - EmptyHost, - IdnaError, - InvalidPort, - InvalidIpv4Address, - InvalidIpv6Address, - InvalidDomainCharacter, - RelativeUrlWithoutBase, - RelativeUrlWithCannotBeABaseBase, - SetHostOnCannotBeABaseUrl, - Overflow, - - // hyper errors - - HttpUser, - HttpClosed, - HttpCanceled, - HttpParse, - HttpOther, -} - -table Base { - cmd_id: uint32; - error_kind: ErrorKind = NoError; - error: string; - msg: Any; -} - -table Start { - unused: int8; -} - -table StartRes { - cwd: string; - argv: [string]; - debug_flag: bool; -} - -table CodeFetch { - module_specifier: string; - containing_file: string; -} - -table CodeFetchRes { - // If it's a non-http module, moduleName and filename will be the same. - // For http modules, moduleName is its resolved http URL, and filename - // is the location of the locally downloaded source code. - module_name: string; - filename: string; - source_code: string; - output_code: string; // Non-empty only if cached. -} - -table CodeCache { - filename: string; - source_code: string; - output_code: string; -} - -table Exit { - code: int; -} - -table TimerStart { - id: uint; - interval: bool; - delay: uint; -} - -table TimerReady { - id: uint; - done: bool; -} - -table TimerClear { - id: uint; -} - -table FetchReq { - id: uint; - url: string; - // header_line: [string]; -} - -table FetchRes { - id: uint; - status: int; - header_line: [string]; - body: [ubyte]; -} - -table MakeTempDir { - dir: string; - prefix: string; - suffix: string; -} - -table MakeTempDirRes { - path: string; -} - -table ReadFileSync { - filename: string; -} - -table ReadFileSyncRes { - data: [ubyte]; -} - -table StatSync { - filename: string; - lstat: bool; -} - -table StatSyncRes { - is_file: bool; - is_symlink: bool; - len: ulong; - modified:ulong; - accessed:ulong; - created:ulong; -} - -table WriteFileSync { - filename: string; - data: [ubyte]; - perm: uint; - // perm specified by https://godoc.org/os#FileMode -} - -root_type Base; diff --git a/src/net.rs b/src/net.rs deleted file mode 100644 index 7e0700bb685780..00000000000000 --- a/src/net.rs +++ /dev/null @@ -1,33 +0,0 @@ -use errors::DenoResult; -use hyper; -use hyper::rt::{Future, Stream}; -use hyper::{Client, Uri}; -use hyper_rustls; -use tokio::runtime::current_thread::Runtime; - -// The CodeFetch message is used to load HTTP javascript resources and expects a -// synchronous response, this utility method supports that. -pub fn fetch_sync_string(module_name: &str) -> DenoResult { - let url = module_name.parse::().unwrap(); - - let https = hyper_rustls::HttpsConnector::new(4); - let client: Client<_, hyper::Body> = Client::builder().build(https); - - // TODO Use Deno's RT - let mut rt = Runtime::new().unwrap(); - - let body = rt.block_on( - client - .get(url) - .and_then(|response| response.into_body().concat2()), - )?; - Ok(String::from_utf8(body.to_vec()).unwrap()) -} - -#[test] -fn test_fetch_sync_string() { - // Relies on external http server. See tools/http_server.py - let p = fetch_sync_string("http://localhost:4545/package.json").unwrap(); - println!("package.json len {}", p.len()); - assert!(p.len() > 1); -} diff --git a/src/version.rs b/src/version.rs deleted file mode 100644 index a8405c303505fb..00000000000000 --- a/src/version.rs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -use binding; -use std::ffi::CStr; - -// This is the source of truth for the Deno version. Ignore the value in Cargo.toml. -const DENO_VERSION: &str = "0.1.1"; - -pub fn print_version() { - let v = unsafe { binding::deno_v8_version() }; - let c_str = unsafe { CStr::from_ptr(v) }; - let version = c_str.to_str().unwrap(); - println!("deno: {}", DENO_VERSION); - println!("v8: {}", version); -} diff --git a/testing b/testing deleted file mode 120000 index ee588681500e34..00000000000000 --- a/testing +++ /dev/null @@ -1 +0,0 @@ -third_party/v8/testing \ No newline at end of file diff --git a/tests/001_hello.js b/tests/001_hello.js deleted file mode 100644 index accefceba62b48..00000000000000 --- a/tests/001_hello.js +++ /dev/null @@ -1 +0,0 @@ -console.log("Hello World"); diff --git a/tests/001_hello.js.out b/tests/001_hello.js.out deleted file mode 100644 index 557db03de997c8..00000000000000 --- a/tests/001_hello.js.out +++ /dev/null @@ -1 +0,0 @@ -Hello World diff --git a/tests/002_hello.ts b/tests/002_hello.ts deleted file mode 100644 index accefceba62b48..00000000000000 --- a/tests/002_hello.ts +++ /dev/null @@ -1 +0,0 @@ -console.log("Hello World"); diff --git a/tests/002_hello.ts.out b/tests/002_hello.ts.out deleted file mode 100644 index 557db03de997c8..00000000000000 --- a/tests/002_hello.ts.out +++ /dev/null @@ -1 +0,0 @@ -Hello World diff --git a/tests/003_relative_import.ts b/tests/003_relative_import.ts deleted file mode 100644 index 01d5d7faac3c1e..00000000000000 --- a/tests/003_relative_import.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { printHello } from "./subdir/print_hello.ts"; - -printHello(); diff --git a/tests/003_relative_import.ts.out b/tests/003_relative_import.ts.out deleted file mode 100644 index e965047ad7c578..00000000000000 --- a/tests/003_relative_import.ts.out +++ /dev/null @@ -1 +0,0 @@ -Hello diff --git a/tests/004_set_timeout.ts b/tests/004_set_timeout.ts deleted file mode 100644 index 214b25086c2522..00000000000000 --- a/tests/004_set_timeout.ts +++ /dev/null @@ -1,11 +0,0 @@ -setTimeout(() => { - console.log("World"); -}, 10); - -console.log("Hello"); - -const id = setTimeout(() => { - console.log("Not printed"); -}, 10000); - -clearTimeout(id); diff --git a/tests/004_set_timeout.ts.out b/tests/004_set_timeout.ts.out deleted file mode 100644 index f9264f7fbd31ae..00000000000000 --- a/tests/004_set_timeout.ts.out +++ /dev/null @@ -1,2 +0,0 @@ -Hello -World diff --git a/tests/005_more_imports.ts b/tests/005_more_imports.ts deleted file mode 100644 index 52dd1df7b916cc..00000000000000 --- a/tests/005_more_imports.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { returnsHi, returnsFoo2, printHello3 } from "./subdir/mod1.ts"; - -printHello3(); - -if (returnsHi() !== "Hi") { - throw Error("Unexpected"); -} - -if (returnsFoo2() !== "Foo") { - throw Error("Unexpected"); -} diff --git a/tests/005_more_imports.ts.out b/tests/005_more_imports.ts.out deleted file mode 100644 index e965047ad7c578..00000000000000 --- a/tests/005_more_imports.ts.out +++ /dev/null @@ -1 +0,0 @@ -Hello diff --git a/tests/006_url_imports.ts b/tests/006_url_imports.ts deleted file mode 100644 index 53dd8b8765690b..00000000000000 --- a/tests/006_url_imports.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { printHello } from "http://localhost:4545/tests/subdir/print_hello.ts"; -printHello(); -console.log("success"); diff --git a/tests/006_url_imports.ts.out b/tests/006_url_imports.ts.out deleted file mode 100644 index d2a3863c59fbc9..00000000000000 --- a/tests/006_url_imports.ts.out +++ /dev/null @@ -1,3 +0,0 @@ -Downloading http://localhost:4545/tests/subdir/print_hello.ts -Hello -success diff --git a/tests/010_set_interval.ts b/tests/010_set_interval.ts deleted file mode 100644 index f58cc3fcd192ff..00000000000000 --- a/tests/010_set_interval.ts +++ /dev/null @@ -1,7 +0,0 @@ -const id = setInterval(function() { - console.log("test"); -}, 200); - -setTimeout(function() { - clearInterval(id); -}, 500); diff --git a/tests/010_set_interval.ts.out b/tests/010_set_interval.ts.out deleted file mode 100644 index dec2cbe1fa34fe..00000000000000 --- a/tests/010_set_interval.ts.out +++ /dev/null @@ -1,2 +0,0 @@ -test -test diff --git a/tests/012_async.ts b/tests/012_async.ts deleted file mode 100644 index 57ae355c25f608..00000000000000 --- a/tests/012_async.ts +++ /dev/null @@ -1,11 +0,0 @@ -// Check that we can use the async keyword. -async function main() { - await new Promise((resolve, reject) => { - console.log("2"); - setTimeout(resolve, 100); - }); - console.log("3"); -} - -console.log("1"); -main(); diff --git a/tests/012_async.ts.out b/tests/012_async.ts.out deleted file mode 100644 index 01e79c32a8c99c..00000000000000 --- a/tests/012_async.ts.out +++ /dev/null @@ -1,3 +0,0 @@ -1 -2 -3 diff --git a/tests/013_dynamic_import.ts b/tests/013_dynamic_import.ts deleted file mode 100644 index 0812623f688e1b..00000000000000 --- a/tests/013_dynamic_import.ts +++ /dev/null @@ -1,17 +0,0 @@ -(async () => { - const { - returnsHi, - returnsFoo2, - printHello3 - } = await import("./subdir/mod1.ts"); - - printHello3(); - - if (returnsHi() !== "Hi") { - throw Error("Unexpected"); - } - - if (returnsFoo2() !== "Foo") { - throw Error("Unexpected"); - } -})(); diff --git a/tests/013_dynamic_import.ts.out b/tests/013_dynamic_import.ts.out deleted file mode 100644 index e965047ad7c578..00000000000000 --- a/tests/013_dynamic_import.ts.out +++ /dev/null @@ -1 +0,0 @@ -Hello diff --git a/tests/014_duplicate_import.ts b/tests/014_duplicate_import.ts deleted file mode 100644 index 88f93452695033..00000000000000 --- a/tests/014_duplicate_import.ts +++ /dev/null @@ -1,9 +0,0 @@ -// with all the imports of the same module, the module should only be -// instantiated once -import "./subdir/auto_print_hello.ts"; - -import "./subdir/auto_print_hello.ts"; - -(async () => { - await import("./subdir/auto_print_hello.ts"); -})(); diff --git a/tests/014_duplicate_import.ts.out b/tests/014_duplicate_import.ts.out deleted file mode 100644 index 4effa19f4f75f8..00000000000000 --- a/tests/014_duplicate_import.ts.out +++ /dev/null @@ -1 +0,0 @@ -hello! diff --git a/tests/async_error.ts b/tests/async_error.ts deleted file mode 100644 index 7ce25d0cb67d2d..00000000000000 --- a/tests/async_error.ts +++ /dev/null @@ -1,8 +0,0 @@ -console.log("hello"); -const foo = async () => { - console.log("before error"); - throw Error("error"); -}; - -foo(); -console.log("world"); diff --git a/tests/async_error.ts.out b/tests/async_error.ts.out deleted file mode 100644 index 862cf0f963b77c..00000000000000 --- a/tests/async_error.ts.out +++ /dev/null @@ -1,10 +0,0 @@ -hello -before error -Error: error - at foo ([WILDCARD]tests/async_error.ts:4:9) - at eval ([WILDCARD]tests/async_error.ts:7:1) - at DenoCompiler.eval [as _globalEval] () - at DenoCompiler._gatherDependencies (deno/js/compiler.ts:[WILDCARD]) - at DenoCompiler.run (deno/js/compiler.ts:[WILDCARD]) - at denoMain (deno/js/main.ts:[WILDCARD]) - at deno_main.js:1:1 diff --git a/tests/error_001.ts b/tests/error_001.ts deleted file mode 100644 index ab6e17a5245ea1..00000000000000 --- a/tests/error_001.ts +++ /dev/null @@ -1,9 +0,0 @@ -function foo() { - throw Error("bad"); -} - -function bar() { - foo(); -} - -bar(); diff --git a/tests/error_001.ts.out b/tests/error_001.ts.out deleted file mode 100644 index daad7d7e28f440..00000000000000 --- a/tests/error_001.ts.out +++ /dev/null @@ -1,9 +0,0 @@ -Error: bad - at foo (file://[WILDCARD]tests/error_001.ts:2:9) - at bar (file://[WILDCARD]tests/error_001.ts:6:3) - at eval (file://[WILDCARD]tests/error_001.ts:9:1) - at DenoCompiler.eval [as _globalEval] () - at DenoCompiler._gatherDependencies (deno/js/compiler.ts:[WILDCARD]) - at DenoCompiler.run (deno/js/compiler.ts:[WILDCARD]) - at denoMain (deno/js/main.ts:[WILDCARD]) - at deno_main.js:1:1 diff --git a/tests/error_002.ts b/tests/error_002.ts deleted file mode 100644 index 6aa0fcc3b6a46f..00000000000000 --- a/tests/error_002.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { throwsError } from "./subdir/mod1.ts"; - -function foo() { - throwsError(); -} - -foo(); diff --git a/tests/error_002.ts.out b/tests/error_002.ts.out deleted file mode 100644 index c375d259a1debd..00000000000000 --- a/tests/error_002.ts.out +++ /dev/null @@ -1,8 +0,0 @@ -Error: exception from mod1 - at Object.throwsError (file://[WILDCARD]deno/tests/subdir/mod1.ts:16:9) - at foo (file://[WILDCARD]deno/tests/error_002.ts:4:3) - at ModuleMetaData.eval [as factory ] (file://[WILDCARD]deno/tests/error_002.ts:7:1) - at DenoCompiler._drainRunQueue (deno/js/compiler.ts:[WILDCARD]) - at DenoCompiler.run (deno/js/compiler.ts:[WILDCARD]) - at denoMain (deno/js/main.ts:[WILDCARD]) - at deno_main.js:1:1 diff --git a/tests/error_003_typescript.ts b/tests/error_003_typescript.ts deleted file mode 100644 index ebd9fcbe64000a..00000000000000 --- a/tests/error_003_typescript.ts +++ /dev/null @@ -1,2 +0,0 @@ -// console.log intentionally misspelled to trigger TypeScript error -consol.log("hello world!"); diff --git a/tests/error_003_typescript.ts.out b/tests/error_003_typescript.ts.out deleted file mode 100644 index f04be363bf5893..00000000000000 --- a/tests/error_003_typescript.ts.out +++ /dev/null @@ -1,10 +0,0 @@ -[WILDCARD]tests/error_003_typescript.tsILDCARD] - error TS2552: Cannot find name 'consol'. Did you mean 'console'? - -[WILDCARD][0m consol.log("hello world!"); -  ~~~~~~ - - $asset$/globals.d.tsILDCARD] - [WILDCARD][0m const console: Console; -    ~~~~~~~ - 'console' is declared here. - diff --git a/tests/error_004_missing_module.ts b/tests/error_004_missing_module.ts deleted file mode 100644 index 48623320b6ba61..00000000000000 --- a/tests/error_004_missing_module.ts +++ /dev/null @@ -1 +0,0 @@ -import * as badModule from "bad-module.ts"; diff --git a/tests/error_004_missing_module.ts.out b/tests/error_004_missing_module.ts.out deleted file mode 100644 index dda14d25e56d3f..00000000000000 --- a/tests/error_004_missing_module.ts.out +++ /dev/null @@ -1,12 +0,0 @@ -Error: Cannot resolve module "bad-module.ts" from "[WILDCARD]error_004_missing_module.ts". - os.codeFetch message: [WILDCARD] (os error 2) - at throwResolutionError (deno/js/compiler.ts:[WILDCARD]) - at DenoCompiler.resolveModule (deno/js/compiler.ts:[WILDCARD]) - at DenoCompiler.resolveModuleName (deno/js/compiler.ts:[WILDCARD]) - at moduleNames.map.name (deno/js/compiler.ts:[WILDCARD]) - at Array.map () - at DenoCompiler.resolveModuleNames (deno/js/compiler.ts:[WILDCARD]) - at Object.compilerHost.resolveModuleNames (deno/third_party/node_modules/typescript/lib/typescript.js:[WILDCARD]) - at resolveModuleNamesWorker (deno/third_party/node_modules/typescript/lib/typescript.js:[WILDCARD]) - at resolveModuleNamesReusingOldState (deno/third_party/node_modules/typescript/lib/typescript.js:[WILDCARD]) - at processImportedModules (deno/third_party/node_modules/typescript/lib/typescript.js:[WILDCARD]) diff --git a/tests/error_005_missing_dynamic_import.ts b/tests/error_005_missing_dynamic_import.ts deleted file mode 100644 index 3cb081a276a5c3..00000000000000 --- a/tests/error_005_missing_dynamic_import.ts +++ /dev/null @@ -1,3 +0,0 @@ -(async () => { - const badModule = await import("bad-module.ts"); -})(); diff --git a/tests/error_005_missing_dynamic_import.ts.out b/tests/error_005_missing_dynamic_import.ts.out deleted file mode 100644 index b28875bc56ddd0..00000000000000 --- a/tests/error_005_missing_dynamic_import.ts.out +++ /dev/null @@ -1,12 +0,0 @@ -Error: Cannot resolve module "bad-module.ts" from "[WILDCARD]deno/tests/error_005_missing_dynamic_import.ts". - os.codeFetch message: [WILDCARD] (os error 2) - at throwResolutionError (deno/js/compiler.ts:[WILDCARD]) - at DenoCompiler.resolveModule (deno/js/compiler.ts:[WILDCARD]) - at DenoCompiler.resolveModuleName (deno/js/compiler.ts:[WILDCARD]) - at moduleNames.map.name (deno/js/compiler.ts:[WILDCARD]) - at Array.map () - at DenoCompiler.resolveModuleNames (deno/js/compiler.ts:[WILDCARD]) - at Object.compilerHost.resolveModuleNames (deno/third_party/node_modules/typescript/lib/typescript.js:[WILDCARD]) - at resolveModuleNamesWorker (deno/third_party/node_modules/typescript/lib/typescript.js:[WILDCARD]) - at resolveModuleNamesReusingOldState (deno/third_party/node_modules/typescript/lib/typescript.js:[WILDCARD]) - at processImportedModules (deno/third_party/node_modules/typescript/lib/typescript.js:[WILDCARD]) diff --git a/tests/exit_error42.ts b/tests/exit_error42.ts deleted file mode 100644 index c55cf0ecedd7af..00000000000000 --- a/tests/exit_error42.ts +++ /dev/null @@ -1,5 +0,0 @@ -import * as deno from "deno"; - -console.log("before"); -deno.exit(42); -console.log("after"); diff --git a/tests/exit_error42.ts.out b/tests/exit_error42.ts.out deleted file mode 100644 index 90be1f3056c4f4..00000000000000 --- a/tests/exit_error42.ts.out +++ /dev/null @@ -1 +0,0 @@ -before diff --git a/tests/fetch_deps.ts b/tests/fetch_deps.ts deleted file mode 100644 index d2690e01c0c573..00000000000000 --- a/tests/fetch_deps.ts +++ /dev/null @@ -1,14 +0,0 @@ -// Run ./tools/http_server.py too in order for this test to run. -import { assert } from "../js/testing/util.ts"; - -// TODO Top level await https://github.com/denoland/deno/issues/471 -async function main() { - const response = await fetch("http://localhost:4545/package.json"); - const json = await response.json(); - const deps = Object.keys(json.devDependencies); - console.log("Deno JS Deps"); - console.log(deps.map(d => `* ${d}`).join("\n")); - assert(deps.includes("typescript")); -} - -main(); diff --git a/tests/https_import.ts b/tests/https_import.ts deleted file mode 100644 index faaf2175f111a9..00000000000000 --- a/tests/https_import.ts +++ /dev/null @@ -1,5 +0,0 @@ -// TODO Use https://localhost:4555/ but we need more infrastructure to -// support verifying self-signed certificates. -import { printHello } from "https://gist.githubusercontent.com/ry/f12b2aa3409e6b52645bc346a9e22929/raw/79318f239f51d764384a8bded8d7c6a833610dde/print_hello.ts"; - -printHello(); diff --git a/tests/https_import.ts.out b/tests/https_import.ts.out deleted file mode 100644 index efc3fd5433c392..00000000000000 --- a/tests/https_import.ts.out +++ /dev/null @@ -1,2 +0,0 @@ -Downloading https://gist.githubusercontent.com/ry/f12b2aa3409e6b52645bc346a9e22929/raw/79318f239f51d764384a8bded8d7c6a833610dde/print_hello.ts -Hello diff --git a/tests/subdir/auto_print_hello.ts b/tests/subdir/auto_print_hello.ts deleted file mode 100644 index a00040281baa8d..00000000000000 --- a/tests/subdir/auto_print_hello.ts +++ /dev/null @@ -1,2 +0,0 @@ -console.log("hello!"); -export = {}; diff --git a/tests/subdir/mod1.ts b/tests/subdir/mod1.ts deleted file mode 100644 index 393535588af3d2..00000000000000 --- a/tests/subdir/mod1.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { returnsFoo, printHello2 } from "./subdir2/mod2.ts"; - -export function returnsHi(): string { - return "Hi"; -} - -export function returnsFoo2(): string { - return returnsFoo(); -} - -export function printHello3(): void { - printHello2(); -} - -export function throwsError(): void { - throw Error("exception from mod1"); -} diff --git a/tests/subdir/print_hello.ts b/tests/subdir/print_hello.ts deleted file mode 100644 index 7ecce50405b191..00000000000000 --- a/tests/subdir/print_hello.ts +++ /dev/null @@ -1,3 +0,0 @@ -export function printHello(): void { - console.log("Hello"); -} diff --git a/tests/subdir/subdir2/mod2.ts b/tests/subdir/subdir2/mod2.ts deleted file mode 100644 index c88d4708c85705..00000000000000 --- a/tests/subdir/subdir2/mod2.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { printHello } from "../print_hello.ts"; - -export function returnsFoo(): string { - return "Foo"; -} - -export function printHello2(): void { - printHello(); -} diff --git a/third_party b/third_party deleted file mode 160000 index 8c1d351df3139d..00000000000000 --- a/third_party +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 8c1d351df3139d82a939b2f5052e0fd96c577d65 diff --git a/tools/build.py b/tools/build.py deleted file mode 100755 index 978b70a36d5199..00000000000000 --- a/tools/build.py +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env python -# Copyright 2018 the Deno authors. All rights reserved. MIT license. -import os -import sys -from os.path import join -import third_party -from util import root_path, run, run_output, build_path - -third_party.fix_symlinks() - -print "DENO_BUILD_PATH:", build_path() -if not os.path.isdir(build_path()): - print "DENO_BUILD_PATH does not exist. Run tools/setup.py" - sys.exit(1) -os.chdir(build_path()) - -ninja_args = sys.argv[1:] - -run([third_party.ninja_path] + ninja_args, - env=third_party.google_env(), - quiet=True) diff --git a/tools/check_output_test.py b/tools/check_output_test.py deleted file mode 100755 index baeff23bfbbe09..00000000000000 --- a/tools/check_output_test.py +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env python -# Given a deno executable, this script execute several integration tests -# with it. The tests are stored in //tests/ and each script has a corresponding -# .out file which specifies what the stdout should be. -# -# Usage: check_output_test.py [path to deno executable] -import os -import sys -import subprocess -from util import pattern_match, parse_exit_code - -root_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) -tests_path = os.path.join(root_path, "tests") - - -def check_output_test(deno_exe_filename): - assert os.path.isfile(deno_exe_filename) - outs = sorted([ - filename for filename in os.listdir(tests_path) - if filename.endswith(".out") - ]) - assert len(outs) > 1 - tests = [(os.path.splitext(filename)[0], filename) for filename in outs] - for (script, out_filename) in tests: - script_abs = os.path.join(tests_path, script) - out_abs = os.path.join(tests_path, out_filename) - with open(out_abs, 'r') as f: - expected_out = f.read() - cmd = [deno_exe_filename, script_abs, "--reload"] - expected_code = parse_exit_code(script) - print " ".join(cmd) - actual_code = 0 - try: - actual_out = subprocess.check_output(cmd, universal_newlines=True) - except subprocess.CalledProcessError as e: - actual_code = e.returncode - actual_out = e.output - if expected_code == 0: - print "Expected success but got error. Output:" - print actual_out - sys.exit(1) - - if expected_code != actual_code: - print "Expected exit code %d but got %d" % (expected_code, - actual_code) - print "Output:" - print actual_out - sys.exit(1) - - if pattern_match(expected_out, actual_out) != True: - print "Expected output does not match actual." - print "Expected: " + expected_out - print "Actual: " + actual_out - sys.exit(1) - - -def main(argv): - check_output_test(argv[1]) - - -if __name__ == '__main__': - sys.exit(main(sys.argv)) diff --git a/tools/clang b/tools/clang deleted file mode 120000 index e3fc67857615a0..00000000000000 --- a/tools/clang +++ /dev/null @@ -1 +0,0 @@ -../third_party/v8/tools/clang \ No newline at end of file diff --git a/tools/format.py b/tools/format.py deleted file mode 100755 index af8cc5e4cc4e35..00000000000000 --- a/tools/format.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python -import os -from third_party import third_party_path, fix_symlinks, google_env, clang_format_path -from util import root_path, run, find_exts - -fix_symlinks() - -prettier = os.path.join(third_party_path, "node_modules", "prettier", - "bin-prettier.js") -tools_path = os.path.join(root_path, "tools") -rustfmt_config = os.path.join(tools_path, "rustfmt.toml") - -os.chdir(root_path) - -run([clang_format_path, "-i", "-style", "Google"] + - find_exts("libdeno", ".cc", ".h")) - -for fn in ["BUILD.gn", ".gn"] + find_exts("build_extra", ".gn", ".gni"): - run(["third_party/depot_tools/gn", "format", fn], env=google_env()) - -# TODO(ry) Install yapf in third_party. -run(["yapf", "-i"] + find_exts("tools/", ".py") + - find_exts("build_extra", ".py")) - -run(["node", prettier, "--write"] + find_exts("js/", ".js", ".ts") + - find_exts("tests/", ".js", ".ts") + - ["rollup.config.js", "tsconfig.json", "tslint.json"]) - -# Requires rustfmt 0.8.2 (flags were different in previous versions) -run(["rustfmt", "--config-path", rustfmt_config] + find_exts("src/", ".rs")) diff --git a/tools/http_server.py b/tools/http_server.py deleted file mode 100755 index f8c77f08b26e4e..00000000000000 --- a/tools/http_server.py +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env python -# Many tests expect there to be an http server on port 4545 servering the deno -# root directory. -import os -from threading import Thread -import SimpleHTTPServer -import SocketServer -from util import root_path -from time import sleep - -PORT = 4545 - - -def serve_forever(): - os.chdir(root_path) # Hopefully the main thread doesn't also chdir. - Handler = SimpleHTTPServer.SimpleHTTPRequestHandler - SocketServer.TCPServer.allow_reuse_address = True - httpd = SocketServer.TCPServer(("", PORT), Handler) - print "Deno test server http://localhost:%d/" % PORT - httpd.serve_forever() - - -def spawn(): - thread = Thread(target=serve_forever) - thread.daemon = True - thread.start() - sleep(1) # TODO I'm too lazy to figure out how to do this properly. - return thread - - -if __name__ == '__main__': - serve_forever() diff --git a/tools/lint.py b/tools/lint.py deleted file mode 100755 index 0ed4222418de7d..00000000000000 --- a/tools/lint.py +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env python -# Does google-lint on c++ files and ts-lint on typescript files - -import os -from util import run - -root_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) -third_party_path = os.path.join(root_path, "third_party") -cpplint = os.path.join(third_party_path, "cpplint", "cpplint.py") -tslint = os.path.join(third_party_path, "node_modules", "tslint", "bin", - "tslint") - -os.chdir(root_path) -run([ - "python", cpplint, "--filter=-build/include_subdir", "--repository=src", - "--extensions=cc,h", "--recursive", "src/." -]) -run(["node", tslint, "-p", ".", "--exclude", "**/gen/**/*.ts"]) diff --git a/tools/run_node.py b/tools/run_node.py deleted file mode 100755 index 4f6c87b91038c2..00000000000000 --- a/tools/run_node.py +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env python -""" -gn can only run python scripts. This launches a subprocess Node process. -The working dir of this program is out/Debug/ (AKA root_build_dir) -Before running node, we symlink js/node_modules to out/Debug/node_modules. -""" -import subprocess -import sys -import os -import util - -root_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) -tools_path = os.path.join(root_path, "tools") -third_party_path = os.path.join(root_path, "third_party") -target_abs = os.path.join(third_party_path, "node_modules") -target_rel = os.path.relpath(target_abs) - -util.remove_and_symlink(target_rel, "node_modules", True) -util.run(["node"] + sys.argv[1:], quiet=True) diff --git a/tools/run_rustc.py b/tools/run_rustc.py deleted file mode 100644 index f56ca8eb879c4d..00000000000000 --- a/tools/run_rustc.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env python -# Inspired by -# https://fuchsia.googlesource.com/build/+/master/rust/build_rustc_target.py -# Copyright 2018 The Fuchsia Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. -import sys -import os -import argparse -import subprocess -import util - - -# Updates the path of the main target in the depfile to the relative path -# from base_path build_output_path -def fix_depfile(depfile_path, base_path, build_output_path): - # It's important that the fixed-up depfile has the same mtime as before. - # Ninja relies on it to decide whether to rebuild the target it belongs to. - stat = os.stat(depfile_path) - with open(depfile_path, "r") as depfile: - content = depfile.read() - content_split = content.split(': ', 1) - target_path = os.path.relpath(build_output_path, start=base_path) - new_content = "%s: %s" % (target_path, content_split[1]) - with open(depfile_path, "w") as depfile: - depfile.write(new_content) - os.utime(depfile_path, (stat.st_atime, stat.st_mtime)) - - -def main(): - parser = argparse.ArgumentParser("Compiles a Rust crate") - parser.add_argument( - "--depfile", - help="Path at which the output depfile should be stored", - required=False) - parser.add_argument( - "--output_file", - help="Path at which the output file should be stored", - required=False) - args, rest = parser.parse_known_args() - - util.run(["rustc"] + rest, quiet=True) - - if args.depfile and args.output_file: - fix_depfile(args.depfile, os.getcwd(), args.output_file) - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/tools/rustfmt.toml b/tools/rustfmt.toml deleted file mode 100644 index 4c1eefaed54745..00000000000000 --- a/tools/rustfmt.toml +++ /dev/null @@ -1,2 +0,0 @@ -max_width = 80 -tab_spaces = 2 diff --git a/tools/setup.py b/tools/setup.py deleted file mode 100755 index 9dff9eb207e833..00000000000000 --- a/tools/setup.py +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/env python -import third_party -from util import run, root_path, build_path, build_mode -import os -import sys -from distutils.spawn import find_executable - - -def main(): - os.chdir(root_path) - - third_party.fix_symlinks() - third_party.download_gn() - third_party.download_clang_format() - third_party.download_clang() - third_party.maybe_download_sysroot() - - write_lastchange() - - mode = build_mode(default=None) - if mode is not None: - gn_gen(mode) - else: - gn_gen("release") - gn_gen("debug") - - -def write_if_not_exists(filename, contents): - if not os.path.exists(filename): - with open(filename, "w+") as f: - f.write(contents) - - -def write_lastchange(): - write_if_not_exists( - "build/util/LASTCHANGE", - "LASTCHANGE=c42e4ddbb7973bfb0c57a49ab6bf6dc432baad7e-\n") - write_if_not_exists("build/util/LASTCHANGE.committime", "1535518087") - # TODO Properly we should call the following script, but it seems to cause - # a rebuild on every commit. - # run([ - # sys.executable, "build/util/lastchange.py", "-o", - # "build/util/LASTCHANGE", "--source-dir", root_path, "--filter=" - # ]) - - -def get_gn_args(): - out = [] - if build_mode() == "release": - out += ["is_official_build=true"] - elif build_mode() == "debug": - pass - else: - print "Bad mode {}. Use 'release' or 'debug' (default)" % build_mode() - sys.exit(1) - if "DENO_BUILD_ARGS" in os.environ: - out += os.environ["DENO_BUILD_ARGS"].split() - - # Check if ccache or sccache are in the path, and if so we set cc_wrapper. - cc_wrapper = find_executable("ccache") or find_executable("sccache") - if cc_wrapper: - out += [r'cc_wrapper="%s"' % cc_wrapper] - # Windows needs a custom toolchain for cc_wrapper to work. - if os.name == "nt": - out += [ - 'custom_toolchain="//build_extra/toolchain/win:win_clang_x64"' - ] - - print "DENO_BUILD_ARGS:", out - - return out - - -# gn gen. -def gn_gen(mode): - os.environ["DENO_BUILD_MODE"] = mode - - # mkdir $build_path(). We do this so we can write args.gn before running gn gen. - if not os.path.isdir(build_path()): - os.makedirs(build_path()) - - # Rather than using gn gen --args we manually write the args.gn override file. - # This is to avoid quoting/escaping complications when passing overrides as - # command-line arguments. - args_filename = os.path.join(build_path(), "args.gn") - if os.path.exists(args_filename): - print "Skip writing args file: '%s' already exists." % args_filename - else: - gn_args = get_gn_args() - with open(args_filename, "w+") as f: - f.write("\n".join(gn_args) + "\n") - - run([third_party.gn_path, "gen", build_path()], - env=third_party.google_env()) - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/tools/sha256sum.py b/tools/sha256sum.py deleted file mode 100644 index d3273d5ba92d7b..00000000000000 --- a/tools/sha256sum.py +++ /dev/null @@ -1,70 +0,0 @@ -# Copyright 2018 the Deno authors. All rights reserved. MIT license. -""" -Computes the SHA256 hash and formats the result. -""" - -import argparse -from hashlib import sha256 -import os -import sys - - -def main(): - parser = argparse.ArgumentParser(description=__doc__) - - # Arguments specifying where input comes from. - # If multiple sources are specified, they are all concatenated together. - parser.add_argument( - "--input", - action="append", - dest="input", - type=str, - metavar="TEXT", - help="Hash literal text specified on the command line.") - parser.add_argument( - "--infile", - action="append", - dest="input", - type=read_file, - metavar="FILE", - help="Hash the contents of a file.") - - # Arguments dealing with output. - parser.add_argument( - "--format", - type=str, - dest="format", - default="%s", - metavar="TEMPLATE", - help="Format output using Python template (default = '%%s').") - parser.add_argument( - "--outfile", - dest="outfile", - type=argparse.FileType("wb"), - default=sys.stdout, - metavar="FILE", - help="Write the formatted hash to a file (default = stdout).") - - # Parse arguments. Print usage and exit if given no input. - args = parser.parse_args() - if (not args.input): - parser.print_usage() - return 1 - - # Compute the hash of all inputs concatenated together. - hasher = sha256() - for data in args.input: - hasher.update(data) - hash = hasher.hexdigest() - - # Format and write to specified out file (or the default, stdout). - args.outfile.write(args.format % hash) - - -def read_file(filename): - with open(filename, "rb") as file: - return file.read() - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/tools/sync_third_party.py b/tools/sync_third_party.py deleted file mode 100755 index cf0de30f3a927e..00000000000000 --- a/tools/sync_third_party.py +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env python -# Run this script if you are changing Deno's dependencies. -# To update the deno_third_party git repo after running this, try the following: -# cd third_party -# find . -type f | grep -v "\.git" | xargs -I% git add -f --no-warn-embedded-repo "%" - -import third_party - -third_party.fix_symlinks() - -third_party.run_yarn() -third_party.run_cargo() -third_party.run_gclient_sync() diff --git a/tools/test.py b/tools/test.py deleted file mode 100755 index 6e5cb548b9570a..00000000000000 --- a/tools/test.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env python -# Runs the full test suite. -# Usage: ./tools/test.py out/Debug -import os -import sys -from check_output_test import check_output_test -from util import executable_suffix, run, build_path -from unit_tests import unit_tests -from util_test import util_test -import subprocess -import http_server - - -def check_exists(filename): - if not os.path.exists(filename): - print "Required target doesn't exist:", filename - print "Run ./tools/build.py" - sys.exit(1) - - -def main(argv): - if len(argv) == 2: - build_dir = sys.argv[1] - elif len(argv) == 1: - build_dir = build_path() - else: - print "Usage: tools/test.py [build_dir]" - sys.exit(1) - - http_server.spawn() - - # Internal tools testing - util_test() - - test_cc = os.path.join(build_dir, "test_cc" + executable_suffix) - check_exists(test_cc) - run([test_cc]) - - test_rs = os.path.join(build_dir, "test_rs" + executable_suffix) - check_exists(test_rs) - run([test_rs]) - - deno_exe = os.path.join(build_dir, "deno" + executable_suffix) - check_exists(deno_exe) - unit_tests(deno_exe) - - check_exists(deno_exe) - check_output_test(deno_exe) - - deno_ns_exe = os.path.join(build_dir, "deno_ns" + executable_suffix) - check_exists(deno_ns_exe) - check_output_test(deno_ns_exe) - - -if __name__ == '__main__': - sys.exit(main(sys.argv)) diff --git a/tools/third_party.py b/tools/third_party.py deleted file mode 100644 index e831d57af4c61c..00000000000000 --- a/tools/third_party.py +++ /dev/null @@ -1,190 +0,0 @@ -#!/usr/bin/env python -# This script contains helper functions to work with the third_party subrepo. - -import os -import sys -from os import path -from util import find_exts, make_env, remove_and_symlink, rmtree, root_path, run - - -# Helper function that returns the full path to a subpath of the repo root. -def root(*subpath_parts): - return path.normpath(path.join(root_path, *subpath_parts)) - - -# Helper function that returns the full path to a file/dir in third_party. -def tp(*subpath_parts): - return root("third_party", *subpath_parts) - - -third_party_path = tp() -depot_tools_path = tp("depot_tools") -rust_crates_path = tp("rust_crates") -gn_path = tp(depot_tools_path, "gn") -clang_format_path = tp(depot_tools_path, "clang-format") -ninja_path = tp(depot_tools_path, "ninja") - - -# This function creates or modifies an environment so that it matches the -# expectations of various google tools (gn, gclient, etc). -def google_env(env=None, merge_env={}, depot_tools_path=depot_tools_path): - env = make_env(env=env, merge_env=merge_env) - # Depot_tools to be in the PATH, before Python. - path_prefix = depot_tools_path + os.path.pathsep - if not env['PATH'].startswith(path_prefix): - env['PATH'] = path_prefix + env['PATH'] - # We're not using Google's internal infrastructure. - if os.name == 'nt' and not 'DEPOT_TOOLS_WIN_TOOLCHAIN' in env: - env['DEPOT_TOOLS_WIN_TOOLCHAIN'] = "0" - return env - - -def fix_symlinks(): - # Ensure the third_party directory exists. - try: - os.makedirs(third_party_path) - except: - pass - - # Make symlinks to Yarn metadata living in the root repo. - remove_and_symlink("../package.json", tp("package.json")) - - # TODO(ry) Is it possible to remove these symlinks? - remove_and_symlink("v8/third_party/googletest", tp("googletest"), True) - remove_and_symlink("v8/third_party/jinja2", tp("jinja2"), True) - remove_and_symlink("v8/third_party/llvm-build", tp("llvm-build"), True) - remove_and_symlink("v8/third_party/markupsafe", tp("markupsafe"), True) - - # On Windows, git doesn't create the right type of symlink if the symlink - # and it's target are in different repos. Here we fix the symlinks that exist - # in the root repo while their target is in the third_party repo. - remove_and_symlink("third_party/node_modules", root("node_modules"), True) - remove_and_symlink("third_party/v8/build", root("build"), True) - remove_and_symlink("third_party/v8/buildtools", root("buildtools"), True) - remove_and_symlink("third_party/v8/build_overrides", - root("build_overrides"), True) - remove_and_symlink("third_party/v8/testing", root("testing"), True) - remove_and_symlink("../third_party/v8/tools/clang", root("tools/clang"), - True) - - -# Run Yarn to install JavaScript dependencies. -def run_yarn(): - run(["yarn", "install"], cwd=third_party_path) - - -# Run Cargo to install Rust dependencies. -def run_cargo(): - # Deletes the cargo index lockfile; it appears that cargo itself doesn't do it. - # If the lockfile ends up in the git repo, it'll make cargo hang for everyone - # else who tries to run sync_third_party. - def delete_lockfile(): - lockfiles = find_exts( - path.join(rust_crates_path, "registry/index"), '.cargo-index-lock') - for lockfile in lockfiles: - os.remove(lockfile) - - # Delete the index lockfile in case someone accidentally checked it in. - delete_lockfile() - - run(["cargo", "fetch", "--manifest-path=" + root("Cargo.toml")], - cwd=third_party_path, - merge_env={'CARGO_HOME': rust_crates_path}) - - # Delete the lockfile again so it doesn't end up in the git repo. - delete_lockfile() - - -# Run gclient to install other dependencies. -def run_gclient_sync(): - # Depot_tools will normally try to self-update, which will fail because - # it's not checked out from it's own git repository; gclient will then try - # to fix things up and not succeed, and and we'll end up with a huge mess. - # To work around this, we rename the `depot_tools` directory to - # `{root_path}/depot_tools_temp` first, and we set DEPOT_TOOLS_UPDATE=0 in - # the environment so depot_tools doesn't attempt to self-update. - # Since depot_tools is listed in .gclient_entries, gclient will install a - # fresh copy in `third_party/depot_tools`. - # If it all works out, we remove the depot_tools_temp directory afterwards. - depot_tools_temp_path = root("depot_tools_temp") - - # Rename depot_tools to depot_tools_temp. - try: - os.rename(depot_tools_path, depot_tools_temp_path) - except: - # If renaming failed, and the depot_tools_temp directory already exists, - # assume that it's still there because a prior run_gclient_sync() call - # failed half-way, before we got the chance to remove the temp dir. - # We'll use whatever is in the temp dir that was already there. - # If not, the user can recover by removing the temp directory manually. - if path.isdir(depot_tools_temp_path): - pass - else: - raise - - args = [ - "gclient", "sync", "--reset", "--shallow", "--no-history", "--nohooks" - ] - envs = { - 'DEPOT_TOOLS_UPDATE': "0", - 'GCLIENT_FILE': root("gclient_config.py") - } - env = google_env(depot_tools_path=depot_tools_temp_path, merge_env=envs) - run(args, cwd=third_party_path, env=env) - - # Delete the depot_tools_temp directory, but not before verifying that - # gclient did indeed install a fresh copy. - # Also check that `{depot_tools_temp_path}/gclient.py` exists, so a typo in - # this script won't accidentally blow out someone's home dir. - if (path.isdir(path.join(depot_tools_path, ".git")) - and path.isfile(path.join(depot_tools_path, "gclient.py")) - and path.isfile(path.join(depot_tools_temp_path, "gclient.py"))): - rmtree(depot_tools_temp_path) - - -# Download the given item from Google storage. -def download_from_google_storage(item, bucket): - if sys.platform == 'win32': - sha1_file = "v8/buildtools/win/%s.exe.sha1" % item - elif sys.platform == 'darwin': - sha1_file = "v8/buildtools/mac/%s.sha1" % item - elif sys.platform.startswith('linux'): - sha1_file = "v8/buildtools/linux64/%s.sha1" % item - - run([ - "python", - tp('depot_tools/download_from_google_storage.py'), - '--platform=' + sys.platform, - '--no_auth', - '--bucket=%s' % bucket, - '--sha1_file', - tp(sha1_file), - ], - env=google_env()) - - -# Download gn from Google storage. -def download_gn(): - download_from_google_storage('gn', 'chromium-gn') - - -# Download clang-format from Google storage. -def download_clang_format(): - download_from_google_storage('clang-format', 'chromium-clang-format') - - -# Download clang by calling the clang update script. -def download_clang(): - run(['python', - tp('v8/tools/clang/scripts/update.py'), '--if-needed'], - env=google_env()) - - -def maybe_download_sysroot(): - if sys.platform.startswith('linux'): - run([ - 'python', - tp('v8/build/linux/sysroot_scripts/install-sysroot.py'), - '--arch=amd64' - ], - env=google_env()) diff --git a/tools/unit_tests.py b/tools/unit_tests.py deleted file mode 100755 index a2cfa33b6d3680..00000000000000 --- a/tools/unit_tests.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python -from util import run -import sys - - -# We want to test many ops in deno which have different behavior depending on -# the permissions set. These tests can specify which permissions they expect, -# which appends a special string like "permW1N0" to the end of the test name. -# Here we run several copies of deno with different permissions, filtering the -# tests by the special string. permW0N0 means allow-write but not allow-net. -# See js/test_util.ts for more details. -def unit_tests(deno_exe): - run([deno_exe, "js/unit_tests.ts", "permW0N0"]) - run([deno_exe, "js/unit_tests.ts", "permW1N0", "--allow-write"]) - run([deno_exe, "js/unit_tests.ts", "permW0N1", "--allow-net"]) - run([ - deno_exe, "js/unit_tests.ts", "permW1N1", "--allow-write", - "--allow-net" - ]) - - -if __name__ == '__main__': - if len(sys.argv) < 2: - print "Usage ./tools/unit_tests.py out/debug/deno" - sys.exit(1) - unit_tests(sys.argv[1]) diff --git a/tools/util.py b/tools/util.py deleted file mode 100644 index b50b754c2efd74..00000000000000 --- a/tools/util.py +++ /dev/null @@ -1,175 +0,0 @@ -# Copyright 2018 the Deno authors. All rights reserved. MIT license. -import os -import re -import shutil -import stat -import sys -import subprocess - -executable_suffix = ".exe" if os.name == "nt" else "" -root_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) - - -def make_env(merge_env={}, env=None): - if env is None: - env = os.environ - env = env.copy() - for key in merge_env.keys(): - env[key] = merge_env[key] - return env - - -def run(args, quiet=False, cwd=None, env=None, merge_env={}): - args[0] = os.path.normpath(args[0]) - if not quiet: - print " ".join(args) - env = make_env(env=env, merge_env=merge_env) - shell = os.name == "nt" # Run through shell to make .bat/.cmd files work. - rc = subprocess.call(args, cwd=cwd, env=env, shell=shell) - if rc != 0: - sys.exit(rc) - - -def run_output(args, quiet=False, cwd=None, env=None, merge_env={}): - args[0] = os.path.normpath(args[0]) - if not quiet: - print " ".join(args) - env = make_env(env=env, merge_env=merge_env) - shell = os.name == "nt" # Run through shell to make .bat/.cmd files work. - return subprocess.check_output(args, cwd=cwd, env=env, shell=shell) - - -def remove_and_symlink(target, name, target_is_dir=False): - try: - # On Windows, directory symlink can only be removed with rmdir(). - if os.name == "nt" and os.path.isdir(name): - os.rmdir(name) - else: - os.unlink(name) - except: - pass - symlink(target, name, target_is_dir) - - -def symlink(target, name, target_is_dir=False): - if os.name == "nt": - from ctypes import WinDLL, WinError, GetLastError - from ctypes.wintypes import BOOLEAN, DWORD, LPCWSTR - - kernel32 = WinDLL('kernel32', use_last_error=False) - CreateSymbolicLinkW = kernel32.CreateSymbolicLinkW - CreateSymbolicLinkW.restype = BOOLEAN - CreateSymbolicLinkW.argtypes = (LPCWSTR, LPCWSTR, DWORD) - - # File-type symlinks can only use backslashes as separators. - target = os.path.normpath(target) - - # If the symlink points at a directory, it needs to have the appropriate - # flag set, otherwise the link will be created but it won't work. - if target_is_dir: - type_flag = 0x01 # SYMBOLIC_LINK_FLAG_DIRECTORY - else: - type_flag = 0 - - # Before Windows 10, creating symlinks requires admin privileges. - # As of Win 10, there is a flag that allows anyone to create them. - # Initially, try to use this flag. - unpriv_flag = 0x02 # SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE - r = CreateSymbolicLinkW(name, target, type_flag | unpriv_flag) - - # If it failed with ERROR_INVALID_PARAMETER, try again without the - # 'allow unprivileged create' flag. - if not r and GetLastError() == 87: # ERROR_INVALID_PARAMETER - r = CreateSymbolicLinkW(name, target, type_flag) - - # Throw if unsuccessful even after the second attempt. - if not r: - raise WinError() - else: - os.symlink(target, name) - - -def touch(fname): - if os.path.exists(fname): - os.utime(fname, None) - else: - open(fname, 'a').close() - - -# Recursive search for files of certain extensions. -# (Recursive glob doesn't exist in python 2.7.) -def find_exts(directory, *extensions): - matches = [] - for root, dirnames, filenames in os.walk(directory): - for filename in filenames: - for ext in extensions: - if filename.endswith(ext): - matches.append(os.path.join(root, filename)) - break - return matches - - -# The Python equivalent of `rm -rf`. -def rmtree(directory): - # On Windows, shutil.rmtree() won't delete files that have a readonly bit. - # Git creates some files that do. The 'onerror' callback deals with those. - def rm_readonly(func, path, _): - os.chmod(path, stat.S_IWRITE) - func(path) - - shutil.rmtree(directory, onerror=rm_readonly) - - -def build_mode(default="debug"): - if "DENO_BUILD_MODE" in os.environ: - return os.environ["DENO_BUILD_MODE"] - else: - return default - - -# E.G. "out/debug" -def build_path(): - if "DENO_BUILD_PATH" in os.environ: - return os.environ["DENO_BUILD_PATH"] - else: - return os.path.join(root_path, "out", build_mode()) - - -# Returns True if the expected matches the actual output, allowing variation -# from actual where expected has the wildcard (e.g. matches /.*/) -def pattern_match(pattern, string, wildcard="[WILDCARD]"): - if len(pattern) == 0: - return string == 0 - if pattern == wildcard: - return True - - parts = str.split(pattern, wildcard) - - if len(parts) == 1: - return pattern == string - - if string.startswith(parts[0]): - string = string[len(parts[0]):] - else: - return False - - for i in range(1, len(parts)): - if i == (len(parts) - 1): - if parts[i] == "" or parts[i] == "\n": - return True - found = string.find(parts[i]) - if found < 0: - return False - string = string[(found + len(parts[i])):] - - return len(string) == 0 - - -def parse_exit_code(s): - codes = [int(d or 1) for d in re.findall(r'error(\d*)', s)] - if len(codes) > 1: - assert False, "doesn't support multiple error codes." - elif len(codes) == 1: - return codes[0] - else: - return 0 diff --git a/tools/util_test.py b/tools/util_test.py deleted file mode 100644 index 308951bc2958db..00000000000000 --- a/tools/util_test.py +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright 2018 the Deno authors. All rights reserved. MIT license. -from util import pattern_match, parse_exit_code - - -def pattern_match_test(): - print "Testing util.pattern_match()..." - # yapf: disable - fixtures = [("foobarbaz", "foobarbaz", True), - ("[WILDCARD]", "foobarbaz", True), - ("foobar", "foobarbaz", False), - ("foo[WILDCARD]baz", "foobarbaz", True), - ("foo[WILDCARD]baz", "foobazbar", False), - ("foo[WILDCARD]baz[WILDCARD]qux", "foobarbazqatqux", True), - ("foo[WILDCARD]", "foobar", True), - ("foo[WILDCARD]baz[WILDCARD]", "foobarbazqat", True)] - # yapf: enable - - # Iterate through the fixture lists, testing each one - for (pattern, string, expected) in fixtures: - actual = pattern_match(pattern, string) - assert expected == actual, "expected %s for\nExpected:\n%s\nTo equal actual:\n%s" % ( - expected, pattern, string) - - assert pattern_match("foo[BAR]baz", "foobarbaz", - "[BAR]") == True, "expected wildcard to be set" - assert pattern_match("foo[BAR]baz", "foobazbar", - "[BAR]") == False, "expected wildcard to be set" - - -def parse_exit_code_test(): - print "Testing util.parse_exit_code()..." - assert 54 == parse_exit_code('hello_error54_world') - assert 1 == parse_exit_code('hello_error_world') - assert 0 == parse_exit_code('hello_world') - - -def util_test(): - pattern_match_test() - parse_exit_code_test() - - -if __name__ == '__main__': - util_test() diff --git a/tsconfig.json b/tsconfig.json deleted file mode 100644 index e6bf1688ba4b89..00000000000000 --- a/tsconfig.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "compilerOptions": { - "allowUnreachableCode": false, - "baseUrl": ".", - "module": "esnext", - "moduleResolution": "node", - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - "noLib": true, - "noUnusedLocals": true, - "paths": { - "*": ["*", "out/debug/*", "out/default/*", "out/release/*"] - }, - "preserveConstEnums": true, - "pretty": true, - "removeComments": true, - "sourceMap": true, - "strict": true, - "target": "esnext", - "types": [] - }, - "files": ["node_modules/typescript/lib/lib.esnext.d.ts", "js/main.ts"] -} diff --git a/tslint.json b/tslint.json deleted file mode 100644 index e521ee081be995..00000000000000 --- a/tslint.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "rules": { - "array-type": [true, "array-simple"], - "arrow-return-shorthand": true, - "ban": [ - true, - ["fit"], - ["fdescribe"], - ["xit"], - ["xdescribe"], - ["fitAsync"], - ["xitAsync"], - ["fitFakeAsync"], - ["xitFakeAsync"] - ], - "ban-types": [ - true, - ["Object", "Use {} instead."], - ["String", "Use 'string' instead."], - ["Number", "Use 'number' instead."], - ["Boolean", "Use 'boolean' instead."] - ], - "class-name": true, - "curly": true, - "interface-name": [true, "never-prefix"], - "jsdoc-format": true, - "forin": false, - "label-position": true, - "max-line-length": [true, 80], - "new-parens": true, - "no-angle-bracket-type-assertion": true, - "no-any": true, - "no-construct": true, - "no-consecutive-blank-lines": true, - "no-debugger": true, - "no-default-export": true, - "no-inferrable-types": true, - //"no-namespace": [true, "allow-declarations"], - "no-reference": true, - "no-require-imports": true, - "no-string-throw": true, - "no-unused-expression": true, - "no-unused-variable": true, - "no-var-keyword": true, - "object-literal-shorthand": true, - "only-arrow-functions": [ - true, - "allow-declarations", - "allow-named-functions" - ], - "prefer-const": true, - "quotemark": [true, "double"], - "radix": true, - "restrict-plus-operands": true, - "semicolon": [true, "always", "ignore-bound-class-methods"], - "switch-default": true, - "triple-equals": [true, "allow-null-check"], - "use-isnan": true, - "variable-name": [ - true, - "check-format", - "ban-keywords", - "allow-leading-underscore", - "allow-trailing-underscore" - ] - }, - "extends": ["tslint-no-circular-imports"] -}