package mclint;

import natlab.utils.NodeFinder;
import ast.ASTNode;
import ast.CompilationUnits;
import ast.Program;

import com.google.common.collect.ComparisonChain;

/**
 * A code location; a file path together with line and column numbers.
 * Essentially just a value object, together with a handy method to
 * extract the necessary information from an AST node.
 * @author ismail
 *
 */
public class Location implements Comparable<Location> {
  private int line;
  private int column;
  private String path;

  public static Location of(ASTNode<?> node) {
    int line = node.getStartLine();
    int col = node.getStartColumn();
    // Some ASTNodes don't have position information...
    if (line == 0 && col == 0)
      return Location.of(node.getParent());
    return new Location(getPathOf(node), line, col);
  }

  // TODO change this use Project / MatlabProgram
  private static String getPathOf(ASTNode<?> node) {
    Program program = null;
    if (node instanceof CompilationUnits)
      program = ((CompilationUnits)node).getProgram(0);
    else if (node.getParent() instanceof CompilationUnits)
      program = (Program)(node.getChild(0));
    else
      program = NodeFinder.findParent(Program.class, node);
    return program.getFile().getPath();
  }

  public int getLine() {
    return line;
  }

  public int getColumn() {
    return column;
  }

  public String getPath() {
    return path;
  }

  @Override
  public String toString() {
    return String.format("%s [%d, %d]", path, line, column);
  }

  private Location(String path, int line, int column) {
    this.line = line;
    this.column = column;
    this.path = path;
  }

  @Override
  public int compareTo(Location location) {
    return ComparisonChain.start()
        .compare(getPath(), location.getPath())
        .compare(getLine(), location.getLine())
        .compare(getColumn(), location.getColumn())
        .result();
  }

  @Override
  public boolean equals(Object o) {
    if (o == this)
      return true;
    if (!(o instanceof Location))
      return false;
    return compareTo((Location)o) == 0;
  }
}

@@ -21,100 +21,19 @@
 ort 
-natlab.utils.NodeFinder;%0Aimport ast.ASTNode;%0Aimport ast.CompilationUnits;%0Aimport ast.Program
+ast.ASTNode
 ;%0A%0Ai
@@ -413,27 +413,37 @@
 private 
-String path
+MatlabProgram program
 ;%0A%0A  pub
@@ -716,481 +716,42 @@
 ion(
-getPathOf(node), line, col);%0A  %7D%0A%0A  // TODO change this use Project / MatlabProgram%0A  private static String getPathOf(ASTNode%3C?%3E node) %7B%0A    Program program = null;%0A    if (node instanceof CompilationUnits)%0A      program = ((CompilationUnits)node).getProgram(0);%0A    else if (node.getParent() instanceof CompilationUnits)%0A      program = (Program)(node.getChild(0));%0A    else%0A      program = NodeFinder.findParent(Program.class, node);%0A    return program.getFile().getPath(
+node.getMatlabProgram(), line, col
 );%0A 
@@ -865,22 +865,38 @@
 lic 
-String
+MatlabProgram
  get
-Path
+MatlabProgram
 () %7B
@@ -908,19 +908,22 @@
 return p
-ath
+rogram
 ;%0A  %7D%0A%0A 
@@ -1003,19 +1003,32 @@
  %25d%5D%22, p
+rogram.getP
 ath
+()
 , line, 
@@ -1064,19 +1064,29 @@
 ion(
-String path
+MatlabProgram program
 , in
@@ -1169,18 +1169,24 @@
 is.p
-ath = path
+rogram = program
 ;%0A  
@@ -1303,24 +1303,62 @@
 (get
-Path(), location
+MatlabProgram().getPath(), location.getMatlabProgram()
 .get

Use MatlabProgram instead of a path in Location