Skip to content

Commit

Permalink
Merge pull request #10 from f-o-a-m/purs-0.15
Browse files Browse the repository at this point in the history
Purs 0.15
  • Loading branch information
iostat authored Sep 8, 2023
2 parents 7d099f8 + b483c42 commit 7a3b930
Show file tree
Hide file tree
Showing 19 changed files with 649 additions and 469 deletions.
25 changes: 25 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Run test suite

on:
push:
branches:
- '*'
workflow_dispatch:

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v4
with:
submodules: recursive
- name: setup node
uses: actions/setup-node@v3
with:
node-version-file: .nvmrc
- name: run tests
run: |
npm install
npm run build
npm run test
25 changes: 25 additions & 0 deletions .github/workflows/tidy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Code style and lint

on:
pull_request:
branches:
- master

workflow_dispatch:

jobs:
tidy:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v4
with:
submodules: recursive
- name: setup node
uses: actions/setup-node@v3
with:
node-version-file: .nvmrc
- name: run tidy
run: |
npm install
npm run tidy-check
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v20.6
8 changes: 8 additions & 0 deletions .tidyrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"indent": 2,
"operatorsFile": null,
"ribbon": 1,
"typeArrowPlacement": "first",
"unicode": "never",
"width": null
}
13 changes: 0 additions & 13 deletions .travis.yml

This file was deleted.

12 changes: 8 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
{
"private": true,
"scripts": {
"build": "spago build"
"build": "spago build",
"test": "spago -x test.dhall test",
"tidy": "purs-tidy format-in-place \"src/**/*.purs\" \"test/**/*.purs\"",
"tidy-check": "purs-tidy check \"src/**/*.purs\" \"test/**/*.purs\""
},
"dependencies": {
"bn.js": "^4.11.0",
Expand All @@ -11,11 +14,12 @@
"pulp": "^15.0.0",
"rlp": "^2.0.0",
"secp256k1": "^3.0.1",
"solc": "^0.5"
"solc": "^0.8"
},
"devDependencies": {
"purescript": "^0.15.8",
"purescript-psa": "^0.8.2",
"purescript": "^0.14.2",
"spago": "^0.20.3"
"spago": "^0.20.9",
"purs-tidy": "^0.10.0"
}
}
78 changes: 3 additions & 75 deletions packages.dhall
Original file line number Diff line number Diff line change
@@ -1,81 +1,9 @@
let upstream =
https://github.com/purescript/package-sets/releases/download/psc-0.14.2-20210629/packages.dhall sha256:534c490bb73cae75adb5a39871142fd8db5c2d74c90509797a80b8bb0d5c3f7b
https://raw.githubusercontent.com/f-o-a-m/package-sets/purs-0.15/purs-0.15.7-web3.dhall
sha256:2d868539460c47c2bf5ecf4c6b68c3ea3162849f2da9cd3f263b740299448d8f

let overrides = {=}

let additions =
{ web3 =
{ dependencies =
[ "aff"
, "avar"
, "console"
, "coroutines"
, "coroutine-transducers"
, "debug"
, "effect"
, "errors"
, "eth-core"
, "foreign"
, "foreign-generic"
, "fork"
, "free"
, "heterogeneous"
, "identity"
, "parsing"
, "partial"
, "profunctor-lenses"
, "psci-support"
, "tagged"
, "transformers"
, "typelevel-prelude"
, "variant"
]
, repo = "https://github.com/f-o-a-m/purescript-web3"
, version = "v4.0.0"
}
, eth-core =
{ dependencies =
[ "argonaut"
, "bytestrings"
, "console"
, "debug"
, "effect"
, "foreign-generic"
, "ordered-collections"
, "parsing"
, "prelude"
, "psci-support"
, "ring-modules"
, "simple-json"
]
, repo =
"https://github.com/f-o-a-m/purescript-eth-core.git"
, version =
"v7.0.0"
}
, coroutine-transducers =
{ dependencies =
[ "aff"
, "coroutines"
, "effect"
, "maybe"
, "psci-support"
]
, repo =
"https://github.com/blinky3713/purescript-coroutine-transducers"
, version =
"v1.0.0"
}
, tagged =
{ dependencies =
[ "identity"
, "profunctor"
]
, repo =
"https://github.com/kejace/purescript-tagged"
, version =
"v0.14"
}
}
let additions = {=}

in upstream // overrides // additions
1 change: 0 additions & 1 deletion spago.dhall
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ You can edit this file as you like.
, "newtype"
, "node-path"
, "prelude"
, "psci-support"
, "strings"
, "transformers"
, "tuples"
Expand Down
81 changes: 63 additions & 18 deletions src/Language/Solidity/Compiler.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use strict";

const solcMod = require('solc');
import solcMod from "solc";

function stringify(input) {
if (typeof input !== 'string') {
Expand All @@ -16,34 +16,79 @@ function objectify(input) {
return JSON.parse(input);
}

exports.defaultCompiler = solcMod;
export const defaultCompiler = solcMod;

exports.version = function(solc) {
export const version = function(solc) {
return solc.version();
}

exports.useCompiler = function(source) {
const requireFromString = function(str) {
const filename = "__solc_useCompiler";
const Module = module.constructor;
var m = new Module(filename, module);
m.filename = filename
m.paths = module.paths;
m._compile(source, "__solc_useCompiler");
return m.exports;
// Because PureScript 0.15+ forces all its modules to be ES modules, we can't just
// use require() like in a CJS module. Nor do we have the CommonJS `Module` API, where we can
// synthesize CJS modules at runtime. This is how useCompiler previously worked.
// import()ing from a data URI will make Node's loader assume we're trying to load an ES module, and there's
// no way to actually tell it to treat it as a CJS module -- `await import(..., { assert: { type: 'commonjs' }})`
// is actually an unsupported assertion (only `import assert { type: 'json' }` is supported by node).
//
// All of this is really unfortunate since solc is shipped as CommonJS. To get around this, we create a loader hook
// that forces Node to treat certain URLs as CommonJS.
//
// This unfortunately requires Node v20.6+
//
// Because we are a PureScript package and can't assume anything about where any relative
// "pure" JS files will be, but we do know our own module's URL, we keep this function here
// and in _useCompiler, we register this file (output/Language.Solidity.Compiler/foreign.js) as a Node loader.
const __DATA_JS_BASE64 = "data:text/javascript;base64,";
const __SOLC_CJS_MARKER = "/solc_cjs";
export function load(spec, context, next) {
if (typeof spec === 'string' && spec.startsWith(__DATA_JS_BASE64) && spec.endsWith(__SOLC_CJS_MARKER)) {
const cleanedSpec = spec.substring(__DATA_JS_BASE64.length, spec.length - __SOLC_CJS_MARKER.length);
return {
format: 'commonjs',
shortCircuit: true,
source: atob(cleanedSpec),
};
} else {
return next(spec, context);
}
return solcMod.setupMethods(requireFromString(source));
}

exports.callbackSuccess = function (contents) {
export const _useCompiler = function(source) {
return function (onError, onSuccess) {
const mkMod = async () => {
try {
// todo: this is obv. unusable in a browser. `purescript-solc` only really exists to
// to support Chanterelle, so this is fine for now...
const NodeModule = await import("node:module");
NodeModule.register(import.meta.url);
const url = __DATA_JS_BASE64 + btoa(source) + __SOLC_CJS_MARKER;
const mod = await import(url);
return mod.default;
} catch(e) {
console.error(e);
throw e;
}
};

const cancel = mkMod().then(m => onSuccess(solcMod.setupMethods(m)), e => {
onError(e);
});

return function(cancelError, onCancelerError, onCancelerSuccess) {
cancel();
onCancelerSuccess();
};
};
}

export const callbackSuccess = function (contents) {
return { "contents": contents }
};

exports.callbackFailure = function (error) {
export const callbackFailure = function (error) {
return { "error": error }
};

exports._loadRemoteVersion = function(version) {
export const _loadRemoteVersion = function(version) {
return function (onError, onSuccess) {
var cancel = solcMod.loadRemoteVersion(version, function(err, solcSnapshot) {
if (err) {
Expand All @@ -59,7 +104,7 @@ exports._loadRemoteVersion = function(version) {
}
};

exports._compile = function (solc, input, readCallback) {
export const _compile = function (solc, input, readCallback) {
return function() {
// support different versions of solc-js
// to understand what's going on here, keep this in mind:
Expand Down Expand Up @@ -156,4 +201,4 @@ exports._compile = function (solc, input, readCallback) {
return readCallback(requestedFile)();
}));
}
};
};
12 changes: 10 additions & 2 deletions src/Language/Solidity/Compiler.purs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ foreign import callbackSuccess :: String -> SolcReadFileCallbackResult
foreign import callbackFailure :: String -> SolcReadFileCallbackResult
foreign import defaultCompiler :: SolidityCompiler
foreign import version :: SolidityCompiler -> String
foreign import useCompiler :: String -> SolidityCompiler
foreign import _useCompiler :: String -> EffectFnAff SolidityCompiler
foreign import _loadRemoteVersion :: String -> EffectFnAff SolidityCompiler
foreign import _compile :: Fn3 SolidityCompiler Json (FilePath -> Effect SolcReadFileCallbackResult) (Effect Json)

Expand All @@ -42,11 +42,19 @@ compile
compile solc input readFile = liftEffect $ map (lmap printJsonDecodeError) $
A.decodeJson <$> runFn3 _compile solc (encodeJson input) liftedCallback

where liftedCallback = map (either callbackFailure callbackSuccess) <<< readFile
where
liftedCallback = map (either callbackFailure callbackSuccess) <<< readFile

loadRemoteVersion
:: forall m
. MonadAff m
=> String
-> m SolidityCompiler
loadRemoteVersion = liftAff <<< fromEffectFnAff <<< _loadRemoteVersion

useCompiler
:: forall m
. MonadAff m
=> String
-> m SolidityCompiler
useCompiler = liftAff <<< fromEffectFnAff <<< _useCompiler
10 changes: 5 additions & 5 deletions src/Language/Solidity/Compiler/Releases.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
"use strict";

const http = require('http');
const https = require('https');
const MemoryStream = require('memorystream');
import http from "http";
import https from "https";
import MemoryStream from "memorystream";

exports._getURL = function(url) {
export const _getURL = function(url) {
const httpImpl = url.startsWith("https:") ? https : http;
return function(onError, onSuccess) {
var cancel = httpImpl.get(url, function (res) {
var error;
if (res.statusCode != 200) {
error = new Error("Request failed, status code " + statusCode);
error = new Error("Request failed to " + url + " status code " + res.statusCode);
}

if (error) {
Expand Down
Loading

0 comments on commit 7a3b930

Please sign in to comment.