package jshinter.analyzer;

import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.TokenStream;

import jshinter.antlr.ECMAScriptBaseListener;
import jshinter.antlr.ECMAScriptParser;
import jshinter.antlr.ECMAScriptParser.AssignmentOperatorContext;
import jshinter.antlr.ECMAScriptParser.BitAndExpressionContext;
import jshinter.antlr.ECMAScriptParser.BitNotExpressionContext;
import jshinter.antlr.ECMAScriptParser.BitOrExpressionContext;
import jshinter.antlr.ECMAScriptParser.BitShiftExpressionContext;
import jshinter.antlr.ECMAScriptParser.BitXOrExpressionContext;

public class JSHinterListener extends ECMAScriptBaseListener {

	private ECMAScriptParser parser;
	
	private final Boolean DEBUG;
	
	public JSHinterListener(ECMAScriptParser parser) {
		this.parser = parser;
		this.DEBUG = false;
	}
	
	public JSHinterListener(ECMAScriptParser parser, Boolean debugMode) {
		this.parser = parser;
		this.DEBUG = debugMode;
	}
	
	private void reportError(String msg, Token t) {
		System.out.printf("%d,%d: %s.\n", t.getLine(), t.getCharPositionInLine() + 1, msg);
	}

	@Override
	public void enterBitXOrExpression(BitXOrExpressionContext ctx) {
		TokenStream ts = parser.getTokenStream();

		reportError(String.format("Unexpected use of '%s'", ctx.getChild(1).getText()), ts.get(ctx.getChild(1).getSourceInterval().a));
	}

	@Override
	public void enterBitShiftExpression(BitShiftExpressionContext ctx) {
		TokenStream ts = parser.getTokenStream();

		reportError(String.format("Unexpected use of '%s'", ctx.getChild(1).getText()), ts.get(ctx.getChild(1).getSourceInterval().a));
	}

	@Override
	public void enterBitNotExpression(BitNotExpressionContext ctx) {
		TokenStream ts = parser.getTokenStream();

		reportError(String.format("Unexpected use of '%s'", ctx.getChild(1).getText()), ts.get(ctx.getChild(1).getSourceInterval().a));
	}

	@Override
	public void enterBitAndExpression(BitAndExpressionContext ctx) {
		TokenStream ts = parser.getTokenStream();

		reportError(String.format("Unexpected use of '%s'", ctx.getChild(1).getText()), ts.get(ctx.getChild(1).getSourceInterval().a));
	}

	@Override
	public void enterBitOrExpression(BitOrExpressionContext ctx) {
		TokenStream ts = parser.getTokenStream();

		reportError(String.format("Unexpected use of '%s'", ctx.getChild(1).getText()), ts.get(ctx.getChild(1).getSourceInterval().a));
	}

	@Override
	public void enterAssignmentOperator(AssignmentOperatorContext ctx) {
		Token t = ctx.getStart();
		int type = t.getType();
		
		if (type >= 45 || type <= 50) {
			reportError(String.format("Unexpected use of '%s'", t.getText()), t);
		}
	}
}

@@ -570,16 +570,82 @@
 Context;
+%0Aimport jshinter.antlr.ECMAScriptParser.EqualityExpressionContext;
 %0A%0Apublic
@@ -1124,16 +1124,39 @@
 Line() +
+ t.getText().length() +
  1, msg)
@@ -2694,11 +2694,510 @@
 ;%0A%09%09%7D%0A%09%7D
+%0A%0A%09@Override%0A%09public void enterEqualityExpression(EqualityExpressionContext ctx) %7B%0A%09%09TokenStream ts = parser.getTokenStream();%0A%09%09Token t = ts.get(ctx.getChild(1).getSourceInterval().b);%0A%09%09String operator = t.getText();%0A%09%09%0A%09%09String shouldBe = null;%0A%09%09%0A%09%09if (operator.equals(%22==%22)) %7B%0A%09%09%09shouldBe = %22===%22;%0A%09%09%7D else if (operator.equals(%22!=%22)) %7B%0A%09%09%09shouldBe = %22!==%22;%0A%09%09%7D%0A%09%09%0A%09%09if (!shouldBe.equals(null)) %7B%0A%09%09%09reportError(String.format(%22Expected '%25s' and instead saw '%25s'%22, shouldBe, operator), t);%0A%09%09%7D%0A%09%7D
 %0A%7D%0A

Include eqeqeq rule