source: Dev/trunk/src/client/util/checkstyle/checkstyleUtil.js @ 531

Last change on this file since 531 was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 24.1 KB
Line 
1checkstyleUtil = {
2        errors: [],
3       
4        commentNames: ["summary", "description", "example", "tags", "this"]
5};
6
7checkstyleUtil.applyRules = function(fileName, contents){
8        // Do not process JSON files
9        if(contents.charAt(0) == "{"){
10                return;
11        }
12       
13        // Mark all the characters that are in comments.
14        var comments = checkstyleUtil.getComments(contents);
15       
16        // Apply all the rules to the file
17        for(var ruleName in checkstyleUtil.rules){
18                checkstyleUtil.rules[ruleName](fileName, contents, comments);
19        }
20};
21
22// Calculate the characters in a file that are in comment fields
23// These will be ignored by the checkstyle rules.
24checkstyleUtil.getComments = function(contents){
25        var comments = [];
26       
27        var i;
28       
29        // Initialize the array to false values.
30        for(i = 0; i < contents.length; i++){
31                comments[i] = 0;
32        }
33       
34        var sep = "\n";
35       
36        function markRange(start, stop){
37                for(var i = start; i < stop; i++){
38                        comments[i] = 1;
39                }
40        }
41
42
43        function markRegexs() {
44                var idx = contents.indexOf("/g");
45                var i;
46                while(idx > -1) {
47                        if(!comments[idx] && contents.charAt(idx - 1) != "*"){
48                                // Look back until either a forward slash
49                                // or a new line is found
50                                var prevChar = contents.charAt(idx - 1);
51                                i = idx;
52                                while(prevChar != "\n" && prevChar != "/" && i > 0){
53                                        prevChar = contents.charAt(--i);
54                                }
55                                if(prevChar == "/" && i < idx - 1){
56                                        markRange(i, idx);
57                                }
58                        }
59                        idx = contents.indexOf("/g", idx + 2)
60                }
61               
62                // Now mark all .match and .replace function calls
63                // They generally contain regular expressions, and are just too bloody difficult.
64                var fnNames = ["match", "replace"];
65                var name;
66               
67                for (i = 0; i < fnNames.length; i++){
68                        name = fnNames[i];
69                       
70                        idx = contents.indexOf(name + "(");
71                       
72                        while(idx > -1){
73                                // Find the end parenthesis
74                                if(comments[idx]){
75                                        idx = contents.indexOf(name + "(", idx + name.length);
76                                } else {
77                                        var fnEnd = contents.indexOf(")", idx);
78                                        markRange(idx, fnEnd + 1);
79                                }
80                        }
81                }
82               
83                // Now look for all the lines that declare a regex variable, e.g.
84                // var begRegExp = /^,|^NOT |^AND |^OR |^\(|^\)|^!|^&&|^\|\|/i;
85               
86                idx = contents.indexOf(" = /");
87               
88                while(idx > -1){
89                        if(!comments[idx] && contents.charAt(idx + 4) != "*"){
90                                var eol = contents.indexOf("\n", idx + 1);
91                                markRange(idx + 3, Math.max(eol, idx + 4));
92                        }
93               
94                        idx = contents.indexOf(" = /", idx + 3);
95                }
96        }
97
98        markRegexs();
99       
100       
101        var marker = null;
102        var ch;
103       
104        var DOUBLE_QUOTE = 1;
105        var SINGLE_QUOTE = 2;
106        var LINE_COMMENT = 3;
107        var MULTI_COMMENT = 4;
108        var UNMARK = 5;
109       
110        var pos;
111       
112        for (i = 0; i < contents.length; i++) {
113                var skip = false;
114               
115                if(comments[i]){
116                        continue;
117                }
118               
119                ch = contents[i];
120               
121                switch(ch){
122                        case "\"":
123                                if(marker == DOUBLE_QUOTE) {
124                                        marker = UNMARK;
125                                } else if (marker == null) {
126                                        marker = DOUBLE_QUOTE;
127                                        pos = i;
128                                }
129                               
130                                break;
131                        case "'":
132                                if(marker == SINGLE_QUOTE) {
133                                        marker = UNMARK;
134                                } else if (marker == null) {
135                                        marker = SINGLE_QUOTE;
136                                        pos = i;
137                                }
138                       
139                                break;
140                        case "/":
141                                if(marker == null){
142                                        if(contents[i + 1] == "/"){
143                                                marker = LINE_COMMENT;
144                                                pos = i;
145                                                skip = true;
146                                        } else if(contents[i + 1] == "*"){
147                                                marker = MULTI_COMMENT;
148                                                pos = i;
149                                                skip = true;
150                                        }
151                                }
152                               
153                                break;
154                        case "*":
155                                if (marker == MULTI_COMMENT){
156                                        if(contents[i + 1] == "/"){
157                                                marker = UNMARK;
158                                                skip = true;
159                                        }
160                                }
161                       
162                                break;
163                        case "\n":
164                                if(marker == LINE_COMMENT){
165                                        marker = UNMARK;
166                                }
167                                break;
168               
169                }
170                if (marker != null) {
171                        comments[i] = 1;
172                }
173                if (marker == UNMARK){
174                        marker = null;
175                }
176                if  (skip) {
177                        i++;
178                        comments[i] = 1;
179                }
180        }
181       
182       
183        return comments;
184}
185
186// Calculate the line number of the character at index 'pos'
187checkstyleUtil.getLineNumber = function(contents, pos){
188        var counter = 0;
189        var sep = "\n";
190               
191        for(var i = pos; i > -1; i--){
192                if(contents.charAt(i) == "\n"){
193                        counter ++;
194                }
195        }
196        return counter + 1;
197};
198
199// Store the information for a single error.
200checkstyleUtil.addError = function(msg, fileName, contents, pos){
201        while(fileName.indexOf("../") == 0){
202                fileName = fileName.substring(3);
203        }
204        checkstyleUtil.errors.push({
205                file: fileName,
206                line: checkstyleUtil.getLineNumber(contents, pos),
207                message: msg
208        });
209};
210
211// Find the next character in 'contents' after the index 'start'
212// Spaces and tabs are ignored.
213checkstyleUtil.getNextChar = function(contents, start, comments, ignoreNewLine){
214        for(var i = start; i < contents.length; i++){
215                if(comments && comments[i]){
216                        continue;
217                }
218                if(contents.charAt(i) != " "
219                        && contents.charAt(i) != "\t"
220                        && (!ignoreNewLine || contents.charCodeAt(i) != 13)){
221                        return {
222                                value: contents[i],
223                                pos: i
224                        };
225                }
226        }
227        return null;
228};
229
230// Find the next occurrence of the character in the
231// 'contents' array after the index 'start'
232checkstyleUtil.findNextCharPos = function(contents, start, character){
233        for(var i = start; i < contents.length; i++){
234                if(contents.charAt(i) == character){
235                        return i;
236                }
237        }
238        return -1;
239};
240
241// Creates a simple function that searches for the token, and
242// adds an error if it is found
243checkstyleUtil.createSimpleSearch = function(token, message){
244        return function(fileName, contents, comments){
245                var idx = contents.indexOf(token);
246               
247                while(idx > -1){
248                       
249                        if(!comments[idx]){
250                                checkstyleUtil.addError(message, fileName, contents, idx);
251                        }
252                        idx = contents.indexOf(token, idx + 1);
253                }
254        };
255};
256
257// Creates a function that fails a test if the given token
258// does not have a space to the left and right.
259checkstyleUtil.createSpaceWrappedSearch = function(token, message){
260        return function(fileName, contents, comments){
261               
262                var idx = contents.indexOf(token);
263                var before, after;
264                var tokenLength = token.length;
265
266                while(idx > -1){
267                        before = contents.charAt(idx - 1);
268                        after = contents.charAt(idx + tokenLength);
269                        if(!comments[idx] &&
270                                ((before != " " && before != "\t"
271                                        && (token != "==" || before != "!")
272                                        && (token != "=" ||
273                                                (before != "<" &&
274                                                 before != ">" &&
275                                                 before != "=" &&
276                                                 before != "!" &&
277                                                 before != "+" &&
278                                                 before != "-" &&
279                                                 before != "*" &&
280                                                 before != "/" &&
281                                                 before != "&" &&
282                                                 before != "|" ))) ||
283                                (
284                                        (after != " " && contents.charCodeAt(idx + tokenLength) != 13
285                                                && contents.charCodeAt(idx + tokenLength) != 10)
286                                        && (token != "==" || after != "=")
287                                        && (token != "!=" || after != "=")
288                                        && (token != "<" || after != "=")
289                                        && (token != ">" || after != "=")
290                                        && (token != "=" || after != "=")
291                                        && (token != "&" || after != "=")
292                                        && (token != "|" || after != "=")
293                                        && (token != "+" || after != "=")
294                                        && (token != "-" || after != "=")
295                                        && (token != "*" || after != "=")
296                                        && (token != "/" || after != "=")
297                                ))){
298                                checkstyleUtil.addError(message, fileName, contents, idx);
299                        }
300                        idx = contents.indexOf(token, idx + token.length);
301                }
302        };
303};
304
305
306
307checkstyleUtil.isEOL = function(contents, pos){
308        var c = contents.charCodeAt(pos);
309        return c == 10 || c == 13 || contents.charAt(pos) == "\n";
310};
311
312// All the rules that will be applied to each file.
313checkstyleUtil.rules = {
314
315        "elseFollowedBySpace": function(fileName, contents, comments){
316                var idx = contents.indexOf("else ");
317                while(idx > -1){
318
319                        if(!comments[idx] && contents.substring(idx + 5, idx + 7) != "if"){
320                                checkstyleUtil.addError("\" else \" cannot be followed by a space", fileName, contents, idx);
321                        }
322                        idx = contents.indexOf("else {", idx + 1);
323                }
324        },
325       
326        "trailingComma" : function(fileName, contents, comments){
327               
328                var s = ",";
329                var idx = contents.indexOf(s);
330                var nextChar;
331               
332                while(idx > -1){
333                        if(!comments[idx]){
334                                nextChar = checkstyleUtil.getNextChar(contents, idx + 1, comments, true);
335                                if(nextChar && nextChar.value == "}"){
336                                        checkstyleUtil.addError("Trailing commas are not permitted", fileName, contents, idx);
337                                }
338                        }
339                        idx = contents.indexOf(s, idx + 1);
340                }
341        },
342       
343        "switchCaseNewLine" : function(fileName, contents, comments){
344                var s = "\tcase ";
345                var idx = contents.indexOf(s);
346                var nextColonIdx;
347                var eolIdx;
348               
349                while(idx > -1){
350                       
351                        if(!comments[idx]){
352                                eolIdx = contents.indexOf("\n", idx + 4);
353                               
354                                if(eolIdx > idx){
355                                        // Count backwards from the end of the line.
356                                        // The first character, that is not a comment,
357                                        // Should be a ':'
358                                       
359                                        for(var i = eolIdx; i > idx + 4; i--){
360                                                var c = contents.charAt(i);
361                                                if(!comments[i]
362                                                        && c != ' '
363                                                        && c != '\t'
364                                                        && c != ':'
365                                                        && !checkstyleUtil.isEOL(contents, i)){
366                                                        checkstyleUtil.addError(
367                                                                "A CASE statement should be followed by a new line",
368                                                                fileName, contents, idx);
369                                                        break;
370                                                }
371                                                if(c == ':'){
372                                                        break;
373                                                }
374                                        }
375                                }
376                        }
377                        idx = contents.indexOf(s, idx + 4);
378                }
379        },
380       
381        "curlyBraceAtStartOfLine": function(fileName, contents, comments){
382               
383                var idx = contents.indexOf("\n");
384               
385                while(idx > -1){
386                        var nextChar = checkstyleUtil.getNextChar(contents, idx + 1);
387                       
388                        if(nextChar && !comments[nextChar.pos] && nextChar.value == "{"){
389                                // Go back three lines, and look for "dojo.declare".  If it exists in the last three lines,
390                                // then it is ok to have  { at the start of this line.
391                               
392                                var nlCount = 0;
393                                var i;
394                                for(i = idx - 1; i > -1 && nlCount < 3; i--){
395                                        if(contents[i] == "\n"){
396                                                nlCount++;
397                                        }
398                                }
399                                var declarePos = contents.indexOf("dojo.declare", Math.max(0, i));
400                                if(declarePos < 0 || declarePos > idx){
401                                        checkstyleUtil.addError("An opening curly brace should not be the first on a line", fileName, contents, idx);
402                                }
403                        }
404                        idx = contents.indexOf("\n", idx + 1);
405                }
406        },
407       
408        "parenthesisSpaceCurlyBrace": checkstyleUtil.createSimpleSearch(") {", "A space is not permitted between a closing parenthesis and a curly brace"),
409       
410        "useTabs": function(fileName, contents, comments){
411               
412                var idx = contents.indexOf("  ");
413               
414                while(idx > -1){
415                        var nextChar = checkstyleUtil.getNextChar(contents, idx + 1);
416                        if(!comments[idx] && nextChar && nextChar.value.charCodeAt(0) != 13){
417                                checkstyleUtil.addError("Tabs should be used instead of spaces", fileName, contents, idx);
418                                var nextLine = checkstyleUtil.findNextCharPos(contents, idx + 1, "\n");
419                                if(nextLine < 0){
420                                        break;
421                                }
422                                idx = contents.indexOf("  ", nextLine + 1);
423                        } else{
424                                idx = contents.indexOf("  ", idx + 2);
425                        }
426                }
427        },
428       
429        "commentFormatting": function(fileName, contents, comments){
430               
431                var commentNames = checkstyleUtil.commentNames;
432                var invalidPrefixes = ["//", "//\t"];
433                var idx;
434               
435                for(var i = 0; i < commentNames.length; i++){
436                        var comment = commentNames[i];
437
438                        for(var j = 0; j < invalidPrefixes.length; j++){
439                                idx = contents.indexOf(invalidPrefixes[j] + comment + ":");
440
441                                // Make sure that there is a space before the comment.
442                                while(idx > -1){
443                                        checkstyleUtil.addError("Must be just a space in a comment before \"" + comment + "\"" , fileName, contents, idx);
444                                        var nextLine = checkstyleUtil.findNextCharPos(contents, idx + 1, "\n");
445                                        if(nextLine < 0){
446                                                break;
447                                        }
448                                        idx = contents.indexOf(invalidPrefixes[j] + comment + ":", nextLine);
449                                }
450                        }
451                       
452                        idx = contents.indexOf(comment + ":");
453                       
454                        // Make sure that the comment name is on a line by itself. The body of the comment
455                        // must be on the next line.
456                        while(idx > -1){
457                                if(comments[idx]){
458                                        var search = idx + comment.length + 1;
459                               
460                                        // Make sure that there is nothing after the comment name on the same line.
461                                        while(!checkstyleUtil.isEOL(contents, search)){
462                                                if(contents[search] != " " && contents[search] != "\t"){
463                                                        checkstyleUtil.addError("The comment \"" + comment + "\" must be followed by a new line" ,
464                                                                                fileName, contents, idx);
465                                                        break;
466                                                }
467                                                search++;
468                                        }
469                                }
470                                idx = contents.indexOf(comment + ":", idx + comment.length + 2);
471                        }
472                }
473        },
474       
475        "spacesAroundEquals": checkstyleUtil.createSpaceWrappedSearch("==", "The equals sign should be preceded and followed by a space"),
476        "spacesAroundNotEquals": checkstyleUtil.createSpaceWrappedSearch("!=", "The != sign should be preceded and followed by a space"),
477        "spacesAroundAssignment": checkstyleUtil.createSpaceWrappedSearch("=", "The = sign should be preceded and followed by a space"),
478        "spacesAroundOr": checkstyleUtil.createSpaceWrappedSearch("||", "The || sign should be preceded and followed by a space"),
479        "spacesAroundLessThan": checkstyleUtil.createSpaceWrappedSearch("<", "The < sign should be preceded and followed by a space"),
480        "spacesAroundGreaterThan": checkstyleUtil.createSpaceWrappedSearch(">", "The > sign should be preceded and followed by a space"),
481        "spacesAroundAnd": checkstyleUtil.createSpaceWrappedSearch("&&", "The && sign should be preceded and followed by a space")
482};
483
484var noSpaceAfter = ["catch","do","finally","for","if","switch","try","while","with"];
485
486// Add checks for all the elements that are not allowed to have a space after them.
487checkstyleUtil.createNoSpaceAfterFunction = function(name){
488        checkstyleUtil.rules["noSpaceAfter" + noSpaceAfter[i] + "1"] =
489                checkstyleUtil.createSimpleSearch(" " + name +" ", "\" " + name + " \" cannot be followed by a space");
490        checkstyleUtil.rules["noSpaceAfter" + noSpaceAfter[i] + "2"] =
491                checkstyleUtil.createSimpleSearch("\t" + name +" ", "\" " + name + " \" cannot be followed by a space");
492}
493
494for(var i = 0; i < noSpaceAfter.length; i++){
495        checkstyleUtil.createNoSpaceAfterFunction(noSpaceAfter[i]);
496}
497
498checkstyleUtil.clear = function(){
499        checkstyleUtil.errors = [];
500}
501
502checkstyleUtil.serializeErrors = function(){
503        var buf = [];
504        var errs = checkstyleUtil.errors;
505        for(var i = 0; i < errs.length; i++){
506                buf.push(errs[i].file + ":" + errs[i].line + " - " + errs[i].message);
507        }
508        return buf.join("\n");
509}
510
511checkstyleUtil.makeSimpleFixes = function(contents){
512       
513        var comments = checkstyleUtil.getComments(contents);
514        for(var i = 0; i < noSpaceAfter.length; i++){
515                contents = checkstyleUtil.fixSpaceAfter(contents, noSpaceAfter[i], comments);
516        }
517        /*
518        contents = contents.split("    ").join("\t")
519                                .split("  ").join("\t")
520                                .split(") {").join("){")
521                                .split("\tif (").join("\tif(")
522                                .split("} else").join("}else")
523                                .split("}\telse").join("}else")
524                                .split("}else {").join("}else{")
525                                .split("\twhile (").join("\twhile(")
526                                .split("\tfor (").join("\tfor(")
527                                .split("\tswitch (").join("\tswitch(");
528        */
529       
530        contents = checkstyleUtil.replaceAllExceptComments(contents, "=  ", "= ", comments);
531        comments = checkstyleUtil.getComments(contents);
532        contents = checkstyleUtil.replaceAllExceptComments(contents, "    ", "\t", comments);
533        comments = checkstyleUtil.getComments(contents);
534        contents = checkstyleUtil.replaceAllExceptComments(contents, "  ", "\t", comments);
535        comments = checkstyleUtil.getComments(contents);
536        contents = checkstyleUtil.replaceAllExceptComments(contents, "\tif (", "\tif(", comments);
537        comments = checkstyleUtil.getComments(contents);
538        contents = checkstyleUtil.replaceAllExceptComments(contents, "} else", "}else", comments);
539        comments = checkstyleUtil.getComments(contents);
540        contents = checkstyleUtil.replaceAllExceptComments(contents, "}\telse", "}else", comments);
541        comments = checkstyleUtil.getComments(contents);
542        contents = checkstyleUtil.replaceAllExceptComments(contents, "}else {", "}else{", comments);
543        comments = checkstyleUtil.getComments(contents);
544        contents = checkstyleUtil.replaceAllExceptComments(contents, "\twhile (", "\twhile(", comments);
545        comments = checkstyleUtil.getComments(contents);
546        contents = checkstyleUtil.replaceAllExceptComments(contents, "\tfor (", "\tfor(", comments);
547        comments = checkstyleUtil.getComments(contents);
548        contents = checkstyleUtil.replaceAllExceptComments(contents, "\tswitch (", "\tswitch(", comments);
549        comments = checkstyleUtil.getComments(contents);
550        contents = checkstyleUtil.replaceAllExceptComments(contents, ") {", "){", comments);
551        comments = checkstyleUtil.getComments(contents);
552        contents = checkstyleUtil.replaceAllExceptComments(contents, "//summary:", "// summary:", {});
553        contents = checkstyleUtil.replaceAllExceptComments(contents, "//description:", "// description:", {});
554        comments = checkstyleUtil.getComments(contents);
555       
556        contents = checkstyleUtil.fixTrailingWhitespace(contents);
557        comments = checkstyleUtil.getComments(contents);
558        contents = checkstyleUtil.fixSpaceBeforeAndAfter(contents, "===", comments);
559        comments = checkstyleUtil.getComments(contents);
560        contents = checkstyleUtil.fixSpaceBeforeAndAfter(contents, "!==", comments);
561        comments = checkstyleUtil.getComments(contents);
562        contents = checkstyleUtil.fixSpaceBeforeAndAfter(contents, "<=", comments);
563        comments = checkstyleUtil.getComments(contents);
564        contents = checkstyleUtil.fixSpaceBeforeAndAfter(contents, "<", comments);
565        comments = checkstyleUtil.getComments(contents);
566        contents = checkstyleUtil.fixSpaceBeforeAndAfter(contents, ">=", comments);
567        comments = checkstyleUtil.getComments(contents);
568        contents = checkstyleUtil.fixSpaceBeforeAndAfter(contents, ">", comments);
569        comments = checkstyleUtil.getComments(contents);
570        contents = checkstyleUtil.fixSpaceBeforeAndAfter(contents, "!=", comments);
571        comments = checkstyleUtil.getComments(contents);
572        contents = checkstyleUtil.fixSpaceBeforeAndAfter(contents, "==", comments);
573        comments = checkstyleUtil.getComments(contents);
574        contents = checkstyleUtil.fixSpaceBeforeAndAfter(contents, "=", comments);
575        comments = checkstyleUtil.getComments(contents);
576        contents = checkstyleUtil.fixSpaceBeforeAndAfter(contents, "||", comments);
577        comments = checkstyleUtil.getComments(contents);
578        contents = checkstyleUtil.fixSpaceBeforeAndAfter(contents, "&&", comments);
579        comments = checkstyleUtil.getComments(contents);
580       
581        contents = checkstyleUtil.fixCommentNames(contents);
582       
583       
584       
585        return contents;
586}
587
588checkstyleUtil.fixCommentNames = function(contents){
589        var commentNames = checkstyleUtil.commentNames;
590        var i;
591       
592        for(i = 0; i < commentNames.length; i++){
593                contents = checkstyleUtil.replaceAllExceptComments(contents, "//\t" + commentNames[i] + ":", "// " + commentNames[i] + ":", {});
594        }
595       
596        for(i = 0; i < commentNames.length; i++){
597                var commentName = commentNames[i];
598                var searchToken = "// " + commentName + ":";
599                var idx = contents.indexOf(searchToken);
600               
601               
602                while(idx > -1){
603                        // If the comment name is not followed immediately by a new line, then insert a new line,
604                        // two forward slashes and two tabs.
605                        if(!checkstyleUtil.isEOL(contents, idx + commentName.length + 4)){
606                                // Calculate how many tabs to put before the "//"
607                               
608                                var tabs = "";
609                                var search = idx - 1;
610                                while(!checkstyleUtil.isEOL(contents, search)){
611                                        tabs += contents.charAt(search);
612                                        search--;
613                                }
614                                var insertPos = idx + commentName.length + 4;
615                                if(contents.charAt(insertPos) == " " || contents.charAt(insertPos) == "\t"){
616                                        contents = checkstyleUtil.deleteChar(contents, insertPos);
617                                }
618                               
619                                contents = checkstyleUtil.insertChar(contents, "\n" + tabs + "//\t\t", idx + commentName.length + 4);
620                       
621                        }
622                        idx = contents.indexOf(searchToken, idx + commentName.length);
623                }
624        }
625        return contents;
626}
627
628
629checkstyleUtil.replaceAllExceptComments = function(contents, old, newStr, comments){
630        var idx = contents.indexOf(old);
631        var toRemove = [];
632       
633        while(idx > -1){
634                if(!comments[idx]){
635                        toRemove.push(idx);
636                }
637
638                idx = contents.indexOf(old, idx + old.length);
639        }
640       
641        // Process the string backwards so we don't have to recompute the comments each time.
642        for(var i = toRemove.length - 1; i > -1; i--){
643                idx = toRemove[i];
644                if(!comments[idx]){
645                        contents = contents.substring(0, idx)
646                                        + newStr
647                                        + contents.substring(idx + old.length, contents.length);
648                }
649        }
650        return contents;
651}
652
653checkstyleUtil.insertChar = function(contents, ch, pos){
654        return contents.substring(0, pos) + ch + contents.substring(pos);
655}
656checkstyleUtil.deleteChar = function(contents, pos){
657        return contents.substring(0, pos) + contents.substring(pos + 1);
658}
659
660checkstyleUtil.fixTrailingWhitespace = function(contents) {
661        var idx = contents.indexOf("\n");
662       
663        // Find each new line character, then iterate backwards until a non-whitespace character is found
664        // then remove the whitespace.
665        while(idx > -1){
666                var search = idx - 1;
667               
668                while(search > -1 && (contents.charAt(search) == " " || contents.charAt(search) == "\t")){
669                        search--;
670                }
671               
672                if(search < idx -1){
673                        contents = contents.substring(0, search + 1)
674                                        + contents.substring(idx, contents.length);
675                       
676                        idx = contents.indexOf("\n", search + 2);
677                }else{
678                        idx = contents.indexOf("\n", idx + 1);
679                }
680        }
681
682        return contents;
683}
684
685checkstyleUtil.fixSpaceAfter = function(contents, token, comments){
686        var idx = contents.indexOf(token + " ");
687       
688        while(idx > -1){
689                if(!comments[idx]){
690                        contents = checkstyleUtil.deleteChar(contents, idx + token.length);
691                }
692               
693                idx = contents.indexOf(token + " ", idx + token.length);
694        }
695        return contents;
696}
697
698checkstyleUtil.fixSpaceBeforeAndAfter = function(contents, token, comments){
699        var idx = contents.indexOf(token);
700        var before, after;
701        var len = token.length;
702
703        while(idx > -1){
704                before = contents.charAt(idx - 1);
705                after = contents.charAt(idx + len);
706                if(!comments[idx]){
707                        // Only insert a space before the token if:
708                        // - char before is not a space or a tab
709                        // - token is "==" and the char before is neither "!" or "="
710               
711                        if(before != " " && before != "\t"
712                                && (token != "==" || (before != "!" && before != "="))
713                                && (token != "=" ||
714                                                (before != "<" &&
715                                                 before != ">" &&
716                                                 before != "=" &&
717                                                 before != "!" &&
718                                                 before != "+" &&
719                                                 before != "-" &&
720                                                 before != "*" &&
721                                                 before != "/" &&
722                                                 before != "&" &&
723                                                 before != "|" ))
724                                ){
725                               
726                                contents = checkstyleUtil.insertChar(contents, " ", idx);
727                                idx ++;
728                        }
729                       
730                        // Only insert a space after the token if:
731                        // - char after is not a space
732                        // - char after is not a new line
733                        // - char after is not "="
734                        if((after != " " && contents.charCodeAt(idx + len) != 13
735                                        && contents.charCodeAt(idx + len) != 10)
736                                        && (token != "==" || after != "=")
737                                        && (token != "!=" || after != "=")
738                                        && (token != "=" || after != "=")
739                                        && (token != "<" || after != "=")
740                                        && (token != ">" || after != "=")
741                                        && (token != "&" || after != "=")
742                                        && (token != "|" || after != "=")
743                                        && (token != "+" || after != "=")
744                                        && (token != "-" || after != "=")
745                                        && (token != "*" || after != "=")
746                                        && (token != "/" || after != "=")
747                                       
748                                        ){
749                                contents = contents = checkstyleUtil.insertChar(contents, " ", idx + token.length);
750                                idx++;
751                        }
752                }
753                idx = contents.indexOf(token, idx + token.length);
754        }
755        return contents;
756}
757
758// Creates the data file suitable to be loaded into a dojo.data.ItemFileReadStore
759checkstyleUtil.generateReport = function(skipPrint){
760       
761        var ids = 1;
762        var json = ["{id:'" +(ids++) + "', file: 'All', isFolder:true}"];
763
764        // A map of folders that have already been found.
765        var allFolders = {};
766       
767        var messageIds = {};
768        var messageCounter = 1;
769        var i, err;
770       
771        function getFolderName(fileName){
772                // Extract the folder name from a file name
773                var idx = fileName.lastIndexOf("/");
774                return fileName.substring(0, idx);
775        }
776       
777        // Add a folder to the list of folders.
778        function pushFolder(folderName){
779                if(!allFolders[folderName]){
780                        allFolders[folderName] = true;
781                        json.push("{id: '" +(ids++) + "', file: '" + folderName + "', folder: 1}");
782                }
783        }
784       
785        for(i = 0; i < checkstyleUtil.errors.length; i++){
786                err = checkstyleUtil.errors[i];
787                var message = err.message;
788                var messageId = messageIds[message];
789                if(!messageId){
790                        messageId = "m" + messageCounter++;
791                        messageIds[message] = messageId;
792                       
793                        json.push("{id:'" + messageId +
794                                        "',msg:'" + message +
795                                        "'}");
796                }
797        }
798       
799        pushFolder("All");
800       
801        // Create the JSON records for each error.
802        for(i = 0; i < checkstyleUtil.errors.length; i++){
803                err = checkstyleUtil.errors[i];
804                var folderName = getFolderName(err.file);
805                pushFolder(folderName);
806               
807                json.push("{id:'" +(ids++) +
808                                        "', file:'" + err.file +
809                                        "',line:" + err.line +
810                                        ",msg:{'_reference':'" + messageIds[err.message] +
811                                        //"'},folder:'" + folderName +
812                                        "'},folder: 0" +
813                                        "}");
814               
815        }
816
817        // Add the date that the check was run to the store.
818        json.push("{id:'" +(ids++) + "', date: " +(new Date()).getTime() + "}");
819       
820        // Save the file.
821
822        if(!skipPrint){
823                print("Found " + checkstyleUtil.errors.length + " checkstyle errors. " +
824                "Open the file checkstyleReport.html to view the results.");
825        }
826                                       
827        return "{ identifier: 'id', label:'file', items: [" + json.join(",\n") + "]}";
828};
Note: See TracBrowser for help on using the repository browser.