[Pkg-javascript-commits] [less.js] 54/285: move some dependencies out of chunker. make chunker optional. start fixing error messages chunker handled

Jonas Smedegaard dr at jones.dk
Mon Oct 26 23:23:37 UTC 2015


This is an automated email from the git hooks/post-receive script.

js pushed a commit to annotated tag v2.0.0
in repository less.js.

commit 94f746b5e754b88ced6605781c94c7acb4d22e20
Author: Luke Page <luke.a.page at gmail.com>
Date:   Thu Jun 19 18:23:19 2014 +0100

    move some dependencies out of chunker. make chunker optional. start fixing error messages chunker handled
---
 lib/less/chunker.js                              | 77 ++++++++++--------------
 lib/less/env.js                                  |  1 +
 lib/less/parser.js                               | 43 ++++++++++---
 test/less/errors/import-subfolder2.txt           |  2 +-
 test/less/errors/parse-error-curly-bracket.txt   |  2 +-
 test/less/errors/parse-error-extra-parens.txt    |  2 +-
 test/less/errors/parse-error-missing-bracket.txt |  2 +-
 test/less/errors/parse-error-missing-parens.txt  |  2 +-
 8 files changed, 75 insertions(+), 56 deletions(-)

diff --git a/lib/less/chunker.js b/lib/less/chunker.js
index 0d13882..a5ccaa9 100644
--- a/lib/less/chunker.js
+++ b/lib/less/chunker.js
@@ -1,32 +1,21 @@
-var LessError = require('./less-error.js');
-
 // Split the input into chunks.
-module.exports = function (parser, input, env) {
+module.exports = function (input, fail) {
     var len = input.length, level = 0, parenLevel = 0,
         lastOpening, lastOpeningParen, lastMultiComment, lastMultiCommentEndBrace,
         chunks = [], emitFrom = 0,
-        parserCurrentIndex, currentChunkStartIndex, cc, cc2, matched;
-
-    function fail(msg, index) {
-        throw new(LessError)(parser, {
-            index: index || parserCurrentIndex,
-            type: 'Parse',
-            message: msg,
-            filename: env.currentFileInfo.filename
-        }, env);
-    }
+        chunkerCurrentIndex, currentChunkStartIndex, cc, cc2, matched;
 
     function emitChunk(force) {
-        var len = parserCurrentIndex - emitFrom;
+        var len = chunkerCurrentIndex - emitFrom;
         if (((len < 512) && !force) || !len) {
             return;
         }
-        chunks.push(input.slice(emitFrom, parserCurrentIndex + 1));
-        emitFrom = parserCurrentIndex + 1;
+        chunks.push(input.slice(emitFrom, chunkerCurrentIndex + 1));
+        emitFrom = chunkerCurrentIndex + 1;
     }
 
-    for (parserCurrentIndex = 0; parserCurrentIndex < len; parserCurrentIndex++) {
-        cc = input.charCodeAt(parserCurrentIndex);
+    for (chunkerCurrentIndex = 0; chunkerCurrentIndex < len; chunkerCurrentIndex++) {
+        cc = input.charCodeAt(chunkerCurrentIndex);
         if (((cc >= 97) && (cc <= 122)) || (cc < 34)) {
             // a-z or whitespace
             continue;
@@ -35,11 +24,11 @@ module.exports = function (parser, input, env) {
         switch (cc) {
             case 40:                        // (
                 parenLevel++;
-                lastOpeningParen = parserCurrentIndex;
+                lastOpeningParen = chunkerCurrentIndex;
                 continue;
             case 41:                        // )
                 if (--parenLevel < 0) {
-                    return fail("missing opening `(`");
+                    return fail("missing opening `(`", chunkerCurrentIndex);
                 }
                 continue;
             case 59:                        // ;
@@ -47,62 +36,62 @@ module.exports = function (parser, input, env) {
                 continue;
             case 123:                       // {
                 level++;
-                lastOpening = parserCurrentIndex;
+                lastOpening = chunkerCurrentIndex;
                 continue;
             case 125:                       // }
                 if (--level < 0) {
-                    return fail("missing opening `{`");
+                    return fail("missing opening `{`", chunkerCurrentIndex);
                 }
                 if (!level && !parenLevel) { emitChunk(); }
                 continue;
             case 92:                        // \
-                if (parserCurrentIndex < len - 1) { parserCurrentIndex++; continue; }
-                return fail("unescaped `\\`");
+                if (chunkerCurrentIndex < len - 1) { chunkerCurrentIndex++; continue; }
+                return fail("unescaped `\\`", chunkerCurrentIndex);
             case 34:
             case 39:
             case 96:                        // ", ' and `
                 matched = 0;
-                currentChunkStartIndex = parserCurrentIndex;
-                for (parserCurrentIndex = parserCurrentIndex + 1; parserCurrentIndex < len; parserCurrentIndex++) {
-                    cc2 = input.charCodeAt(parserCurrentIndex);
+                currentChunkStartIndex = chunkerCurrentIndex;
+                for (chunkerCurrentIndex = chunkerCurrentIndex + 1; chunkerCurrentIndex < len; chunkerCurrentIndex++) {
+                    cc2 = input.charCodeAt(chunkerCurrentIndex);
                     if (cc2 > 96) { continue; }
                     if (cc2 == cc) { matched = 1; break; }
                     if (cc2 == 92) {        // \
-                        if (parserCurrentIndex == len - 1) {
-                            return fail("unescaped `\\`");
+                        if (chunkerCurrentIndex == len - 1) {
+                            return fail("unescaped `\\`", chunkerCurrentIndex);
                         }
-                        parserCurrentIndex++;
+                        chunkerCurrentIndex++;
                     }
                 }
                 if (matched) { continue; }
                 return fail("unmatched `" + String.fromCharCode(cc) + "`", currentChunkStartIndex);
             case 47:                        // /, check for comment
-                if (parenLevel || (parserCurrentIndex == len - 1)) { continue; }
-                cc2 = input.charCodeAt(parserCurrentIndex + 1);
+                if (parenLevel || (chunkerCurrentIndex == len - 1)) { continue; }
+                cc2 = input.charCodeAt(chunkerCurrentIndex + 1);
                 if (cc2 == 47) {
                     // //, find lnfeed
-                    for (parserCurrentIndex = parserCurrentIndex + 2; parserCurrentIndex < len; parserCurrentIndex++) {
-                        cc2 = input.charCodeAt(parserCurrentIndex);
+                    for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len; chunkerCurrentIndex++) {
+                        cc2 = input.charCodeAt(chunkerCurrentIndex);
                         if ((cc2 <= 13) && ((cc2 == 10) || (cc2 == 13))) { break; }
                     }
                 } else if (cc2 == 42) {
                     // /*, find */
-                    lastMultiComment = currentChunkStartIndex = parserCurrentIndex;
-                    for (parserCurrentIndex = parserCurrentIndex + 2; parserCurrentIndex < len - 1; parserCurrentIndex++) {
-                        cc2 = input.charCodeAt(parserCurrentIndex);
-                        if (cc2 == 125) { lastMultiCommentEndBrace = parserCurrentIndex; }
+                    lastMultiComment = currentChunkStartIndex = chunkerCurrentIndex;
+                    for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len - 1; chunkerCurrentIndex++) {
+                        cc2 = input.charCodeAt(chunkerCurrentIndex);
+                        if (cc2 == 125) { lastMultiCommentEndBrace = chunkerCurrentIndex; }
                         if (cc2 != 42) { continue; }
-                        if (input.charCodeAt(parserCurrentIndex + 1) == 47) { break; }
+                        if (input.charCodeAt(chunkerCurrentIndex + 1) == 47) { break; }
                     }
-                    if (parserCurrentIndex == len - 1) {
+                    if (chunkerCurrentIndex == len - 1) {
                         return fail("missing closing `*/`", currentChunkStartIndex);
                     }
-                    parserCurrentIndex++;
+                    chunkerCurrentIndex++;
                 }
                 continue;
             case 42:                       // *, check for unmatched */
-                if ((parserCurrentIndex < len - 1) && (input.charCodeAt(parserCurrentIndex + 1) == 47)) {
-                    return fail("unmatched `/*`");
+                if ((chunkerCurrentIndex < len - 1) && (input.charCodeAt(chunkerCurrentIndex + 1) == 47)) {
+                    return fail("unmatched `/*`", chunkerCurrentIndex);
                 }
                 continue;
         }
@@ -120,4 +109,4 @@ module.exports = function (parser, input, env) {
 
     emitChunk(true);
     return chunks;
-};
\ No newline at end of file
+};
diff --git a/lib/less/env.js b/lib/less/env.js
index 8019294..8e964a7 100644
--- a/lib/less/env.js
+++ b/lib/less/env.js
@@ -14,6 +14,7 @@ module.exports = function (tree) {
         'processImports',   // option - whether to process imports. if false then imports will not be imported
         'syncImport',       // option - whether to import synchronously
         'javascriptEnabled',// option - whether JavaScript is enabled. if undefined, defaults to true
+        'chunkInput',       // option - whether to chunk input. more performant but causes parse issues.
         'mime',             // browser only - mime type for sheet import
         'useFileCache',     // browser only - whether to use the per file session cache
         'currentFileInfo'   // information about the current file - for error reporting and importing and making urls relative etc.
diff --git a/lib/less/parser.js b/lib/less/parser.js
index 22e4a9c..7341edd 100644
--- a/lib/less/parser.js
+++ b/lib/less/parser.js
@@ -355,10 +355,30 @@ var Parser = function Parser(env) {
             input = str = preText + str.replace(/^\uFEFF/, '') + modifyVars;
             parser.imports.contents[env.currentFileInfo.filename] = str;
 
-            try {
-                chunks = chunker(parser, str, env);
-            } catch (ex) {
-                return callback(new LessError(parser, ex, env));
+            // chunking makes things quicker
+            // but it is a non-perfect parse - it can't recognise
+            // unquoted urls, meaning it can't distinguish comments
+            // meaning comments with quotes or {}() in them get 'counted'
+            // and then lead to parse errors.
+            // In addition if the chunking chunks in the wrong place we might
+            // not be able to parse a parser statement in one go
+            // this is officially deprecated but can be switched on via an option
+            // in the case it causes too much performance issues.
+            if (env.chunkInput) {
+                try {
+                    chunks = chunker(str, function fail(msg, index) {
+                        throw new(LessError)(parser, {
+                            index: index,
+                            type: 'Parse',
+                            message: msg,
+                            filename: env.currentFileInfo.filename
+                        }, env);
+                    });
+                } catch (ex) {
+                    return callback(new LessError(parser, ex, env));
+                }
+            } else {
+                chunks = [str];
             }
 
             current = chunks[0];
@@ -499,14 +519,23 @@ var Parser = function Parser(env) {
             // We split it up into two parts (the part which parsed,
             // and the part which didn't), so we can color them differently.
             if (i < input.length - 1) {
-                i = furthest;
+                i = Math.max(i, furthest);
+
+                var message = "Unrecognised input";
+
+                if (input[i] === '}') {
+                    message = "Missing opening '{'";
+                } else if (input[i] === ')') {
+                    message = "Missing opening '('";
+                }
+
                 var loc = getLocation(i, input);
                 lines = input.split('\n');
                 line = loc.line + 1;
 
                 error = {
                     type: "Parse",
-                    message: "Unrecognised input",
+                    message: message,
                     index: i,
                     filename: env.currentFileInfo.filename,
                     line: line,
@@ -822,7 +851,7 @@ var Parser = function Parser(env) {
                         colorCandidateString = colorCandidateString[1];
                         if (!colorCandidateString.match(/^[A-Fa-f0-9]+$/)) { // verify if candidate consists only of allowed HEX characters
                             error("Invalid HEX color code");
-                        } 
+                        }
                         return new(tree.Color)(rgb[1]);
                     }
                 },
diff --git a/test/less/errors/import-subfolder2.txt b/test/less/errors/import-subfolder2.txt
index b5b1a69..bb77163 100644
--- a/test/less/errors/import-subfolder2.txt
+++ b/test/less/errors/import-subfolder2.txt
@@ -1,4 +1,4 @@
-ParseError: missing opening `{` in {path}parse-error-curly-bracket.less on line 4, column 1:
+ParseError: Missing opening '{' in {path}parse-error-curly-bracket.less on line 4, column 1:
 3   }
 4 }
 5 
diff --git a/test/less/errors/parse-error-curly-bracket.txt b/test/less/errors/parse-error-curly-bracket.txt
index b5b1a69..bb77163 100644
--- a/test/less/errors/parse-error-curly-bracket.txt
+++ b/test/less/errors/parse-error-curly-bracket.txt
@@ -1,4 +1,4 @@
-ParseError: missing opening `{` in {path}parse-error-curly-bracket.less on line 4, column 1:
+ParseError: Missing opening '{' in {path}parse-error-curly-bracket.less on line 4, column 1:
 3   }
 4 }
 5 
diff --git a/test/less/errors/parse-error-extra-parens.txt b/test/less/errors/parse-error-extra-parens.txt
index 5c1aaef..4eccf1b 100644
--- a/test/less/errors/parse-error-extra-parens.txt
+++ b/test/less/errors/parse-error-extra-parens.txt
@@ -1,3 +1,3 @@
-ParseError: missing opening `(` in {path}parse-error-extra-parens.less on line 1, column 24:
+ParseError: Missing opening '(' in {path}parse-error-extra-parens.less on line 1, column 24:
 1 @media (extra: bracket)) {
 2   body {
diff --git a/test/less/errors/parse-error-missing-bracket.txt b/test/less/errors/parse-error-missing-bracket.txt
index 7db2716..a516a0a 100644
--- a/test/less/errors/parse-error-missing-bracket.txt
+++ b/test/less/errors/parse-error-missing-bracket.txt
@@ -1,3 +1,3 @@
-ParseError: missing closing `}` in {path}parse-error-missing-bracket.less on line 1, column 6:
+ParseError: Missing closing '}' in {path}parse-error-missing-bracket.less on line 1, column 6:
 1 body {
 2   background-color: #fff;
diff --git a/test/less/errors/parse-error-missing-parens.txt b/test/less/errors/parse-error-missing-parens.txt
index a7a6706..f92da45 100644
--- a/test/less/errors/parse-error-missing-parens.txt
+++ b/test/less/errors/parse-error-missing-parens.txt
@@ -1,3 +1,3 @@
-ParseError: missing closing `)` in {path}parse-error-missing-parens.less on line 1, column 8:
+ParseError: Missing closing ')' in {path}parse-error-missing-parens.less on line 1, column 8:
 1 @media (missing: bracket {
 2   body {

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/less.js.git



More information about the Pkg-javascript-commits mailing list