mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-04-22 06:48:03 +00:00
Add all resolc dependencies to resolc_web.js file (#176)
This commit is contained in:
committed by
GitHub
parent
374563bbe5
commit
79ec4dd04b
@@ -87,6 +87,7 @@ jobs:
|
||||
path: |
|
||||
${{ env.REVIVE_WASM_INSTALL_DIR }}/resolc.js
|
||||
${{ env.REVIVE_WASM_INSTALL_DIR }}/resolc.wasm
|
||||
${{ env.REVIVE_WASM_INSTALL_DIR }}/resolc_web.js
|
||||
retention-days: 1
|
||||
|
||||
test-revive-wasm:
|
||||
|
||||
@@ -30,6 +30,7 @@ install-npm:
|
||||
|
||||
install-wasm: install-npm
|
||||
cargo build --target wasm32-unknown-emscripten -p revive-solidity --release --no-default-features
|
||||
npm run build:package
|
||||
|
||||
install-llvm-builder:
|
||||
cargo install --path crates/llvm-builder
|
||||
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const { minify } = require("terser");
|
||||
|
||||
const SOLJSON_URI =
|
||||
"https://binaries.soliditylang.org/wasm/soljson-v0.8.28+commit.7893614a.js";
|
||||
const RESOLC_WASM_URI = "http://127.0.0.1:8080/resolc.wasm";
|
||||
const RESOLC_WASM_TARGET_DIR = path.join(
|
||||
__dirname,
|
||||
"../target/wasm32-unknown-emscripten/release",
|
||||
);
|
||||
const RESOLC_JS = path.join(RESOLC_WASM_TARGET_DIR, "resolc.js");
|
||||
const RESOLC_WEB_JS = path.join(RESOLC_WASM_TARGET_DIR, "resolc_web.js");
|
||||
|
||||
const resolcJs = fs.readFileSync(RESOLC_JS, "utf-8");
|
||||
|
||||
const packedJsContent = `
|
||||
if (typeof importScripts === "function") {
|
||||
importScripts("${SOLJSON_URI}");
|
||||
|
||||
var moduleArgs = {
|
||||
wasmBinary: (function () {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "${RESOLC_WASM_URI}", false);
|
||||
xhr.responseType = "arraybuffer";
|
||||
xhr.send(null);
|
||||
return new Uint8Array(xhr.response);
|
||||
})(),
|
||||
soljson: Module
|
||||
};
|
||||
} else {
|
||||
console.log("Not a WebWorker, skipping Soljson and WASM loading.");
|
||||
}
|
||||
|
||||
${resolcJs}
|
||||
|
||||
createRevive = createRevive.bind(null, moduleArgs);
|
||||
`;
|
||||
|
||||
minify(packedJsContent)
|
||||
.then((minifiedJs) => {
|
||||
if (minifiedJs.error) {
|
||||
console.error("Error during minification:", minifiedJs.error);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
fs.writeFileSync(RESOLC_WEB_JS, minifiedJs.code, "utf-8");
|
||||
console.log(`Combined script written to ${RESOLC_WEB_JS}`);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("Minification failed:", err);
|
||||
process.exit(1);
|
||||
});
|
||||
+80
-49
@@ -1,16 +1,23 @@
|
||||
const { test, expect } = require('@playwright/test');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { test, expect } = require("@playwright/test");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
function loadFixture(fixture) {
|
||||
const fixturePath = path.resolve(__dirname, `../fixtures/${fixture}`);
|
||||
return JSON.parse(fs.readFileSync(fixturePath, 'utf-8'));
|
||||
return JSON.parse(fs.readFileSync(fixturePath, "utf-8"));
|
||||
}
|
||||
|
||||
async function loadTestPage(page) {
|
||||
await page.goto("http://127.0.0.1:8080");
|
||||
const outputElement = page.locator("#output");
|
||||
await outputElement.waitFor({ state: "visible" });
|
||||
await page.setContent("");
|
||||
}
|
||||
|
||||
async function runWorker(page, input) {
|
||||
return await page.evaluate((input) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const worker = new Worker('worker.js');
|
||||
const worker = new Worker("worker.js");
|
||||
worker.postMessage(JSON.stringify(input));
|
||||
|
||||
worker.onmessage = (event) => {
|
||||
@@ -26,69 +33,87 @@ async function runWorker(page, input) {
|
||||
}, input);
|
||||
}
|
||||
|
||||
test('should successfully compile valid Solidity code in the browser', async ({ page }) => {
|
||||
await page.goto("http://127.0.0.1:8080");
|
||||
await page.setContent("");
|
||||
const standardInput = loadFixture('storage.json')
|
||||
test("should successfully compile valid Solidity code in browser", async ({
|
||||
page,
|
||||
}) => {
|
||||
await loadTestPage(page);
|
||||
const standardInput = loadFixture("storage.json");
|
||||
const result = await runWorker(page, standardInput);
|
||||
|
||||
expect(typeof result).toBe('string');
|
||||
|
||||
expect(typeof result).toBe("string");
|
||||
let output = JSON.parse(result);
|
||||
expect(output).toHaveProperty('contracts');
|
||||
expect(output.contracts['fixtures/storage.sol']).toHaveProperty('Storage');
|
||||
expect(output.contracts['fixtures/storage.sol'].Storage).toHaveProperty('abi');
|
||||
expect(output.contracts['fixtures/storage.sol'].Storage).toHaveProperty('evm');
|
||||
expect(output.contracts['fixtures/storage.sol'].Storage.evm).toHaveProperty('bytecode');
|
||||
expect(output).toHaveProperty("contracts");
|
||||
expect(output.contracts["fixtures/storage.sol"]).toHaveProperty("Storage");
|
||||
expect(output.contracts["fixtures/storage.sol"].Storage).toHaveProperty(
|
||||
"abi",
|
||||
);
|
||||
expect(output.contracts["fixtures/storage.sol"].Storage).toHaveProperty(
|
||||
"evm",
|
||||
);
|
||||
expect(output.contracts["fixtures/storage.sol"].Storage.evm).toHaveProperty(
|
||||
"bytecode",
|
||||
);
|
||||
});
|
||||
|
||||
test('should successfully compile large valid Solidity code in the browser', async ({ page }) => {
|
||||
await page.goto("http://127.0.0.1:8080");
|
||||
await page.setContent("");
|
||||
const standardInput = loadFixture('token.json')
|
||||
test("should successfully compile large valid Solidity code in browser", async ({
|
||||
page,
|
||||
browserName,
|
||||
}) => {
|
||||
if (browserName === "firefox") {
|
||||
// Skipping tests with large contracts on Firefox due to out-of-memory issues.
|
||||
test.skip();
|
||||
}
|
||||
await loadTestPage(page);
|
||||
const standardInput = loadFixture("token.json");
|
||||
const result = await runWorker(page, standardInput);
|
||||
|
||||
expect(typeof result).toBe('string');
|
||||
|
||||
expect(typeof result).toBe("string");
|
||||
let output = JSON.parse(result);
|
||||
expect(output).toHaveProperty('contracts');
|
||||
expect(output.contracts['fixtures/token.sol']).toHaveProperty('MyToken');
|
||||
expect(output.contracts['fixtures/token.sol'].MyToken).toHaveProperty('abi');
|
||||
expect(output.contracts['fixtures/token.sol'].MyToken).toHaveProperty('evm');
|
||||
expect(output.contracts['fixtures/token.sol'].MyToken.evm).toHaveProperty('bytecode');
|
||||
expect(output).toHaveProperty("contracts");
|
||||
expect(output.contracts["fixtures/token.sol"]).toHaveProperty("MyToken");
|
||||
expect(output.contracts["fixtures/token.sol"].MyToken).toHaveProperty("abi");
|
||||
expect(output.contracts["fixtures/token.sol"].MyToken).toHaveProperty("evm");
|
||||
expect(output.contracts["fixtures/token.sol"].MyToken.evm).toHaveProperty(
|
||||
"bytecode",
|
||||
);
|
||||
});
|
||||
|
||||
test('should throw an error for invalid Solidity code in the browser', async ({ page }) => {
|
||||
await page.goto("http://127.0.0.1:8080");
|
||||
await page.setContent("");
|
||||
const standardInput = loadFixture('invalid_contract_content.json')
|
||||
test("should throw an error for invalid Solidity code in browser", async ({
|
||||
page,
|
||||
}) => {
|
||||
await loadTestPage(page);
|
||||
const standardInput = loadFixture("invalid_contract_content.json");
|
||||
const result = await runWorker(page, standardInput);
|
||||
|
||||
expect(typeof result).toBe('string');
|
||||
expect(typeof result).toBe("string");
|
||||
let output = JSON.parse(result);
|
||||
expect(output).toHaveProperty('errors');
|
||||
expect(output).toHaveProperty("errors");
|
||||
expect(Array.isArray(output.errors)).toBeTruthy(); // Check if it's an array
|
||||
expect(output.errors.length).toBeGreaterThan(0);
|
||||
expect(output.errors[0]).toHaveProperty('type');
|
||||
expect(output.errors[0].type).toContain('ParserError');
|
||||
expect(output.errors[0]).toHaveProperty("type");
|
||||
expect(output.errors[0].type).toContain("ParserError");
|
||||
});
|
||||
|
||||
test('should return not found error for missing imports in the browser', async ({page}) => {
|
||||
await page.goto("http://127.0.0.1:8080");
|
||||
await page.setContent("");
|
||||
const standardInput = loadFixture('missing_import.json')
|
||||
test("should return not found error for missing imports in browser", async ({
|
||||
page,
|
||||
}) => {
|
||||
await loadTestPage(page);
|
||||
const standardInput = loadFixture("missing_import.json");
|
||||
const result = await runWorker(page, standardInput);
|
||||
|
||||
expect(typeof result).toBe('string');
|
||||
|
||||
expect(typeof result).toBe("string");
|
||||
let output = JSON.parse(result);
|
||||
expect(output).toHaveProperty('errors');
|
||||
expect(output).toHaveProperty("errors");
|
||||
expect(Array.isArray(output.errors)).toBeTruthy(); // Check if it's an array
|
||||
expect(output.errors.length).toBeGreaterThan(0);
|
||||
expect(output.errors[0]).toHaveProperty('message');
|
||||
expect(output.errors[0].message).toContain('Source "nonexistent/console.sol" not found');
|
||||
expect(output.errors[0]).toHaveProperty("message");
|
||||
expect(output.errors[0].message).toContain(
|
||||
'Source "nonexistent/console.sol" not found',
|
||||
);
|
||||
});
|
||||
|
||||
test('should successfully compile a valid Solidity contract that instantiates another contract in the browser', async ({ page }) => {
|
||||
await page.goto("http://127.0.0.1:8080");
|
||||
await page.setContent("");
|
||||
await loadTestPage(page);
|
||||
const standardInput = loadFixture('instantiate.json')
|
||||
const result = await runWorker(page, standardInput);
|
||||
|
||||
@@ -105,9 +130,15 @@ test('should successfully compile a valid Solidity contract that instantiates an
|
||||
expect(output.contracts['fixtures/instantiate.sol'].MainContract.evm).toHaveProperty('bytecode');
|
||||
});
|
||||
|
||||
test('should successfully compile a valid Solidity contract that instantiates the token contracts in the browser', async ({ page }) => {
|
||||
await page.goto("http://127.0.0.1:8080");
|
||||
await page.setContent("");
|
||||
test('should successfully compile a valid Solidity contract that instantiates the token contracts in the browser', async ({
|
||||
page,
|
||||
browserName,
|
||||
}) => {
|
||||
if (browserName === "firefox") {
|
||||
// Skipping tests with large contracts on Firefox due to out-of-memory issues.
|
||||
test.skip();
|
||||
}
|
||||
await loadTestPage(page);
|
||||
const standardInput = loadFixture('instantiate_tokens.json')
|
||||
const result = await runWorker(page, standardInput);
|
||||
|
||||
|
||||
+55
-52
@@ -1,54 +1,57 @@
|
||||
var Module = {
|
||||
stdinData: null,
|
||||
stdinDataPosition: 0,
|
||||
stdoutData: [],
|
||||
stderrData: [],
|
||||
Module.stdinData = null;
|
||||
Module.stdinDataPosition = 0;
|
||||
Module.stdoutData = [];
|
||||
Module.stderrData = [];
|
||||
|
||||
// Function to read and return all collected stdout data as a string
|
||||
readFromStdout: function() {
|
||||
if (!this.stdoutData.length) return "";
|
||||
const decoder = new TextDecoder('utf-8');
|
||||
const data = decoder.decode(new Uint8Array(this.stdoutData));
|
||||
this.stdoutData = [];
|
||||
return data;
|
||||
},
|
||||
|
||||
// Function to read and return all collected stderr data as a string
|
||||
readFromStderr: function() {
|
||||
if (!this.stderrData.length) return "";
|
||||
const decoder = new TextDecoder('utf-8');
|
||||
const data = decoder.decode(new Uint8Array(this.stderrData));
|
||||
this.stderrData = [];
|
||||
return data;
|
||||
},
|
||||
|
||||
// Function to set input data for stdin
|
||||
writeToStdin: function(data) {
|
||||
const encoder = new TextEncoder();
|
||||
this.stdinData = encoder.encode(data);
|
||||
this.stdinDataPosition = 0;
|
||||
},
|
||||
|
||||
// `preRun` is called before the program starts running
|
||||
preRun: function() {
|
||||
// Define a custom stdin function
|
||||
function customStdin() {
|
||||
if (!Module.stdinData || Module.stdinDataPosition >= Module.stdinData.length) {
|
||||
return null; // End of input (EOF)
|
||||
}
|
||||
return Module.stdinData[Module.stdinDataPosition++];
|
||||
}
|
||||
|
||||
// Define a custom stdout function
|
||||
function customStdout(char) {
|
||||
Module.stdoutData.push(char);
|
||||
}
|
||||
|
||||
// Define a custom stderr function
|
||||
function customStderr(char) {
|
||||
Module.stderrData.push(char);
|
||||
}
|
||||
|
||||
FS.init(customStdin, customStdout, customStderr);
|
||||
},
|
||||
// Method to read all collected stdout data
|
||||
Module.readFromStdout = function () {
|
||||
if (!Module.stdoutData.length) return "";
|
||||
const decoder = new TextDecoder("utf-8");
|
||||
const data = decoder.decode(new Uint8Array(Module.stdoutData));
|
||||
Module.stdoutData = [];
|
||||
return data;
|
||||
};
|
||||
|
||||
// Method to read all collected stderr data
|
||||
Module.readFromStderr = function () {
|
||||
if (!Module.stderrData.length) return "";
|
||||
const decoder = new TextDecoder("utf-8");
|
||||
const data = decoder.decode(new Uint8Array(Module.stderrData));
|
||||
Module.stderrData = [];
|
||||
return data;
|
||||
};
|
||||
|
||||
// Method to write data to stdin
|
||||
Module.writeToStdin = function (data) {
|
||||
const encoder = new TextEncoder();
|
||||
Module.stdinData = encoder.encode(data);
|
||||
Module.stdinDataPosition = 0;
|
||||
};
|
||||
|
||||
// Override the `preRun` method to customize file system initialization
|
||||
Module.preRun = Module.preRun || [];
|
||||
Module.preRun.push(function () {
|
||||
// Custom stdin function
|
||||
function customStdin() {
|
||||
if (
|
||||
!Module.stdinData ||
|
||||
Module.stdinDataPosition >= Module.stdinData.length
|
||||
) {
|
||||
return null; // End of input (EOF)
|
||||
}
|
||||
return Module.stdinData[Module.stdinDataPosition++];
|
||||
}
|
||||
|
||||
// Custom stdout function
|
||||
function customStdout(char) {
|
||||
Module.stdoutData.push(char);
|
||||
}
|
||||
|
||||
// Custom stderr function
|
||||
function customStderr(char) {
|
||||
Module.stderrData.push(char);
|
||||
}
|
||||
|
||||
// Initialize the FS (File System) with custom handlers
|
||||
FS.init(customStdin, customStdout, customStderr);
|
||||
});
|
||||
|
||||
@@ -1,29 +1,34 @@
|
||||
mergeInto(LibraryManager.library, {
|
||||
soljson_compile: function(inputPtr, inputLen) {
|
||||
const inputJson = UTF8ToString(inputPtr, inputLen);
|
||||
const output = Module.soljson.cwrap('solidity_compile', 'string', ['string'])(inputJson);
|
||||
return stringToNewUTF8(output);
|
||||
},
|
||||
soljson_version: function() {
|
||||
const version = Module.soljson.cwrap("solidity_version", "string", [])();
|
||||
return stringToNewUTF8(version);
|
||||
},
|
||||
resolc_compile: function(inputPtr, inputLen) {
|
||||
const inputJson = UTF8ToString(inputPtr, inputLen);
|
||||
var revive = createRevive();
|
||||
revive.writeToStdin(inputJson);
|
||||
soljson_compile: function (inputPtr, inputLen) {
|
||||
const inputJson = UTF8ToString(inputPtr, inputLen);
|
||||
const output = Module.soljson.cwrap("solidity_compile", "string", [
|
||||
"string",
|
||||
])(inputJson);
|
||||
return stringToNewUTF8(output);
|
||||
},
|
||||
soljson_version: function () {
|
||||
const version = Module.soljson.cwrap("solidity_version", "string", [])();
|
||||
return stringToNewUTF8(version);
|
||||
},
|
||||
resolc_compile: function (inputPtr, inputLen) {
|
||||
const inputJson = UTF8ToString(inputPtr, inputLen);
|
||||
var revive = createRevive();
|
||||
revive.writeToStdin(inputJson);
|
||||
|
||||
// Call main on the new instance
|
||||
const result = revive.callMain(['--recursive-process']);
|
||||
// Call main on the new instance
|
||||
const result = revive.callMain(["--recursive-process"]);
|
||||
|
||||
if (result) {
|
||||
const stderrString = revive.readFromStderr();
|
||||
const error = JSON.stringify({ type: 'error', message: stderrString || "Unknown error" });
|
||||
return stringToNewUTF8(error);
|
||||
} else {
|
||||
const stdoutString = revive.readFromStdout();
|
||||
const json = JSON.stringify({ type: 'success', data: stdoutString });
|
||||
return stringToNewUTF8(json);
|
||||
}
|
||||
},
|
||||
if (result) {
|
||||
const stderrString = revive.readFromStderr();
|
||||
const error = JSON.stringify({
|
||||
type: "error",
|
||||
message: stderrString || "Unknown error",
|
||||
});
|
||||
return stringToNewUTF8(error);
|
||||
} else {
|
||||
const stdoutString = revive.readFromStdout();
|
||||
const json = JSON.stringify({ type: "success", data: stdoutString });
|
||||
return stringToNewUTF8(json);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
const soljson = require('solc/soljson');
|
||||
const createRevive = require('./resolc.js');
|
||||
const soljson = require("solc/soljson");
|
||||
const createRevive = require("./resolc.js");
|
||||
|
||||
async function compile(standardJsonInput) {
|
||||
if (!standardJsonInput) {
|
||||
throw new Error('Input JSON for the Solidity compiler is required.');
|
||||
throw new Error("Input JSON for the Solidity compiler is required.");
|
||||
}
|
||||
|
||||
// Initialize the compiler
|
||||
@@ -14,7 +14,7 @@ async function compile(standardJsonInput) {
|
||||
compiler.writeToStdin(JSON.stringify(standardJsonInput));
|
||||
|
||||
// Run the compiler
|
||||
compiler.callMain(['--standard-json']);
|
||||
compiler.callMain(["--standard-json"]);
|
||||
|
||||
// Collect output
|
||||
const stdout = compiler.readFromStdout();
|
||||
@@ -29,4 +29,4 @@ async function compile(standardJsonInput) {
|
||||
return stdout;
|
||||
}
|
||||
|
||||
module.exports = { compile };
|
||||
module.exports = { compile };
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
const { compile } = require('./revive.js');
|
||||
const { compile } = require("./revive.js");
|
||||
|
||||
const compilerStandardJsonInput = {
|
||||
language: 'Solidity',
|
||||
sources: {
|
||||
'MyContract.sol': {
|
||||
content: `
|
||||
language: "Solidity",
|
||||
sources: {
|
||||
"MyContract.sol": {
|
||||
content: `
|
||||
// SPDX-License-Identifier: UNLICENSED
|
||||
pragma solidity ^0.8.0;
|
||||
contract MyContract {
|
||||
@@ -13,26 +13,26 @@ const compilerStandardJsonInput = {
|
||||
}
|
||||
}
|
||||
`,
|
||||
},
|
||||
},
|
||||
settings: {
|
||||
optimizer: {
|
||||
enabled: true,
|
||||
runs: 200,
|
||||
},
|
||||
outputSelection: {
|
||||
"*": {
|
||||
"*": ["abi"],
|
||||
},
|
||||
},
|
||||
settings: {
|
||||
optimizer: {
|
||||
enabled: true,
|
||||
runs: 200,
|
||||
},
|
||||
outputSelection: {
|
||||
'*': {
|
||||
'*': ['abi'],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
async function runCompiler() {
|
||||
let output = await compile(compilerStandardJsonInput)
|
||||
let output = await compile(compilerStandardJsonInput);
|
||||
console.log("Output: " + output);
|
||||
}
|
||||
|
||||
runCompiler().catch(err => {
|
||||
console.error('Error:', err);
|
||||
runCompiler().catch((err) => {
|
||||
console.error("Error:", err);
|
||||
});
|
||||
|
||||
+49
-47
@@ -1,51 +1,53 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Web Worker Example</title>
|
||||
<style>
|
||||
/* Ensure the pre tag wraps long lines */
|
||||
pre {
|
||||
white-space: pre-wrap; /* Wrap long lines */
|
||||
word-wrap: break-word; /* Break long words */
|
||||
max-width: 100%; /* Optional: Ensures it doesn't overflow container */
|
||||
overflow-wrap: break-word; /* Another method for wrapping */
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Web Worker Example</title>
|
||||
<style>
|
||||
/* Ensure the pre tag wraps long lines */
|
||||
pre {
|
||||
white-space: pre-wrap; /* Wrap long lines */
|
||||
word-wrap: break-word; /* Break long words */
|
||||
max-width: 100%; /* Optional: Ensures it doesn't overflow container */
|
||||
overflow-wrap: break-word; /* Another method for wrapping */
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Revive Compilation Output</h1>
|
||||
<pre id="output"></pre>
|
||||
<script>
|
||||
var outputElement = document.getElementById('output');
|
||||
var worker = new Worker('./worker.js');
|
||||
const standardJsonInput = {
|
||||
language: 'Solidity',
|
||||
sources: {
|
||||
contract: {
|
||||
content: 'contract MyContract { function f() public { } }',
|
||||
}
|
||||
},
|
||||
settings: {
|
||||
optimizer: {
|
||||
enabled: true,
|
||||
runs: 200,
|
||||
},
|
||||
outputSelection: {
|
||||
'*': {
|
||||
'*': ['abi'],
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
worker.addEventListener('message', function (e) {
|
||||
outputElement.textContent = e.data.output;
|
||||
}, false);
|
||||
|
||||
worker.postMessage(JSON.stringify(standardJsonInput));
|
||||
</script>
|
||||
</body>
|
||||
<body>
|
||||
<h1>Revive Compilation Output</h1>
|
||||
<pre id="output"></pre>
|
||||
<script>
|
||||
var outputElement = document.getElementById("output");
|
||||
var worker = new Worker("./worker.js");
|
||||
const standardJsonInput = {
|
||||
language: "Solidity",
|
||||
sources: {
|
||||
contract: {
|
||||
content: "contract MyContract { function f() public { } }",
|
||||
},
|
||||
},
|
||||
settings: {
|
||||
optimizer: {
|
||||
enabled: true,
|
||||
runs: 200,
|
||||
},
|
||||
outputSelection: {
|
||||
"*": {
|
||||
"*": ["abi"],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
worker.addEventListener(
|
||||
"message",
|
||||
function (e) {
|
||||
outputElement.textContent = e.data.output;
|
||||
},
|
||||
false,
|
||||
);
|
||||
|
||||
worker.postMessage(JSON.stringify(standardJsonInput));
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
../../../target/wasm32-unknown-emscripten/release/resolc.js
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../../../target/wasm32-unknown-emscripten/release/resolc_web.js
|
||||
@@ -1,18 +1,14 @@
|
||||
|
||||
importScripts('./soljson.js');
|
||||
importScripts('./resolc.js');
|
||||
importScripts("./resolc_web.js");
|
||||
|
||||
// Handle messages from the main thread
|
||||
onmessage = async function (e) {
|
||||
const m = createRevive();
|
||||
const m = createRevive();
|
||||
|
||||
m.soljson = Module;
|
||||
// Set input data for stdin
|
||||
m.writeToStdin(e.data);
|
||||
|
||||
// Set input data for stdin
|
||||
m.writeToStdin(e.data);
|
||||
// Compile the Solidity source code
|
||||
m.callMain(["--standard-json"]);
|
||||
|
||||
// Compile the Solidity source code
|
||||
m.callMain(['--standard-json']);
|
||||
|
||||
postMessage({output: m.readFromStdout() || m.readFromStderr()});
|
||||
postMessage({ output: m.readFromStdout() || m.readFromStderr() });
|
||||
};
|
||||
|
||||
@@ -1,22 +1,19 @@
|
||||
{
|
||||
"language": "Solidity",
|
||||
"sources": {
|
||||
"fixtures/storage.sol": {
|
||||
"content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\nimport \"nonexistent/console.sol\";\ncontract MyContract { function greet() public pure returns (string memory) { return \"Hello\" // Missing semicolon }}"
|
||||
}
|
||||
"language": "Solidity",
|
||||
"sources": {
|
||||
"fixtures/storage.sol": {
|
||||
"content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\nimport \"nonexistent/console.sol\";\ncontract MyContract { function greet() public pure returns (string memory) { return \"Hello\" // Missing semicolon }}"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"optimizer": {
|
||||
"enabled": true,
|
||||
"runs": 200
|
||||
},
|
||||
"settings": {
|
||||
"optimizer": {
|
||||
"enabled": true,
|
||||
"runs": 200
|
||||
},
|
||||
"outputSelection": {
|
||||
"*": {
|
||||
"*": [
|
||||
"abi"
|
||||
]
|
||||
}
|
||||
"outputSelection": {
|
||||
"*": {
|
||||
"*": ["abi"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,22 +1,19 @@
|
||||
{
|
||||
"language": "Solidity",
|
||||
"sources": {
|
||||
"fixtures/storage.sol": {
|
||||
"content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\nimport \"nonexistent/console.sol\";\ncontract MyContract { function f() public { } }"
|
||||
}
|
||||
"language": "Solidity",
|
||||
"sources": {
|
||||
"fixtures/storage.sol": {
|
||||
"content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\nimport \"nonexistent/console.sol\";\ncontract MyContract { function f() public { } }"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"optimizer": {
|
||||
"enabled": true,
|
||||
"runs": 200
|
||||
},
|
||||
"settings": {
|
||||
"optimizer": {
|
||||
"enabled": true,
|
||||
"runs": 200
|
||||
},
|
||||
"outputSelection": {
|
||||
"*": {
|
||||
"*": [
|
||||
"abi"
|
||||
]
|
||||
}
|
||||
"outputSelection": {
|
||||
"*": {
|
||||
"*": ["abi"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+14
-17
@@ -1,22 +1,19 @@
|
||||
{
|
||||
"language": "Solidity",
|
||||
"sources": {
|
||||
"fixtures/storage.sol": {
|
||||
"content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.8.2 <0.9.0;\ncontract Storage {\n uint256 number;\n function store(uint256 num) public { number = num; }\n function retrieve() public view returns (uint256){ return number; }\n}"
|
||||
}
|
||||
"language": "Solidity",
|
||||
"sources": {
|
||||
"fixtures/storage.sol": {
|
||||
"content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.8.2 <0.9.0;\ncontract Storage {\n uint256 number;\n function store(uint256 num) public { number = num; }\n function retrieve() public view returns (uint256){ return number; }\n}"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"optimizer": {
|
||||
"enabled": true,
|
||||
"runs": 200
|
||||
},
|
||||
"settings": {
|
||||
"optimizer": {
|
||||
"enabled": true,
|
||||
"runs": 200
|
||||
},
|
||||
"outputSelection": {
|
||||
"*": {
|
||||
"*": [
|
||||
"abi"
|
||||
]
|
||||
}
|
||||
"outputSelection": {
|
||||
"*": {
|
||||
"*": ["abi"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+74
-77
File diff suppressed because one or more lines are too long
+7
-4
@@ -5,17 +5,20 @@
|
||||
"solc": "^0.8.28"
|
||||
},
|
||||
"scripts": {
|
||||
"fetch:soljson": "wget https://binaries.soliditylang.org/wasm/soljson-v0.8.28+commit.7893614a.js -O ./examples/web/soljson.js",
|
||||
"example:web": "npm run fetch:soljson && http-server ./examples/web/",
|
||||
"example:web": "http-server ./examples/web/",
|
||||
"example:node": "node ./examples/node/run_revive.js",
|
||||
"test:node": "mocha --timeout 60000 ./tests",
|
||||
"test:bun": "bun test --timeout 60000 node.test",
|
||||
"test:all": "npm run test:node && npm run test:bun"
|
||||
"test:all": "npm run test:node && npm run test:bun",
|
||||
"format": "prettier --write .",
|
||||
"build:package": "node ./build.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.49.1",
|
||||
"chai": "^5.1.2",
|
||||
"http-server": "^14.1.1",
|
||||
"mocha": "^11.0.1"
|
||||
"mocha": "^11.0.1",
|
||||
"prettier": "^3.4.2",
|
||||
"terser": "^5.37.0"
|
||||
}
|
||||
}
|
||||
|
||||
+14
-15
@@ -1,10 +1,10 @@
|
||||
const { defineConfig, devices } = require('@playwright/test');
|
||||
const { defineConfig, devices } = require("@playwright/test");
|
||||
|
||||
/**
|
||||
* @see https://playwright.dev/docs/test-configuration
|
||||
*/
|
||||
module.exports = defineConfig({
|
||||
testDir: './e2e',
|
||||
testDir: "./e2e",
|
||||
/* Run tests in files in parallel */
|
||||
fullyParallel: true,
|
||||
/* Fail the build on CI if you accidentally left test.only in the source code. */
|
||||
@@ -14,39 +14,38 @@ module.exports = defineConfig({
|
||||
/* Opt out of parallel tests on CI. */
|
||||
workers: process.env.CI ? 1 : undefined,
|
||||
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
||||
reporter: 'list',
|
||||
reporter: "list",
|
||||
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
||||
use: {
|
||||
/* Base URL to use in actions like `await page.goto('/')`. */
|
||||
baseURL: 'http://127.0.0.1:8080',
|
||||
baseURL: "http://127.0.0.1:8080",
|
||||
|
||||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||
trace: 'on-first-retry',
|
||||
trace: "on-first-retry",
|
||||
},
|
||||
timeout: 480000,
|
||||
/* Configure projects for major browsers */
|
||||
projects: [
|
||||
{
|
||||
name: 'chromium',
|
||||
use: { ...devices['Desktop Chrome'] },
|
||||
name: "chromium",
|
||||
use: { ...devices["Desktop Chrome"] },
|
||||
},
|
||||
|
||||
{
|
||||
name: 'firefox',
|
||||
use: { ...devices['Desktop Firefox'] },
|
||||
name: "firefox",
|
||||
use: { ...devices["Desktop Firefox"] },
|
||||
},
|
||||
|
||||
{
|
||||
name: 'webkit',
|
||||
use: { ...devices['Desktop Safari'] },
|
||||
}
|
||||
name: "webkit",
|
||||
use: { ...devices["Desktop Safari"] },
|
||||
},
|
||||
],
|
||||
|
||||
/* Run your local dev server before starting the tests */
|
||||
webServer: {
|
||||
command: 'npm run example:web',
|
||||
url: 'http://127.0.0.1:8080',
|
||||
command: "npm run example:web",
|
||||
url: "http://127.0.0.1:8080",
|
||||
reuseExistingServer: !process.env.CI,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
+53
-35
@@ -1,45 +1,61 @@
|
||||
import { expect } from 'chai';
|
||||
import { compile } from '../examples/node/revive.js';
|
||||
import { fileURLToPath } from 'url';
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import { expect } from "chai";
|
||||
import { compile } from "../examples/node/revive.js";
|
||||
import { fileURLToPath } from "url";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
function loadFixture(fixture) {
|
||||
const fixturePath = path.resolve(__dirname, `../fixtures/${fixture}`);
|
||||
return JSON.parse(fs.readFileSync(fixturePath, 'utf-8'));
|
||||
return JSON.parse(fs.readFileSync(fixturePath, "utf-8"));
|
||||
}
|
||||
|
||||
describe('Compile Function Tests', function () {
|
||||
it('should successfully compile valid Solidity code', async function () {
|
||||
const standardInput = loadFixture('storage.json')
|
||||
describe("Compile Function Tests", function () {
|
||||
it("should successfully compile valid Solidity code", async function () {
|
||||
const standardInput = loadFixture("storage.json");
|
||||
|
||||
const result = await compile(standardInput);
|
||||
expect(result).to.be.a('string');
|
||||
expect(result).to.be.a("string");
|
||||
const output = JSON.parse(result);
|
||||
expect(output).to.have.property('contracts');
|
||||
expect(output.contracts['fixtures/storage.sol']).to.have.property('Storage');
|
||||
expect(output.contracts['fixtures/storage.sol'].Storage).to.have.property('abi');
|
||||
expect(output.contracts['fixtures/storage.sol'].Storage).to.have.property('evm');
|
||||
expect(output.contracts['fixtures/storage.sol'].Storage.evm).to.have.property('bytecode');
|
||||
expect(output).to.have.property("contracts");
|
||||
expect(output.contracts["fixtures/storage.sol"]).to.have.property(
|
||||
"Storage",
|
||||
);
|
||||
expect(output.contracts["fixtures/storage.sol"].Storage).to.have.property(
|
||||
"abi",
|
||||
);
|
||||
expect(output.contracts["fixtures/storage.sol"].Storage).to.have.property(
|
||||
"evm",
|
||||
);
|
||||
expect(
|
||||
output.contracts["fixtures/storage.sol"].Storage.evm,
|
||||
).to.have.property("bytecode");
|
||||
});
|
||||
|
||||
if (typeof globalThis.Bun == 'undefined') {
|
||||
if (typeof globalThis.Bun == "undefined") {
|
||||
// Running this test with Bun on a Linux host causes:
|
||||
// RuntimeError: Out of bounds memory access (evaluating 'getWasmTableEntry(index)(a1, a2, a3, a4, a5)')
|
||||
// Once this issue is resolved, the test will be re-enabled.
|
||||
it('should successfully compile large Solidity code', async function () {
|
||||
const standardInput = loadFixture('token.json')
|
||||
it("should successfully compile large Solidity code", async function () {
|
||||
const standardInput = loadFixture("token.json");
|
||||
|
||||
const result = await compile(standardInput);
|
||||
expect(result).to.be.a('string');
|
||||
expect(result).to.be.a("string");
|
||||
const output = JSON.parse(result);
|
||||
expect(output).to.have.property('contracts');
|
||||
expect(output.contracts['fixtures/token.sol']).to.have.property('MyToken');
|
||||
expect(output.contracts['fixtures/token.sol'].MyToken).to.have.property('abi');
|
||||
expect(output.contracts['fixtures/token.sol'].MyToken).to.have.property('evm');
|
||||
expect(output.contracts['fixtures/token.sol'].MyToken.evm).to.have.property('bytecode');
|
||||
expect(output).to.have.property("contracts");
|
||||
expect(output.contracts["fixtures/token.sol"]).to.have.property(
|
||||
"MyToken",
|
||||
);
|
||||
expect(output.contracts["fixtures/token.sol"].MyToken).to.have.property(
|
||||
"abi",
|
||||
);
|
||||
expect(output.contracts["fixtures/token.sol"].MyToken).to.have.property(
|
||||
"evm",
|
||||
);
|
||||
expect(
|
||||
output.contracts["fixtures/token.sol"].MyToken.evm,
|
||||
).to.have.property("bytecode");
|
||||
});
|
||||
|
||||
it("should successfully compile a valid Solidity contract that instantiates the token contracts", async function () {
|
||||
@@ -64,29 +80,31 @@ describe('Compile Function Tests', function () {
|
||||
});
|
||||
}
|
||||
|
||||
it('should throw an error for invalid Solidity code', async function () {
|
||||
const standardInput = loadFixture('invalid_contract_content.json')
|
||||
it("should throw an error for invalid Solidity code", async function () {
|
||||
const standardInput = loadFixture("invalid_contract_content.json");
|
||||
|
||||
const result = await compile(standardInput);
|
||||
expect(result).to.be.a('string');
|
||||
expect(result).to.be.a("string");
|
||||
const output = JSON.parse(result);
|
||||
expect(output).to.have.property('errors');
|
||||
expect(output.errors).to.be.an('array');
|
||||
expect(output).to.have.property("errors");
|
||||
expect(output.errors).to.be.an("array");
|
||||
expect(output.errors.length).to.be.greaterThan(0);
|
||||
expect(output.errors[0].type).to.exist;
|
||||
expect(output.errors[0].type).to.contain("ParserError");
|
||||
});
|
||||
|
||||
it('should return not found error for missing imports', async function () {
|
||||
const standardInput = loadFixture('missing_import.json')
|
||||
it("should return not found error for missing imports", async function () {
|
||||
const standardInput = loadFixture("missing_import.json");
|
||||
|
||||
const result = await compile(standardInput);
|
||||
const result = await compile(standardInput);
|
||||
const output = JSON.parse(result);
|
||||
expect(output).to.have.property('errors');
|
||||
expect(output.errors).to.be.an('array');
|
||||
expect(output).to.have.property("errors");
|
||||
expect(output.errors).to.be.an("array");
|
||||
expect(output.errors.length).to.be.greaterThan(0);
|
||||
expect(output.errors[0].message).to.exist;
|
||||
expect(output.errors[0].message).to.include('Source "nonexistent/console.sol" not found');
|
||||
expect(output.errors[0].message).to.include(
|
||||
'Source "nonexistent/console.sol" not found',
|
||||
);
|
||||
});
|
||||
|
||||
it("should successfully compile a valid Solidity contract that instantiates another contract", async function () {
|
||||
|
||||
+2
-1
@@ -3,7 +3,8 @@
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"test:cli": "npm run test -w crates/solidity/src/tests/cli-tests",
|
||||
"test:wasm": "npm run test:all -w js"
|
||||
"test:wasm": "npm run test:all -w js",
|
||||
"build:package": "npm run build:package -w js"
|
||||
},
|
||||
"workspaces": [
|
||||
"crates/solidity/src/tests/cli-tests",
|
||||
|
||||
Reference in New Issue
Block a user