001/*
002 * Copyright (c) 2012-2021 Institut National des Sciences Appliquées de Lyon (INSA Lyon) and others
003 *
004 * This program and the accompanying materials are made available under the
005 * terms of the Eclipse Public License 2.0 which is available at
006 * http://www.eclipse.org/legal/epl-2.0.
007 *
008 * SPDX-License-Identifier: EPL-2.0
009 */
010
011package gololang;
012
013import java.text.MessageFormat;
014import java.util.ResourceBundle;
015import java.util.Locale;
016import gololang.ir.GoloElement;
017import gololang.ir.GoloModule;
018
019/**
020 * Functions to display various localized messages.
021 */
022public final class Messages {
023
024  private static final boolean ANSI = !System.getProperty("os.name").contains("Windows");
025  private static final boolean color = (System.console() != null);
026
027  private static final ResourceBundle MESSAGES = ResourceBundle.getBundle("messages", Locale.getDefault());
028
029  private static final String ERROR = "\u001B[31m"; // red
030  private static final String INFO = "\u001B[34m";  // blue
031  private static final String WARNING = "\u001B[33m"; // yellow
032  private static final String STACK = "\u001B[36m"; // cyan
033
034  private Messages() {
035    // utility class
036  }
037
038  private static boolean withColor() {
039    return ANSI && color;
040  }
041
042  /**
043   * Format a localized message.
044   */
045  public static String message(String key, Object... values) {
046    return MessageFormat.format(MESSAGES.getString(key), values);
047  }
048
049  /**
050   * Return a localized message.
051   */
052  public static String message(String key) {
053    return MESSAGES.getString(key);
054  }
055
056  public static String prefixed(String prefix, String message) {
057    return prefixed(prefix, message, null);
058  }
059
060  public static String prefixed(String prefix, String message, String color) {
061    if (!withColor() || color == null) {
062      return String.format("[%s] %s", MESSAGES.getString(prefix), message);
063    }
064    return String.format("[%s%s\u001B[0m] %s", color, MESSAGES.getString(prefix), message);
065  }
066
067  public static void printPrefixed(String prefix, String message, String color) {
068    System.err.println(prefixed(prefix, message, color));
069  }
070
071  public static void printPrefixedWithPosition(String prefix, Object message, GoloElement<?> node, String color) {
072    String source = "unknown";
073    int line = 0;
074    int column = 0;
075    if (node != null) {
076      GoloModule mod = node.enclosingModule();
077      if (mod != null) {
078        source = mod.sourceFile();
079      }
080      line = node.positionInSourceCode().getStartLine();
081      column = node.positionInSourceCode().getStartColumn();
082    }
083    printPrefixed(
084        prefix,
085        node == null ? String.valueOf(message) : String.format("%s (%s {l=%s,c=%s})",
086          message, source, line, column),
087        color);
088  }
089
090  /**
091   * Prints an error message to standard error.
092   */
093  public static void error(Object message, String prefix) {
094    printPrefixed("error", prefix + String.valueOf(message), ERROR);
095  }
096
097  /**
098   * Prints an error message to standard error.
099   */
100  public static void error(Object message) {
101    error(message, "");
102  }
103
104  /**
105   * Prints an error message to standard error with information from given IR node.
106   */
107  public static void error(Object message, GoloElement<?> node) {
108    printPrefixedWithPosition("error", message, node, ERROR);
109  }
110
111
112  /**
113   * Prints a warning to standard error.
114   */
115  public static void warning(Object message) {
116    printPrefixed("warning", String.valueOf(message), WARNING);
117  }
118
119  /**
120   * Prints a warning to standard error with information from given IR node.
121   */
122  public static void warning(Object message, GoloElement<?> node) {
123    printPrefixedWithPosition("warning", message, node, WARNING);
124  }
125
126  /**
127   * Prints an info message to standard error.
128   */
129  public static void info(Object message) {
130    printPrefixed("info", String.valueOf(message), INFO);
131  }
132
133  /**
134   * Prints an info message to standard error with information from given IR node.
135   */
136  public static void info(Object message, GoloElement<?> node) {
137    printPrefixedWithPosition("info", message, node, INFO);
138  }
139
140  /**
141   * Prints an error stack trace to standard error.
142   */
143  public static void printStackTrace(Throwable e) {
144    if (withColor()) {
145      System.err.print(STACK);
146    }
147    e.printStackTrace();
148    if (withColor()) {
149      System.err.println("\u001B[0m");
150    }
151  }
152
153
154
155}