Use the compiler callback method for resolving imports if available.

pull/1/head
chriseth 9 years ago
parent e04e22cbc8
commit 3e83423915
  1. 107
      index.html
  2. 35
      index.js
  3. 16
      worker.js

@ -512,7 +512,7 @@
var previousInput = '';
var sourceAnnotations = [];
var compile = function() {
var compile = function(missingInputs) {
editor.getSession().clearAnnotations();
sourceAnnotations = [];
editor.getSession().removeMarker(errMarkerId);
@ -522,13 +522,17 @@
var files = {};
files[fileNameFromKey(SOL_CACHE_FILE)] = input;
var input = gatherImports(files, compile);
if (!input) return;
var optimize = document.querySelector('#optimize').checked;
compileJSON(input, optimize ? 1 : 0);
gatherImports(files, missingInputs, function(input, error) {
$('#output').empty();
if (input === null) {
renderError(error);
} else {
var optimize = document.querySelector('#optimize').checked;
compileJSON(input, optimize ? 1 : 0);
}
});
};
var compilationFinished = function(result) {
var compilationFinished = function(result, missingInputs) {
var data = $.parseJSON(result);
var noFatalErrors = true; // ie warnings are ok
@ -543,7 +547,10 @@
});
}
if (noFatalErrors && !hidingRHP) renderContracts(data, editor.getValue());
if (missingInputs !== undefined && missingInputs.length > 0)
compile(missingInputs);
else if (noFatalErrors && !hidingRHP)
renderContracts(data, editor.getValue());
};
var compileTimeout = null;
@ -563,7 +570,18 @@
var onCompilerLoaded = function() {
if (worker === null) {
var compile;
if ('_compileJSONMulti' in Module) {
var missingInputs = [];
if ('_compileJSONCallback' in Module) {
compilerAcceptsMultipleFiles = true;
var missingInputsCallback = Module.Runtime.addFunction(function(path, contents, error) {
missingInputs.push(Module.Pointer_stringify(path));
});
var compileInternal = Module.cwrap("compileJSONCallback", "string", ["string", "number", "number"]);
compile = function(input, optimize) {
missingInputs.length = 0;
return compileInternal(input, optimize, missingInputsCallback);
};
} else if ('_compileJSONMulti' in Module) {
compilerAcceptsMultipleFiles = true;
compile = Module.cwrap("compileJSONMulti", "string", ["string", "number"]);
} else {
@ -576,7 +594,7 @@
} catch (exception) {
result = JSON.stringify({error: 'Uncaught JavaScript exception:\n' + exception});
}
compilationFinished(result);
compilationFinished(result, missingInputs);
};
$('#version').text(Module.cwrap("version", "string", [])());
}
@ -585,49 +603,54 @@
};
var cachedRemoteFiles = {};
function gatherImports(files, asyncCallback, needAsync) {
function gatherImports(files, importHints, cb) {
importHints = importHints || [];
if (!compilerAcceptsMultipleFiles)
return files[fileNameFromKey(SOL_CACHE_FILE)];
{
cb(files[fileNameFromKey(SOL_CACHE_FILE)]);
return;
}
var importRegex = /import\s[\'\"]([^\'\"]+)[\'\"];/g;
var reloop = false;
do {
reloop = false;
for (var fileName in files) {
var match;
while (match = importRegex.exec(files[fileName])) {
var m = match[1];
if (m in files) continue;
if (getFiles().indexOf(fileKey(m)) !== -1) {
files[m] = window.localStorage[fileKey(match[1])];
reloop = true;
} else if (m in cachedRemoteFiles) {
files[m] = cachedRemoteFiles[m];
reloop = true;
} else if (githubMatch = /^(https?:\/\/)?(www.)?github.com\/([^\/]*\/[^\/]*)\/(.*)/.exec(m)) {
$.getJSON('https://api.github.com/repos/' + githubMatch[3] + '/contents/' + githubMatch[4], function(result) {
var content;
if ('content' in result)
content = Base64.decode(result.content);
else
content = "\"" + m + "\" NOT FOUND"; //@TODO handle this better
cachedRemoteFiles[m] = content;
files[m] = content;
gatherImports(files, asyncCallback, true);
}).fail(function(){
var content = "\"" + m + "\" NOT FOUND"; //@TODO handle this better
while (match = importRegex.exec(files[fileName]))
importHints.push(match[1]);
}
while (importHints.length > 0) {
var m = importHints.pop();
if (m in files) continue;
if (getFiles().indexOf(fileKey(m)) !== -1) {
files[m] = window.localStorage[fileKey(m)];
reloop = true;
} else if (m in cachedRemoteFiles) {
files[m] = cachedRemoteFiles[m];
reloop = true;
} else if (githubMatch = /^(https?:\/\/)?(www.)?github.com\/([^\/]*\/[^\/]*)\/(.*)/.exec(m)) {
$('#output').append($('<div/>').append($('<pre/>').text("Loading github.com/" + githubMatch[3] + " ...")));
$.getJSON('https://api.github.com/repos/' + githubMatch[3] + '/contents/' + githubMatch[4], function(result) {
if ('content' in result)
{
var content = Base64.decode(result.content);
cachedRemoteFiles[m] = content;
files[m] = content;
gatherImports(files, asyncCallback, true);
});
return null;
}
gatherImports(files, importHints, cb);
}
else
cb(null, "Unable to import \"" + m + "\"");
}).fail(function(){
cb(null, "Unable to import \"" + m + "\"");
});
return;
} else {
cb(null, "Unable to import \"" + m + "\"");
return;
}
}
} while (reloop);
var input = JSON.stringify({'sources':files});
if (needAsync)
asyncCallback(input);
return input;
cb(JSON.stringify({'sources':files}));
}
var initializeWorker = function() {
@ -643,7 +666,7 @@
onCompilerLoaded();
break;
case 'compiled':
compilationFinished(data.data);
compilationFinished(data.data, data.missingInputs);
break;
};
});

@ -5,9 +5,42 @@ function setupMethods (soljson){
'_compileJSONMulti' in soljson ?
soljson.cwrap("compileJSONMulti", "string", ["string", "number"]) :
null;
var compileJSONCallback = null;
if ('_compileJSONCallback' in soljson)
{
/// TODO: Allocating memory and copying the strings over
/// to the emscripten runtime does not seem to work.
var copyString = function(str, ptr) {
var buffer = soljson._malloc(str.length + 1);
soljson.writeStringToMemory(str, buffer);
soljson.setValue(ptr, buffer, '*');
};
var wrapCallback = function(callback) {
return soljson.Runtime.addFunction(function(path, contents, error) {
// path is char*, contents is char**, error is char**
// TODO copying the results does not seem to work.
// This is not too bad, because most of the requests
// cannot be answered synchronously anyway.
var result = callback(soljson.Pointer_stringify(path));
if (typeof(result.contents) === typeof(''))
copyString(result.contents, contents);
if (typeof(result.error) === typeof(''))
copyString(result.error, error);
});
};
var compileInternal = soljson.cwrap("compileJSONCallback", "string", ["string", "number", "number"]);
compileJSONCallback = function(input, optimize, readCallback) {
var cb = wrapCallback(readCallback);
var output = compileInternal(input, optimize, cb);
soljson.Runtime.removeFunction(cb);
return output;
};
}
var compile = function(input, optimise) {
var compile = function(input, optimise, readCallback) {
var result = '';
if (readCallback !== undefined && compileJSONCallback !== null)
result = compileJSONCallback(JSON.stringify(input), optimise, readCallback);
if (typeof(input) != typeof('') && compileJSONMulti !== null)
result = compileJSONMulti(JSON.stringify(input), optimise);
else

@ -2,6 +2,7 @@ var version = function() { return '(loading)'; }
var compileJSON = function() { return ''; }
addEventListener('message', function(e) {
var data = e.data;
var missingInputs = [];
switch (data.cmd) {
case 'loadVersion':
delete Module;
@ -10,7 +11,17 @@ addEventListener('message', function(e) {
importScripts(data.data);
version = Module.cwrap("version", "string", []);
if ('_compileJSONMulti' in Module)
if ('_compileJSONCallback' in Module)
{
compileJSONInternal = Module.cwrap("compileJSONCallback", "string", ["string", "number", "number"]);
var missingInputCallback = Module.Runtime.addFunction(function(path) {
missingInputs.push(Module.Pointer_stringify(path));
});
compileJSON = function(input, optimize) {
return compileJSONInternal(input, optimize, missingInputCallback);
};
}
else if ('_compileJSONMulti' in Module)
compileJSON = Module.cwrap("compileJSONMulti", "string", ["string", "number"]);
else
compileJSON = Module.cwrap("compileJSON", "string", ["string", "number"]);
@ -21,7 +32,8 @@ addEventListener('message', function(e) {
});
break;
case 'compile':
postMessage({cmd: 'compiled', data: compileJSON(data.source, data.optimize)});
missingInputs
postMessage({cmd: 'compiled', data: compileJSON(data.source, data.optimize)}, missingInputs: missingInputs);
break;
}
}, false);

Loading…
Cancel
Save