Skip to content

Commit f2bb6f5

Browse files
committed
Work around exception when jshint accesses console
When checking multiple files, JSHint 1.1.0 runs into a condition where it tries to access the console object, leading to a runtime exception. The workaround is to fake a console object with no-ops. See jshint/jshint#931
1 parent dc693b8 commit f2bb6f5

File tree

2 files changed

+61
-4
lines changed
  • bundles/com.eclipsesource.jshint/src/com/eclipsesource/jshint
  • tests/com.eclipsesource.jshint.test/src/com/eclipsesource/jshint

2 files changed

+61
-4
lines changed

bundles/com.eclipsesource.jshint/src/com/eclipsesource/jshint/JSHint.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ public class JSHint {
4747

4848
private static final String DEFAULT_JSHINT_VERSION = "1.1.0";
4949
private static final int DEFAULT_JSHINT_INDENT = 4;
50+
private Function fakeConsole;
5051
private Function jshint;
5152
private Object opts;
52-
private ScriptableObject scope;
5353
private int indent = DEFAULT_JSHINT_INDENT;
5454

5555
/**
@@ -171,8 +171,11 @@ public static String getDefaultLibraryVersion() {
171171
private void load( Reader reader ) throws IOException {
172172
Context context = Context.enter();
173173
try {
174-
scope = context.initStandardObjects();
174+
ScriptableObject scope = context.initStandardObjects();
175175
context.evaluateReader( scope, reader, "jshint library", 1, null );
176+
String code = "fakeConsole = function(){ console = {log:function(){},error:function(){},trace:function(){}}; };";
177+
context.evaluateString( scope, code, "fake console", 2, null );
178+
fakeConsole = (Function)scope.get( "fakeConsole" );
176179
jshint = findJSHintFunction( scope );
177180
} catch( RhinoException exception ) {
178181
throw new IllegalArgumentException( "Could not evaluate JavaScript input", exception );
@@ -184,6 +187,8 @@ private void load( Reader reader ) throws IOException {
184187
private boolean checkCode( Context context, String code ) {
185188
try {
186189
Object[] args = new Object[] { code, opts };
190+
ScriptableObject scope = context.initStandardObjects();
191+
fakeConsole.call( context, scope, null, null );
187192
return ( (Boolean)jshint.call( context, scope, null, args ) ).booleanValue();
188193
} catch( JavaScriptException exception ) {
189194
String message = "JavaScript exception thrown by JSHint: " + exception.getMessage();

tests/com.eclipsesource.jshint.test/src/com/eclipsesource/jshint/JSHint_Test.java

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public class JSHint_Test {
3535
@Before
3636
public void setUp() throws IOException {
3737
problems = new ArrayList<Problem>();
38-
handler = new TestHandler();
38+
handler = new TestHandler( problems );
3939
jsHint = new JSHint();
4040
jsHint.load();
4141
}
@@ -284,11 +284,63 @@ public void errorAtEndDoesNotThrowException() {
284284
jsHint.check( "var x = 1;\t#", handler );
285285
}
286286

287-
private class TestHandler implements ProblemHandler {
287+
@Test
288+
public void checkSameInputTwice() {
289+
jsHint.configure( new Configuration().addOption( "undef", true ) );
290+
LoggingHandler handler1 = new LoggingHandler();
291+
LoggingHandler handler2 = new LoggingHandler();
292+
293+
jsHint.check( "var x = 1;\t#", handler1 );
294+
jsHint.check( "var x = 1;\t#", handler2 );
295+
296+
assertTrue( handler1.toString().length() > 0 );
297+
assertEquals( handler1.toString(), handler2.toString() );
298+
}
299+
300+
@Test
301+
public void checkMultipleFiles() {
302+
// see https://github.com/jshint/jshint/issues/931
303+
jsHint.configure( new Configuration().addOption( "undef", true ) );
304+
305+
jsHint.check( "var x = 1;\t#", handler );
306+
jsHint.check( "var x = 1;\t#", handler );
307+
jsHint.check( "var x = 1;\t#", handler );
308+
jsHint.check( "var x = 1;\t#", handler );
309+
jsHint.check( "var x = 1;\t#", handler );
310+
}
311+
312+
private static class LoggingHandler implements ProblemHandler {
313+
314+
StringBuilder log = new StringBuilder();
315+
316+
public void handleProblem( Problem problem ) {
317+
log.append( problem.getLine() );
318+
log.append( ':' );
319+
log.append( problem.getCharacter() );
320+
log.append( ':' );
321+
log.append( problem.getMessage() );
322+
log.append( '\n' );
323+
}
324+
325+
@Override
326+
public String toString() {
327+
return log.toString();
328+
}
329+
330+
}
331+
332+
private static class TestHandler implements ProblemHandler {
333+
334+
private final List<Problem> problems;
335+
336+
public TestHandler( List<Problem> problems ) {
337+
this.problems = problems;
338+
}
288339

289340
public void handleProblem( Problem problem ) {
290341
problems.add( problem );
291342
}
343+
292344
}
293345

294346
}

0 commit comments

Comments
 (0)