I've implemented a small program in JavaScript to count the number of lines of a string of java source code.
This was done for one of the Code Kata exercise: http://codekata.com/kata/kata13-counting-code-lines/
Overall, the goal of this exercise is summarised as follow:
The mixture of line-based things (single line comments, blank lines, and so on) with the stream-based block comments can make solutions slightly ugly. While coding your solution, consider the structure of your code, and see how well it fits the structure of the problem. As with most of these kata, consider coding multiple alternative implementations. Does what you learned on the first tries affect your approach to subsequent ones?
To be honest, I've submitted this for an interview and was told that this "lacked fundamentals by allowing errors in the code, there were issues in code construct and there were issues in choice of techniques".
Here's my simple app's source (also available in CodePen):
/**
* Return the number of lines of code of a Java source code.
* {@link http://codekata.com/kata/kata13-counting-code-lines/}
* @param {string} Java source code
* @return {number}
*/
function getJavaLineCount(source) {
var count = 0;
var patterns = {
spaces: /^\s+/,
singleLineComment: /^\/\/.*/,
multiLineComment: /^\/\*((?!\*\/)[\s\S])*\*\//,
code: /^.*\s*/
};
var readToken = function () {
var m, type;
if (m = source.match(patterns.spaces)) {
type = 'spaces';
} else if (m = source.match(patterns.singleLineComment)) {
type = 'singleLineComment';
} else if (m = source.match(patterns.multiLineComment)) {
type = 'multiLineComment';
} else if (m = source.match(patterns.code)) {
type = 'code';
} else {
throw new Error("Unknown code pattern!");
}
var token = m[0];
source = source.substr(token.length);
//DEBUG
console.log('Found token (%s): %s', type, JSON.stringify(token));
return type;
};
while (source) {
if (readToken() === 'code') {
count++;
}
console.log('new source = |%s|', source);
}
//DEBUG
console.log('LOC = ', count);
return count;
}
$(function () {
var calculateLOC = function() {
$('#linesOfCode').text(getJavaLineCount(
$('#source').val()
));
};
$('#source').change(calculateLOC);
calculateLOC();
});
textarea {
width: 50%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="source" rows="15">
/*****
* This is a test program with 5 lines of code
* \/* no nesting allowed!
//*****//***/// Slightly pathological comment ending...
public class Hello {
@cool
private String test = "some /* commented */ 'and' \" asd other\" " +
"string";
public static final void main(String [] args) { // gotta love Java
// Say hello
System./*wait*/out./*for*/println/*it*/("Hello/*");
}
}
</textarea>
<p>
<span id="linesOfCode">n/a</span> lines of java code.
</p>
To improve this, I could imagine writing a simple character parser to avoid using regexp, that's assuming that we consider regexps to be too slow in JS.
I know that if you provide it broken java code, it'll not work properly - but I assumed that this case would not be considered a normal scenario in this exercise.
Apart from this, I'm not sure what other kind of errors it might have.
Any suggestions?