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}