/* ************************************************************** *
 *                                                                *
 * Copyright (c) 2005, Kota Mizushima, All rights reserved.       *
 *                                                                *
 *                                                                *
 * This software is distributed under the modified BSD License.   *
 * ************************************************************** */
package onion.compiler;

import java.io.BufferedReader;
import java.io.IOException;
import java.text.MessageFormat;

import onion.compiler.pass.Parsing;
import onion.compiler.pass.CodeAnalysis;
import onion.compiler.pass.CodeGeneration;
import onion.compiler.util.*;


/**
 * @author Kota Mizushima
 * Date: 2005/04/08
 */
public class OnionCompiler {
  private final CompilerConfig config;
  
  public OnionCompiler(CompilerConfig config) {
    this.config = config;
  }
  
  public CompilerConfig getConfig() {
    return config;
  }
  
  public CompiledClass[] compile(String[] fileNames) {
    InputSource[] srcs = new InputSource[fileNames.length];
    for (int i = 0; i < srcs.length; i++) {
      srcs[i] = new FileInputSource(fileNames[i]);        
    }
    return compile(srcs);
  }
  
  public CompiledClass[] compile(InputSource[] srcs) {
    try {
      Parsing        pass1 = new Parsing(config);
      CodeAnalysis   pass2 = new CodeAnalysis(config);
      CodeGeneration pass3 = new CodeGeneration(config);
      return pass3.process(pass2.process(pass1.process(srcs)));
    }catch(CompilationException ex){
      for(CompileError error:ex) printError(error);
      System.err.println(Messages.get("error.count", ex.size()));
      return null;
    }
  }
  
  private void printError(CompileError error) {
    Location location = error.getLocation();
    String sourceFile = error.getSourceFile();
    StringBuffer message = new StringBuffer();
    if(sourceFile == null){
      message.append(MessageFormat.format("{0}", new Object[]{error.getMessage()}));
    }else{
      String line = null, lineNum = null;
      try {
        line = location != null ? getLine(sourceFile, location.line()) : "";
        lineNum = location != null ? Integer.toString(location.line()) : "";
      } catch (IOException e) {
        e.printStackTrace();
      }
      message.append(
        MessageFormat.format(
          "{0}:{1}: {2}", new Object[]{sourceFile, lineNum, error.getMessage()}
        )
      );
      
      message.append(Systems.getLineSeparator());
      message.append("\t\t");
      message.append(line);
      message.append(Systems.getLineSeparator());
      message.append("\t\t");
      if(location != null){
        message.append(getCursor(location.column()));
      }
    }
    System.err.println(new String(message));
  }

  private String getCursor(int column) {
    return Strings.repeat(" ", column - 1) + "^";
  }
  
  private String getLine(String sourceFile, int lineNumber) throws IOException {
    BufferedReader reader = Inputs.newReader(sourceFile);
    try {
      int countLineNumber = 1;
      String line = null;
      while((line = reader.readLine()) != null){
        if(countLineNumber == lineNumber) break;
        countLineNumber++;
      }
      return line;
    } finally {
      reader.close();
    }
  }
}
@@ -2008,29 +2008,16 @@
 (%22%7B0%7D%22, 
-new Object%5B%5D%7B
 error.ge
@@ -2026,17 +2026,16 @@
 essage()
-%7D
 ));%0A    
@@ -2339,25 +2339,16 @@
 .append(
-%0A        
 MessageF
@@ -2364,19 +2364,8 @@
 mat(
-%0A          
 %22%7B0%7D
@@ -2380,21 +2380,8 @@
 %7D%22, 
-new Object%5B%5D%7B
 sour
@@ -2419,35 +2419,11 @@
 ge()
-%7D%0A        )%0A      );%0A      
+));
 %0A   

Refactor onion.compiler.OnionCompiler.