From 9e51c128bff26ffe294333c112b82e7c258ef831 Mon Sep 17 00:00:00 2001 From: jrburke Date: Tue, 12 Jun 2012 19:25:28 -0700 Subject: [PATCH] Fixes #195, option to use sourceURL in built files. --- build/example.build.js | 14 +++++- build/jslib/build.js | 2 +- build/jslib/transform.js | 94 +++------------------------------------- build/tests/all.js | 7 ++- build/tests/transform.js | 24 ---------- 5 files changed, 22 insertions(+), 119 deletions(-) delete mode 100644 build/tests/transform.js diff --git a/build/example.build.js b/build/example.build.js index a63e9740..c451930a 100644 --- a/build/example.build.js +++ b/build/example.build.js @@ -421,6 +421,16 @@ //path lookups. cjsTranslate: true, - //useSourceUrl, optimize: none is best, since otherwise do not get benefit - //of minification. Only define() calls. + //Introduced in 2.0.2: a bit experimental. + //Each script in the build layer will be turned into + //a JavaScript string with a //@ sourceURL comment, and then wrapped in an + //eval call. This allows some browsers to see each evaled script as a + //separate script in the script debugger even though they are all combined + //in the same file. Some important limitations: + //1) Do not use in IE if conditional comments are turned on, it will cause + //errors: + //http://en.wikipedia.org/wiki/Conditional_comment#Conditional_comments_in_JScript + //2) It is only useful in optimize: 'none' scenarios. The goal is to allow + //easier built layer debugging, which goes against minification desires. + useSourceUrl: true }) diff --git a/build/jslib/build.js b/build/jslib/build.js index f566e38f..c93517c3 100644 --- a/build/jslib/build.js +++ b/build/jslib/build.js @@ -1227,7 +1227,7 @@ function (lang, logger, file, parse, optimize, pragma, } currContents = build.toTransport(namespace, moduleName, path, currContents, layer, { - useSourceUrl: layer.context.config.useSourceUrl + useSourceUrl: config.useSourceUrl }); if (packageConfig) { diff --git a/build/jslib/transform.js b/build/jslib/transform.js index 2e181b16..08641a11 100644 --- a/build/jslib/transform.js +++ b/build/jslib/transform.js @@ -19,9 +19,7 @@ function (esprima, parse, logger, lang) { var defineRanges = [], contentInsertion = '', depString = '', - useSourceUrl = options.useSourceUrl, - tokens, info, deps, urlData, - functionContent, functionBody; + tokens, info, deps; try { tokens = esprima.parse(contents, { @@ -83,10 +81,6 @@ function (esprima, parse, logger, lang) { //Dependency array needsId = true; depAction = 'skip'; - - if (useSourceUrl) { - sourceUrlData = transform.getSourceUrlData(tokens, i + 2); - } } else if (next2.type === 'Punctuator' && next2.value === '{') { //Object literal @@ -97,10 +91,6 @@ function (esprima, parse, logger, lang) { //function needsId = true; depAction = 'scan'; - - if (useSourceUrl) { - sourceUrlData = transform.getSourceUrlData(tokens, i + 2); - } } else if (next2.type === 'String') { //Named module needsId = false; @@ -126,12 +116,6 @@ function (esprima, parse, logger, lang) { next4.value === 'function') { depAction = 'scan'; nameCommaRange = next3.range; - - if (next4.type === 'Keyword' && - next4.value === 'function' - && useSourceUrl) { - sourceUrlData = transform.getSourceUrlData(tokens, i + 4); - } } else { depAction = 'skip'; } @@ -211,29 +195,11 @@ function (esprima, parse, logger, lang) { } info = defineRanges[0]; - urlData = info.sourceUrlData; //Do the modifications "backwards", in other words, start with the //one that is farthest down and work up, so that the ranges in the //defineRanges still apply. So that means deps, id, then namespace. - if (useSourceUrl && urlData) { - //First, convert the function to a Function string, if - //useSourceUrl is in play. - functionBody = lang.jsEscape(contents.substring(urlData.bodyStart[1], urlData.bodyEnd[0]) + - '\r\n//@ sourceURL=' + (path.indexOf('/') === 0 ? '' : '/') + path); - - functionContent = 'Function([' + - (urlData.args.length ? '"' + urlData.args.join('","') + '"' : '') + - '], "' + functionBody + '")'; - - contents = contents.substring(0, urlData.functionStart[0]) + - functionContent + - contents.substring(urlData.bodyEnd[1], - contents.length); - } - - if (info.needsId && moduleName) { contentInsertion += "'" + moduleName + "',"; } @@ -286,61 +252,13 @@ function (esprima, parse, logger, lang) { onFound(info); } - return contents; - }, - - getSourceUrlData: function (tokens, i) { - var data = {}, - foundIt = false, - curlyCount = 1, - //This strange line for jslint - init = i, - token; - - for (i = init; i < tokens.length && !foundIt; i += 1) { - token = tokens[i]; - - //Look for starting function if it was not already found. - if (!data.args && token.type === 'Keyword' && token.value === 'function') { - data.functionStart = token.range; - - //Bingo. Now start finding the args. - data.args = []; - for (i += 1; i < tokens.length; i += 1) { - token = tokens[i]; - if (token.type === 'Punctuator' && token.value === ')') { - //Found the end of the args - break; - } - - if (token.type === 'Identifier') { - data.args.push(token.value); - } - } - } - - if (data.args && token.type === 'Punctuator' && token.value === '{') { - //Found the start position - data.bodyStart = token.range; - for (i += 1; i < tokens.length; i += 1) { - token = tokens[i]; - if (token.type === 'Punctuator') { - if (token.value === '{') { - curlyCount += 1; - } else if (token.value === '}') { - curlyCount -= 1; - if (curlyCount === 0) { - data.bodyEnd = token.range; - foundIt = true; - break; - } - } - } - } - } + if (options.useSourceUrl) { + contents = 'eval("' + lang.jsEscape(contents) + + '\\n//@ sourceURL=' + (path.indexOf('/') === 0 ? '' : '/') + path + + '");\n'; } - return foundIt ? data : undefined; + return contents; } }); }); \ No newline at end of file diff --git a/build/tests/all.js b/build/tests/all.js index a9e80c7f..9f193bc3 100644 --- a/build/tests/all.js +++ b/build/tests/all.js @@ -32,14 +32,13 @@ require({ }, [ '../../tests/doh/runner.js', 'env!../../tests/doh/_{env}Runner.js', - /*'tests/convert', - 'tests/parse', */ - 'tests/transform'/*, + 'tests/convert', + 'tests/parse', 'tests/buildUtils', //Build tests should be last in case they alter the environment //in a weird way. - 'tests/builds' */ + 'tests/builds' ]); //Show final report. Do this outside the require call, not diff --git a/build/tests/transform.js b/build/tests/transform.js deleted file mode 100644 index bcef83a3..00000000 --- a/build/tests/transform.js +++ /dev/null @@ -1,24 +0,0 @@ -/*jslint */ -/*global doh: false, define: false */ - -define(['transform'], function (transform) { - 'use strict'; - doh.register( - "transformTests", - [ - function transformTests(t) { - var source1 = 'define(["a", "b"], function(a, b) {\nreturn a + "hello" + b;\n});', - expected1 = 'define(\'source1\',["a", "b"], Function(["a","b"], "\\nreturn a + \\"hello\\" + b;\\n\\r\\n//@ sourceURL=/source1.js"));'; - - -//test no args function -//test object literal define. - - t.is(expected1, transform.toTransport(null, 'source1', 'source1.js', source1, null, { - useSourceUrl: true - })); - } - ] - ); - doh.run(); -});