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"] -}