feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
47
jdkSrc/jdk8/com/sun/tools/javac/util/Abort.java
Normal file
47
jdkSrc/jdk8/com/sun/tools/javac/util/Abort.java
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
/** Throwing an instance of
|
||||
* this class causes (silent) termination of the main compiler method.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class Abort extends Error {
|
||||
private static final long serialVersionUID = 0;
|
||||
|
||||
public Abort(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public Abort() {
|
||||
super();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,533 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
import com.sun.tools.javac.api.DiagnosticFormatter;
|
||||
import com.sun.tools.javac.api.DiagnosticFormatter.Configuration.DiagnosticPart;
|
||||
import com.sun.tools.javac.api.DiagnosticFormatter.Configuration.MultilineLimit;
|
||||
import com.sun.tools.javac.api.DiagnosticFormatter.PositionKind;
|
||||
import com.sun.tools.javac.api.Formattable;
|
||||
import com.sun.tools.javac.code.Lint.LintCategory;
|
||||
import com.sun.tools.javac.code.Printer;
|
||||
import com.sun.tools.javac.code.Symbol;
|
||||
import com.sun.tools.javac.code.Type;
|
||||
import com.sun.tools.javac.code.Type.CapturedType;
|
||||
import com.sun.tools.javac.file.BaseFileObject;
|
||||
import com.sun.tools.javac.jvm.Profile;
|
||||
import com.sun.tools.javac.tree.JCTree.*;
|
||||
import com.sun.tools.javac.tree.Pretty;
|
||||
import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticType.*;
|
||||
|
||||
/**
|
||||
* This abstract class provides a basic implementation of the functionalities that should be provided
|
||||
* by any formatter used by javac. Among the main features provided by AbstractDiagnosticFormatter are:
|
||||
*
|
||||
* <ul>
|
||||
* <li> Provides a standard implementation of the visitor-like methods defined in the interface DiagnisticFormatter.
|
||||
* Those implementations are specifically targeting JCDiagnostic objects.
|
||||
* <li> Provides basic support for i18n and a method for executing all locale-dependent conversions
|
||||
* <li> Provides the formatting logic for rendering the arguments of a JCDiagnostic object.
|
||||
* <ul>
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter<JCDiagnostic> {
|
||||
|
||||
/**
|
||||
* JavacMessages object used by this formatter for i18n.
|
||||
*/
|
||||
protected JavacMessages messages;
|
||||
|
||||
/**
|
||||
* Configuration object used by this formatter
|
||||
*/
|
||||
private SimpleConfiguration config;
|
||||
|
||||
/**
|
||||
* Current depth level of the disgnostic being formatted
|
||||
* (!= 0 for subdiagnostics)
|
||||
*/
|
||||
protected int depth = 0;
|
||||
|
||||
/**
|
||||
* All captured types that have been encountered during diagnostic formatting.
|
||||
* This info is used by the FormatterPrinter in order to print friendly unique
|
||||
* ids for captured types
|
||||
*/
|
||||
private List<Type> allCaptured = List.nil();
|
||||
|
||||
/**
|
||||
* Initialize an AbstractDiagnosticFormatter by setting its JavacMessages object.
|
||||
* @param messages
|
||||
*/
|
||||
protected AbstractDiagnosticFormatter(JavacMessages messages, SimpleConfiguration config) {
|
||||
this.messages = messages;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public String formatKind(JCDiagnostic d, Locale l) {
|
||||
switch (d.getType()) {
|
||||
case FRAGMENT: return "";
|
||||
case NOTE: return localize(l, "compiler.note.note");
|
||||
case WARNING: return localize(l, "compiler.warn.warning");
|
||||
case ERROR: return localize(l, "compiler.err.error");
|
||||
default:
|
||||
throw new AssertionError("Unknown diagnostic type: " + d.getType());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String format(JCDiagnostic d, Locale locale) {
|
||||
allCaptured = List.nil();
|
||||
return formatDiagnostic(d, locale);
|
||||
}
|
||||
|
||||
protected abstract String formatDiagnostic(JCDiagnostic d, Locale locale);
|
||||
|
||||
public String formatPosition(JCDiagnostic d, PositionKind pk,Locale l) {
|
||||
Assert.check(d.getPosition() != Position.NOPOS);
|
||||
return String.valueOf(getPosition(d, pk));
|
||||
}
|
||||
//where
|
||||
private long getPosition(JCDiagnostic d, PositionKind pk) {
|
||||
switch (pk) {
|
||||
case START: return d.getIntStartPosition();
|
||||
case END: return d.getIntEndPosition();
|
||||
case LINE: return d.getLineNumber();
|
||||
case COLUMN: return d.getColumnNumber();
|
||||
case OFFSET: return d.getIntPosition();
|
||||
default:
|
||||
throw new AssertionError("Unknown diagnostic position: " + pk);
|
||||
}
|
||||
}
|
||||
|
||||
public String formatSource(JCDiagnostic d, boolean fullname, Locale l) {
|
||||
JavaFileObject fo = d.getSource();
|
||||
if (fo == null)
|
||||
throw new IllegalArgumentException(); // d should have source set
|
||||
if (fullname)
|
||||
return fo.getName();
|
||||
else if (fo instanceof BaseFileObject)
|
||||
return ((BaseFileObject) fo).getShortName();
|
||||
else
|
||||
return BaseFileObject.getSimpleName(fo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the arguments of a given diagnostic.
|
||||
*
|
||||
* @param d diagnostic whose arguments are to be formatted
|
||||
* @param l locale object to be used for i18n
|
||||
* @return a Collection whose elements are the formatted arguments of the diagnostic
|
||||
*/
|
||||
protected Collection<String> formatArguments(JCDiagnostic d, Locale l) {
|
||||
ListBuffer<String> buf = new ListBuffer<String>();
|
||||
for (Object o : d.getArgs()) {
|
||||
buf.append(formatArgument(d, o, l));
|
||||
}
|
||||
return buf.toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a single argument of a given diagnostic.
|
||||
*
|
||||
* @param d diagnostic whose argument is to be formatted
|
||||
* @param arg argument to be formatted
|
||||
* @param l locale object to be used for i18n
|
||||
* @return string representation of the diagnostic argument
|
||||
*/
|
||||
protected String formatArgument(JCDiagnostic d, Object arg, Locale l) {
|
||||
if (arg instanceof JCDiagnostic) {
|
||||
String s = null;
|
||||
depth++;
|
||||
try {
|
||||
s = formatMessage((JCDiagnostic)arg, l);
|
||||
}
|
||||
finally {
|
||||
depth--;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
else if (arg instanceof JCExpression) {
|
||||
return expr2String((JCExpression)arg);
|
||||
}
|
||||
else if (arg instanceof Iterable<?>) {
|
||||
return formatIterable(d, (Iterable<?>)arg, l);
|
||||
}
|
||||
else if (arg instanceof Type) {
|
||||
return printer.visit((Type)arg, l);
|
||||
}
|
||||
else if (arg instanceof Symbol) {
|
||||
return printer.visit((Symbol)arg, l);
|
||||
}
|
||||
else if (arg instanceof JavaFileObject) {
|
||||
return ((JavaFileObject)arg).getName();
|
||||
}
|
||||
else if (arg instanceof Profile) {
|
||||
return ((Profile)arg).name;
|
||||
}
|
||||
else if (arg instanceof Formattable) {
|
||||
return ((Formattable)arg).toString(l, messages);
|
||||
}
|
||||
else {
|
||||
return String.valueOf(arg);
|
||||
}
|
||||
}
|
||||
//where
|
||||
private String expr2String(JCExpression tree) {
|
||||
switch(tree.getTag()) {
|
||||
case PARENS:
|
||||
return expr2String(((JCParens)tree).expr);
|
||||
case LAMBDA:
|
||||
case REFERENCE:
|
||||
case CONDEXPR:
|
||||
return Pretty.toSimpleString(tree);
|
||||
default:
|
||||
Assert.error("unexpected tree kind " + tree.getKind());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Format an iterable argument of a given diagnostic.
|
||||
*
|
||||
* @param d diagnostic whose argument is to be formatted
|
||||
* @param it iterable argument to be formatted
|
||||
* @param l locale object to be used for i18n
|
||||
* @return string representation of the diagnostic iterable argument
|
||||
*/
|
||||
protected String formatIterable(JCDiagnostic d, Iterable<?> it, Locale l) {
|
||||
StringBuilder sbuf = new StringBuilder();
|
||||
String sep = "";
|
||||
for (Object o : it) {
|
||||
sbuf.append(sep);
|
||||
sbuf.append(formatArgument(d, o, l));
|
||||
sep = ",";
|
||||
}
|
||||
return sbuf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Format all the subdiagnostics attached to a given diagnostic.
|
||||
*
|
||||
* @param d diagnostic whose subdiagnostics are to be formatted
|
||||
* @param l locale object to be used for i18n
|
||||
* @return list of all string representations of the subdiagnostics
|
||||
*/
|
||||
protected List<String> formatSubdiagnostics(JCDiagnostic d, Locale l) {
|
||||
List<String> subdiagnostics = List.nil();
|
||||
int maxDepth = config.getMultilineLimit(MultilineLimit.DEPTH);
|
||||
if (maxDepth == -1 || depth < maxDepth) {
|
||||
depth++;
|
||||
try {
|
||||
int maxCount = config.getMultilineLimit(MultilineLimit.LENGTH);
|
||||
int count = 0;
|
||||
for (JCDiagnostic d2 : d.getSubdiagnostics()) {
|
||||
if (maxCount == -1 || count < maxCount) {
|
||||
subdiagnostics = subdiagnostics.append(formatSubdiagnostic(d, d2, l));
|
||||
count++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
depth--;
|
||||
}
|
||||
}
|
||||
return subdiagnostics;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a subdiagnostics attached to a given diagnostic.
|
||||
*
|
||||
* @param parent multiline diagnostic whose subdiagnostics is to be formatted
|
||||
* @param sub subdiagnostic to be formatted
|
||||
* @param l locale object to be used for i18n
|
||||
* @return string representation of the subdiagnostics
|
||||
*/
|
||||
protected String formatSubdiagnostic(JCDiagnostic parent, JCDiagnostic sub, Locale l) {
|
||||
return formatMessage(sub, l);
|
||||
}
|
||||
|
||||
/** Format the faulty source code line and point to the error.
|
||||
* @param d The diagnostic for which the error line should be printed
|
||||
*/
|
||||
protected String formatSourceLine(JCDiagnostic d, int nSpaces) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
DiagnosticSource source = d.getDiagnosticSource();
|
||||
int pos = d.getIntPosition();
|
||||
if (d.getIntPosition() == Position.NOPOS)
|
||||
throw new AssertionError();
|
||||
String line = (source == null ? null : source.getLine(pos));
|
||||
if (line == null)
|
||||
return "";
|
||||
buf.append(indent(line, nSpaces));
|
||||
int col = source.getColumnNumber(pos, false);
|
||||
if (config.isCaretEnabled()) {
|
||||
buf.append("\n");
|
||||
for (int i = 0; i < col - 1; i++) {
|
||||
buf.append((line.charAt(i) == '\t') ? "\t" : " ");
|
||||
}
|
||||
buf.append(indent("^", nSpaces));
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
protected String formatLintCategory(JCDiagnostic d, Locale l) {
|
||||
LintCategory lc = d.getLintCategory();
|
||||
if (lc == null)
|
||||
return "";
|
||||
return localize(l, "compiler.warn.lintOption", lc.option);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a String into a locale-dependent representation accordingly to a given locale.
|
||||
*
|
||||
* @param l locale object to be used for i18n
|
||||
* @param key locale-independent key used for looking up in a resource file
|
||||
* @param args localization arguments
|
||||
* @return a locale-dependent string
|
||||
*/
|
||||
protected String localize(Locale l, String key, Object... args) {
|
||||
return messages.getLocalizedString(l, key, args);
|
||||
}
|
||||
|
||||
public boolean displaySource(JCDiagnostic d) {
|
||||
return config.getVisible().contains(DiagnosticPart.SOURCE) &&
|
||||
d.getType() != FRAGMENT &&
|
||||
d.getIntPosition() != Position.NOPOS;
|
||||
}
|
||||
|
||||
public boolean isRaw() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a string with a given amount of empty spaces. Useful for
|
||||
* indenting the text of a diagnostic message.
|
||||
*
|
||||
* @param nSpaces the amount of spaces to be added to the result string
|
||||
* @return the indentation string
|
||||
*/
|
||||
protected String indentString(int nSpaces) {
|
||||
String spaces = " ";
|
||||
if (nSpaces <= spaces.length())
|
||||
return spaces.substring(0, nSpaces);
|
||||
else {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
for (int i = 0 ; i < nSpaces ; i++)
|
||||
buf.append(" ");
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indent a string by prepending a given amount of empty spaces to each line
|
||||
* of the string.
|
||||
*
|
||||
* @param s the string to be indented
|
||||
* @param nSpaces the amount of spaces that should be prepended to each line
|
||||
* of the string
|
||||
* @return an indented string
|
||||
*/
|
||||
protected String indent(String s, int nSpaces) {
|
||||
String indent = indentString(nSpaces);
|
||||
StringBuilder buf = new StringBuilder();
|
||||
String nl = "";
|
||||
for (String line : s.split("\n")) {
|
||||
buf.append(nl);
|
||||
buf.append(indent + line);
|
||||
nl = "\n";
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public SimpleConfiguration getConfiguration() {
|
||||
return config;
|
||||
}
|
||||
|
||||
static public class SimpleConfiguration implements Configuration {
|
||||
|
||||
protected Map<MultilineLimit, Integer> multilineLimits;
|
||||
protected EnumSet<DiagnosticPart> visibleParts;
|
||||
protected boolean caretEnabled;
|
||||
|
||||
public SimpleConfiguration(Set<DiagnosticPart> parts) {
|
||||
multilineLimits = new HashMap<MultilineLimit, Integer>();
|
||||
setVisible(parts);
|
||||
setMultilineLimit(MultilineLimit.DEPTH, -1);
|
||||
setMultilineLimit(MultilineLimit.LENGTH, -1);
|
||||
setCaretEnabled(true);
|
||||
}
|
||||
|
||||
@SuppressWarnings("fallthrough")
|
||||
public SimpleConfiguration(Options options, Set<DiagnosticPart> parts) {
|
||||
this(parts);
|
||||
String showSource = null;
|
||||
if ((showSource = options.get("showSource")) != null) {
|
||||
if (showSource.equals("true"))
|
||||
setVisiblePart(DiagnosticPart.SOURCE, true);
|
||||
else if (showSource.equals("false"))
|
||||
setVisiblePart(DiagnosticPart.SOURCE, false);
|
||||
}
|
||||
String diagOpts = options.get("diags");
|
||||
if (diagOpts != null) {//override -XDshowSource
|
||||
Collection<String> args = Arrays.asList(diagOpts.split(","));
|
||||
if (args.contains("short")) {
|
||||
setVisiblePart(DiagnosticPart.DETAILS, false);
|
||||
setVisiblePart(DiagnosticPart.SUBDIAGNOSTICS, false);
|
||||
}
|
||||
if (args.contains("source"))
|
||||
setVisiblePart(DiagnosticPart.SOURCE, true);
|
||||
if (args.contains("-source"))
|
||||
setVisiblePart(DiagnosticPart.SOURCE, false);
|
||||
}
|
||||
String multiPolicy = null;
|
||||
if ((multiPolicy = options.get("multilinePolicy")) != null) {
|
||||
if (multiPolicy.equals("disabled"))
|
||||
setVisiblePart(DiagnosticPart.SUBDIAGNOSTICS, false);
|
||||
else if (multiPolicy.startsWith("limit:")) {
|
||||
String limitString = multiPolicy.substring("limit:".length());
|
||||
String[] limits = limitString.split(":");
|
||||
try {
|
||||
switch (limits.length) {
|
||||
case 2: {
|
||||
if (!limits[1].equals("*"))
|
||||
setMultilineLimit(MultilineLimit.DEPTH, Integer.parseInt(limits[1]));
|
||||
}
|
||||
case 1: {
|
||||
if (!limits[0].equals("*"))
|
||||
setMultilineLimit(MultilineLimit.LENGTH, Integer.parseInt(limits[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(NumberFormatException ex) {
|
||||
setMultilineLimit(MultilineLimit.DEPTH, -1);
|
||||
setMultilineLimit(MultilineLimit.LENGTH, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
String showCaret = null;
|
||||
if (((showCaret = options.get("showCaret")) != null) &&
|
||||
showCaret.equals("false"))
|
||||
setCaretEnabled(false);
|
||||
else
|
||||
setCaretEnabled(true);
|
||||
}
|
||||
|
||||
public int getMultilineLimit(MultilineLimit limit) {
|
||||
return multilineLimits.get(limit);
|
||||
}
|
||||
|
||||
public EnumSet<DiagnosticPart> getVisible() {
|
||||
return EnumSet.copyOf(visibleParts);
|
||||
}
|
||||
|
||||
public void setMultilineLimit(MultilineLimit limit, int value) {
|
||||
multilineLimits.put(limit, value < -1 ? -1 : value);
|
||||
}
|
||||
|
||||
|
||||
public void setVisible(Set<DiagnosticPart> diagParts) {
|
||||
visibleParts = EnumSet.copyOf(diagParts);
|
||||
}
|
||||
|
||||
public void setVisiblePart(DiagnosticPart diagParts, boolean enabled) {
|
||||
if (enabled)
|
||||
visibleParts.add(diagParts);
|
||||
else
|
||||
visibleParts.remove(diagParts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a '^' sign under the source line displayed by the formatter
|
||||
* (if applicable).
|
||||
*
|
||||
* @param caretEnabled if true enables caret
|
||||
*/
|
||||
public void setCaretEnabled(boolean caretEnabled) {
|
||||
this.caretEnabled = caretEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells whether the caret display is active or not.
|
||||
*
|
||||
* @return true if the caret is enabled
|
||||
*/
|
||||
public boolean isCaretEnabled() {
|
||||
return caretEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
public Printer getPrinter() {
|
||||
return printer;
|
||||
}
|
||||
|
||||
public void setPrinter(Printer printer) {
|
||||
this.printer = printer;
|
||||
}
|
||||
|
||||
/**
|
||||
* An enhanced printer for formatting types/symbols used by
|
||||
* AbstractDiagnosticFormatter. Provides alternate numbering of captured
|
||||
* types (they are numbered starting from 1 on each new diagnostic, instead
|
||||
* of relying on the underlying hashcode() method which generates unstable
|
||||
* output). Also detects cycles in wildcard messages (e.g. if the wildcard
|
||||
* type referred by a given captured type C contains C itself) which might
|
||||
* lead to infinite loops.
|
||||
*/
|
||||
protected Printer printer = new Printer() {
|
||||
|
||||
@Override
|
||||
protected String localize(Locale locale, String key, Object... args) {
|
||||
return AbstractDiagnosticFormatter.this.localize(locale, key, args);
|
||||
}
|
||||
@Override
|
||||
protected String capturedVarId(CapturedType t, Locale locale) {
|
||||
return "" + (allCaptured.indexOf(t) + 1);
|
||||
}
|
||||
@Override
|
||||
public String visitCapturedType(CapturedType t, Locale locale) {
|
||||
if (!allCaptured.contains(t)) {
|
||||
allCaptured = allCaptured.append(t);
|
||||
}
|
||||
return super.visitCapturedType(t, locale);
|
||||
}
|
||||
};
|
||||
}
|
||||
261
jdkSrc/jdk8/com/sun/tools/javac/util/AbstractLog.java
Normal file
261
jdkSrc/jdk8/com/sun/tools/javac/util/AbstractLog.java
Normal file
@@ -0,0 +1,261 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
import com.sun.tools.javac.code.Lint.LintCategory;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;
|
||||
|
||||
|
||||
/**
|
||||
* A base class for error logs. Reports errors and warnings, and
|
||||
* keeps track of error numbers and positions.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public abstract class AbstractLog {
|
||||
AbstractLog(JCDiagnostic.Factory diags) {
|
||||
this.diags = diags;
|
||||
sourceMap = new HashMap<JavaFileObject, DiagnosticSource>();
|
||||
}
|
||||
|
||||
/** Re-assign source, returning previous setting.
|
||||
*/
|
||||
public JavaFileObject useSource(JavaFileObject file) {
|
||||
JavaFileObject prev = (source == null ? null : source.getFile());
|
||||
source = getSource(file);
|
||||
return prev;
|
||||
}
|
||||
|
||||
protected DiagnosticSource getSource(JavaFileObject file) {
|
||||
if (file == null)
|
||||
return DiagnosticSource.NO_SOURCE;
|
||||
DiagnosticSource s = sourceMap.get(file);
|
||||
if (s == null) {
|
||||
s = new DiagnosticSource(file, this);
|
||||
sourceMap.put(file, s);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/** Return the underlying diagnostic source
|
||||
*/
|
||||
public DiagnosticSource currentSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
/** Report an error, unless another error was already reported at same
|
||||
* source position.
|
||||
* @param key The key for the localized error message.
|
||||
* @param args Fields of the error message.
|
||||
*/
|
||||
public void error(String key, Object ... args) {
|
||||
report(diags.error(source, null, key, args));
|
||||
}
|
||||
|
||||
/** Report an error, unless another error was already reported at same
|
||||
* source position.
|
||||
* @param pos The source position at which to report the error.
|
||||
* @param key The key for the localized error message.
|
||||
* @param args Fields of the error message.
|
||||
*/
|
||||
public void error(DiagnosticPosition pos, String key, Object ... args) {
|
||||
report(diags.error(source, pos, key, args));
|
||||
}
|
||||
|
||||
/** Report an error, unless another error was already reported at same
|
||||
* source position.
|
||||
* @param flag A flag to set on the diagnostic
|
||||
* @param pos The source position at which to report the error.
|
||||
* @param key The key for the localized error message.
|
||||
* @param args Fields of the error message.
|
||||
*/
|
||||
public void error(DiagnosticFlag flag, DiagnosticPosition pos, String key, Object ... args) {
|
||||
JCDiagnostic d = diags.error(source, pos, key, args);
|
||||
d.setFlag(flag);
|
||||
report(d);
|
||||
}
|
||||
|
||||
/** Report an error, unless another error was already reported at same
|
||||
* source position.
|
||||
* @param pos The source position at which to report the error.
|
||||
* @param key The key for the localized error message.
|
||||
* @param args Fields of the error message.
|
||||
*/
|
||||
public void error(int pos, String key, Object ... args) {
|
||||
report(diags.error(source, wrap(pos), key, args));
|
||||
}
|
||||
|
||||
/** Report an error, unless another error was already reported at same
|
||||
* source position.
|
||||
* @param flag A flag to set on the diagnostic
|
||||
* @param pos The source position at which to report the error.
|
||||
* @param key The key for the localized error message.
|
||||
* @param args Fields of the error message.
|
||||
*/
|
||||
public void error(DiagnosticFlag flag, int pos, String key, Object ... args) {
|
||||
JCDiagnostic d = diags.error(source, wrap(pos), key, args);
|
||||
d.setFlag(flag);
|
||||
report(d);
|
||||
}
|
||||
|
||||
/** Report a warning, unless suppressed by the -nowarn option or the
|
||||
* maximum number of warnings has been reached.
|
||||
* @param key The key for the localized warning message.
|
||||
* @param args Fields of the warning message.
|
||||
*/
|
||||
public void warning(String key, Object ... args) {
|
||||
report(diags.warning(source, null, key, args));
|
||||
}
|
||||
|
||||
/** Report a lint warning, unless suppressed by the -nowarn option or the
|
||||
* maximum number of warnings has been reached.
|
||||
* @param lc The lint category for the diagnostic
|
||||
* @param key The key for the localized warning message.
|
||||
* @param args Fields of the warning message.
|
||||
*/
|
||||
public void warning(LintCategory lc, String key, Object ... args) {
|
||||
report(diags.warning(lc, key, args));
|
||||
}
|
||||
|
||||
/** Report a warning, unless suppressed by the -nowarn option or the
|
||||
* maximum number of warnings has been reached.
|
||||
* @param pos The source position at which to report the warning.
|
||||
* @param key The key for the localized warning message.
|
||||
* @param args Fields of the warning message.
|
||||
*/
|
||||
public void warning(DiagnosticPosition pos, String key, Object ... args) {
|
||||
report(diags.warning(source, pos, key, args));
|
||||
}
|
||||
|
||||
/** Report a lint warning, unless suppressed by the -nowarn option or the
|
||||
* maximum number of warnings has been reached.
|
||||
* @param lc The lint category for the diagnostic
|
||||
* @param pos The source position at which to report the warning.
|
||||
* @param key The key for the localized warning message.
|
||||
* @param args Fields of the warning message.
|
||||
*/
|
||||
public void warning(LintCategory lc, DiagnosticPosition pos, String key, Object ... args) {
|
||||
report(diags.warning(lc, source, pos, key, args));
|
||||
}
|
||||
|
||||
/** Report a warning, unless suppressed by the -nowarn option or the
|
||||
* maximum number of warnings has been reached.
|
||||
* @param pos The source position at which to report the warning.
|
||||
* @param key The key for the localized warning message.
|
||||
* @param args Fields of the warning message.
|
||||
*/
|
||||
public void warning(int pos, String key, Object ... args) {
|
||||
report(diags.warning(source, wrap(pos), key, args));
|
||||
}
|
||||
|
||||
/** Report a warning.
|
||||
* @param pos The source position at which to report the warning.
|
||||
* @param key The key for the localized warning message.
|
||||
* @param args Fields of the warning message.
|
||||
*/
|
||||
public void mandatoryWarning(DiagnosticPosition pos, String key, Object ... args) {
|
||||
report(diags.mandatoryWarning(source, pos, key, args));
|
||||
}
|
||||
|
||||
/** Report a warning.
|
||||
* @param lc The lint category for the diagnostic
|
||||
* @param pos The source position at which to report the warning.
|
||||
* @param key The key for the localized warning message.
|
||||
* @param args Fields of the warning message.
|
||||
*/
|
||||
public void mandatoryWarning(LintCategory lc, DiagnosticPosition pos, String key, Object ... args) {
|
||||
report(diags.mandatoryWarning(lc, source, pos, key, args));
|
||||
}
|
||||
|
||||
/** Provide a non-fatal notification, unless suppressed by the -nowarn option.
|
||||
* @param key The key for the localized notification message.
|
||||
* @param args Fields of the notint an error or warning message:
|
||||
*/
|
||||
public void note(String key, Object ... args) {
|
||||
report(diags.note(source, null, key, args));
|
||||
}
|
||||
|
||||
/** Provide a non-fatal notification, unless suppressed by the -nowarn option.
|
||||
* @param key The key for the localized notification message.
|
||||
* @param args Fields of the notification message.
|
||||
*/
|
||||
public void note(DiagnosticPosition pos, String key, Object ... args) {
|
||||
report(diags.note(source, pos, key, args));
|
||||
}
|
||||
|
||||
/** Provide a non-fatal notification, unless suppressed by the -nowarn option.
|
||||
* @param key The key for the localized notification message.
|
||||
* @param args Fields of the notification message.
|
||||
*/
|
||||
public void note(int pos, String key, Object ... args) {
|
||||
report(diags.note(source, wrap(pos), key, args));
|
||||
}
|
||||
|
||||
/** Provide a non-fatal notification, unless suppressed by the -nowarn option.
|
||||
* @param key The key for the localized notification message.
|
||||
* @param args Fields of the notification message.
|
||||
*/
|
||||
public void note(JavaFileObject file, String key, Object ... args) {
|
||||
report(diags.note(getSource(file), null, key, args));
|
||||
}
|
||||
|
||||
/** Provide a non-fatal notification, unless suppressed by the -nowarn option.
|
||||
* @param key The key for the localized notification message.
|
||||
* @param args Fields of the notification message.
|
||||
*/
|
||||
public void mandatoryNote(final JavaFileObject file, String key, Object ... args) {
|
||||
report(diags.mandatoryNote(getSource(file), key, args));
|
||||
}
|
||||
|
||||
protected abstract void report(JCDiagnostic diagnostic);
|
||||
|
||||
protected abstract void directError(String key, Object... args);
|
||||
|
||||
private DiagnosticPosition wrap(int pos) {
|
||||
return (pos == Position.NOPOS ? null : new SimpleDiagnosticPosition(pos));
|
||||
}
|
||||
|
||||
/** Factory for diagnostics
|
||||
*/
|
||||
protected JCDiagnostic.Factory diags;
|
||||
|
||||
/** The file that's currently being translated.
|
||||
*/
|
||||
protected DiagnosticSource source;
|
||||
|
||||
/** A cache of lightweight DiagnosticSource objects.
|
||||
*/
|
||||
protected Map<JavaFileObject, DiagnosticSource> sourceMap;
|
||||
}
|
||||
88
jdkSrc/jdk8/com/sun/tools/javac/util/ArrayUtils.java
Normal file
88
jdkSrc/jdk8/com/sun/tools/javac/util/ArrayUtils.java
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
|
||||
/** <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class ArrayUtils {
|
||||
|
||||
private static int calculateNewLength(int currentLength, int maxIndex) {
|
||||
while (currentLength < maxIndex + 1)
|
||||
currentLength = currentLength * 2;
|
||||
return currentLength;
|
||||
}
|
||||
|
||||
public static <T> T[] ensureCapacity(T[] array, int maxIndex) {
|
||||
if (maxIndex < array.length) {
|
||||
return array;
|
||||
} else {
|
||||
int newLength = calculateNewLength(array.length, maxIndex);
|
||||
@SuppressWarnings("unchecked")
|
||||
T[] result = (T[]) Array.newInstance(array.getClass().getComponentType(), newLength);
|
||||
System.arraycopy(array, 0, result, 0, array.length);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] ensureCapacity(byte[] array, int maxIndex) {
|
||||
if (maxIndex < array.length) {
|
||||
return array;
|
||||
} else {
|
||||
int newLength = calculateNewLength(array.length, maxIndex);
|
||||
byte[] result = new byte[newLength];
|
||||
System.arraycopy(array, 0, result, 0, array.length);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public static char[] ensureCapacity(char[] array, int maxIndex) {
|
||||
if (maxIndex < array.length) {
|
||||
return array;
|
||||
} else {
|
||||
int newLength = calculateNewLength(array.length, maxIndex);
|
||||
char[] result = new char[newLength];
|
||||
System.arraycopy(array, 0, result, 0, array.length);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public static int[] ensureCapacity(int[] array, int maxIndex) {
|
||||
if (maxIndex < array.length) {
|
||||
return array;
|
||||
} else {
|
||||
int newLength = calculateNewLength(array.length, maxIndex);
|
||||
int[] result = new int[newLength];
|
||||
System.arraycopy(array, 0, result, 0, array.length);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
138
jdkSrc/jdk8/com/sun/tools/javac/util/Assert.java
Normal file
138
jdkSrc/jdk8/com/sun/tools/javac/util/Assert.java
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
|
||||
/**
|
||||
* Simple facility for unconditional assertions.
|
||||
* The methods in this class are described in terms of equivalent assert
|
||||
* statements, assuming that assertions have been enabled.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class Assert {
|
||||
/** Equivalent to
|
||||
* assert cond;
|
||||
*/
|
||||
public static void check(boolean cond) {
|
||||
if (!cond)
|
||||
error();
|
||||
}
|
||||
|
||||
/** Equivalent to
|
||||
* assert (o == null);
|
||||
*/
|
||||
public static void checkNull(Object o) {
|
||||
if (o != null)
|
||||
error();
|
||||
}
|
||||
|
||||
/** Equivalent to
|
||||
* assert (t != null); return t;
|
||||
*/
|
||||
public static <T> T checkNonNull(T t) {
|
||||
if (t == null)
|
||||
error();
|
||||
return t;
|
||||
}
|
||||
|
||||
/** Equivalent to
|
||||
* assert cond : value;
|
||||
*/
|
||||
public static void check(boolean cond, int value) {
|
||||
if (!cond)
|
||||
error(String.valueOf(value));
|
||||
}
|
||||
|
||||
/** Equivalent to
|
||||
* assert cond : value;
|
||||
*/
|
||||
public static void check(boolean cond, long value) {
|
||||
if (!cond)
|
||||
error(String.valueOf(value));
|
||||
}
|
||||
|
||||
/** Equivalent to
|
||||
* assert cond : value;
|
||||
*/
|
||||
public static void check(boolean cond, Object value) {
|
||||
if (!cond)
|
||||
error(String.valueOf(value));
|
||||
}
|
||||
|
||||
/** Equivalent to
|
||||
* assert cond : value;
|
||||
*/
|
||||
public static void check(boolean cond, String msg) {
|
||||
if (!cond)
|
||||
error(msg);
|
||||
}
|
||||
|
||||
/** Equivalent to
|
||||
* assert (o == null) : value;
|
||||
*/
|
||||
public static void checkNull(Object o, Object value) {
|
||||
if (o != null)
|
||||
error(String.valueOf(value));
|
||||
}
|
||||
|
||||
/** Equivalent to
|
||||
* assert (o == null) : value;
|
||||
*/
|
||||
public static void checkNull(Object o, String msg) {
|
||||
if (o != null)
|
||||
error(msg);
|
||||
}
|
||||
|
||||
/** Equivalent to
|
||||
* assert (o != null) : value;
|
||||
*/
|
||||
public static <T> T checkNonNull(T t, String msg) {
|
||||
if (t == null)
|
||||
error(msg);
|
||||
return t;
|
||||
}
|
||||
|
||||
/** Equivalent to
|
||||
* assert false;
|
||||
*/
|
||||
public static void error() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
/** Equivalent to
|
||||
* assert false : msg;
|
||||
*/
|
||||
public static void error(String msg) {
|
||||
throw new AssertionError(msg);
|
||||
}
|
||||
|
||||
/** Prevent instantiation. */
|
||||
private Assert() { }
|
||||
}
|
||||
402
jdkSrc/jdk8/com/sun/tools/javac/util/BaseFileManager.java
Normal file
402
jdkSrc/jdk8/com/sun/tools/javac/util/BaseFileManager.java
Normal file
@@ -0,0 +1,402 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.nio.charset.CoderResult;
|
||||
import java.nio.charset.CodingErrorAction;
|
||||
import java.nio.charset.IllegalCharsetNameException;
|
||||
import java.nio.charset.UnsupportedCharsetException;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.JavaFileObject.Kind;
|
||||
|
||||
import com.sun.tools.javac.code.Lint;
|
||||
import com.sun.tools.javac.code.Source;
|
||||
import com.sun.tools.javac.file.FSInfo;
|
||||
import com.sun.tools.javac.file.Locations;
|
||||
import com.sun.tools.javac.main.Option;
|
||||
import com.sun.tools.javac.main.OptionHelper;
|
||||
import com.sun.tools.javac.main.OptionHelper.GrumpyHelper;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;
|
||||
|
||||
/**
|
||||
* Utility methods for building a filemanager.
|
||||
* There are no references here to file-system specific objects such as
|
||||
* java.io.File or java.nio.file.Path.
|
||||
*/
|
||||
public abstract class BaseFileManager {
|
||||
protected BaseFileManager(Charset charset) {
|
||||
this.charset = charset;
|
||||
byteBufferCache = new ByteBufferCache();
|
||||
locations = createLocations();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the context for JavacPathFileManager.
|
||||
*/
|
||||
public void setContext(Context context) {
|
||||
log = Log.instance(context);
|
||||
options = Options.instance(context);
|
||||
classLoaderClass = options.get("procloader");
|
||||
locations.update(log, options, Lint.instance(context), FSInfo.instance(context));
|
||||
}
|
||||
|
||||
protected Locations createLocations() {
|
||||
return new Locations();
|
||||
}
|
||||
|
||||
/**
|
||||
* The log to be used for error reporting.
|
||||
*/
|
||||
public Log log;
|
||||
|
||||
/**
|
||||
* User provided charset (through javax.tools).
|
||||
*/
|
||||
protected Charset charset;
|
||||
|
||||
protected Options options;
|
||||
|
||||
protected String classLoaderClass;
|
||||
|
||||
protected Locations locations;
|
||||
|
||||
protected Source getSource() {
|
||||
String sourceName = options.get(Option.SOURCE);
|
||||
Source source = null;
|
||||
if (sourceName != null)
|
||||
source = Source.lookup(sourceName);
|
||||
return (source != null ? source : Source.DEFAULT);
|
||||
}
|
||||
|
||||
protected ClassLoader getClassLoader(URL[] urls) {
|
||||
ClassLoader thisClassLoader = getClass().getClassLoader();
|
||||
|
||||
// Allow the following to specify a closeable classloader
|
||||
// other than URLClassLoader.
|
||||
|
||||
// 1: Allow client to specify the class to use via hidden option
|
||||
if (classLoaderClass != null) {
|
||||
try {
|
||||
Class<? extends ClassLoader> loader =
|
||||
Class.forName(classLoaderClass).asSubclass(ClassLoader.class);
|
||||
Class<?>[] constrArgTypes = { URL[].class, ClassLoader.class };
|
||||
Constructor<? extends ClassLoader> constr = loader.getConstructor(constrArgTypes);
|
||||
return constr.newInstance(new Object[] { urls, thisClassLoader });
|
||||
} catch (Throwable t) {
|
||||
// ignore errors loading user-provided class loader, fall through
|
||||
}
|
||||
}
|
||||
return new URLClassLoader(urls, thisClassLoader);
|
||||
}
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="Option handling">
|
||||
public boolean handleOption(String current, Iterator<String> remaining) {
|
||||
OptionHelper helper = new GrumpyHelper(log) {
|
||||
@Override
|
||||
public String get(Option option) {
|
||||
return options.get(option.getText());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(String name, String value) {
|
||||
options.put(name, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(String name) {
|
||||
options.remove(name);
|
||||
}
|
||||
};
|
||||
for (Option o: javacFileManagerOptions) {
|
||||
if (o.matches(current)) {
|
||||
if (o.hasArg()) {
|
||||
if (remaining.hasNext()) {
|
||||
if (!o.process(helper, current, remaining.next()))
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (!o.process(helper, current))
|
||||
return true;
|
||||
}
|
||||
// operand missing, or process returned false
|
||||
throw new IllegalArgumentException(current);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
// where
|
||||
private static final Set<Option> javacFileManagerOptions =
|
||||
Option.getJavacFileManagerOptions();
|
||||
|
||||
public int isSupportedOption(String option) {
|
||||
for (Option o : javacFileManagerOptions) {
|
||||
if (o.matches(option))
|
||||
return o.hasArg() ? 1 : 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public abstract boolean isDefaultBootClassPath();
|
||||
|
||||
// </editor-fold>
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="Encoding">
|
||||
private String defaultEncodingName;
|
||||
private String getDefaultEncodingName() {
|
||||
if (defaultEncodingName == null) {
|
||||
defaultEncodingName =
|
||||
new OutputStreamWriter(new ByteArrayOutputStream()).getEncoding();
|
||||
}
|
||||
return defaultEncodingName;
|
||||
}
|
||||
|
||||
public String getEncodingName() {
|
||||
String encName = options.get(Option.ENCODING);
|
||||
if (encName == null)
|
||||
return getDefaultEncodingName();
|
||||
else
|
||||
return encName;
|
||||
}
|
||||
|
||||
public CharBuffer decode(ByteBuffer inbuf, boolean ignoreEncodingErrors) {
|
||||
String encodingName = getEncodingName();
|
||||
CharsetDecoder decoder;
|
||||
try {
|
||||
decoder = getDecoder(encodingName, ignoreEncodingErrors);
|
||||
} catch (IllegalCharsetNameException e) {
|
||||
log.error("unsupported.encoding", encodingName);
|
||||
return (CharBuffer)CharBuffer.allocate(1).flip();
|
||||
} catch (UnsupportedCharsetException e) {
|
||||
log.error("unsupported.encoding", encodingName);
|
||||
return (CharBuffer)CharBuffer.allocate(1).flip();
|
||||
}
|
||||
|
||||
// slightly overestimate the buffer size to avoid reallocation.
|
||||
float factor =
|
||||
decoder.averageCharsPerByte() * 0.8f +
|
||||
decoder.maxCharsPerByte() * 0.2f;
|
||||
CharBuffer dest = CharBuffer.
|
||||
allocate(10 + (int)(inbuf.remaining()*factor));
|
||||
|
||||
while (true) {
|
||||
CoderResult result = decoder.decode(inbuf, dest, true);
|
||||
dest.flip();
|
||||
|
||||
if (result.isUnderflow()) { // done reading
|
||||
// make sure there is at least one extra character
|
||||
if (dest.limit() == dest.capacity()) {
|
||||
dest = CharBuffer.allocate(dest.capacity()+1).put(dest);
|
||||
dest.flip();
|
||||
}
|
||||
return dest;
|
||||
} else if (result.isOverflow()) { // buffer too small; expand
|
||||
int newCapacity =
|
||||
10 + dest.capacity() +
|
||||
(int)(inbuf.remaining()*decoder.maxCharsPerByte());
|
||||
dest = CharBuffer.allocate(newCapacity).put(dest);
|
||||
} else if (result.isMalformed() || result.isUnmappable()) {
|
||||
// bad character in input
|
||||
|
||||
// report coding error (warn only pre 1.5)
|
||||
if (!getSource().allowEncodingErrors()) {
|
||||
log.error(new SimpleDiagnosticPosition(dest.limit()),
|
||||
"illegal.char.for.encoding",
|
||||
charset == null ? encodingName : charset.name());
|
||||
} else {
|
||||
log.warning(new SimpleDiagnosticPosition(dest.limit()),
|
||||
"illegal.char.for.encoding",
|
||||
charset == null ? encodingName : charset.name());
|
||||
}
|
||||
|
||||
// skip past the coding error
|
||||
inbuf.position(inbuf.position() + result.length());
|
||||
|
||||
// undo the flip() to prepare the output buffer
|
||||
// for more translation
|
||||
dest.position(dest.limit());
|
||||
dest.limit(dest.capacity());
|
||||
dest.put((char)0xfffd); // backward compatible
|
||||
} else {
|
||||
throw new AssertionError(result);
|
||||
}
|
||||
}
|
||||
// unreached
|
||||
}
|
||||
|
||||
public CharsetDecoder getDecoder(String encodingName, boolean ignoreEncodingErrors) {
|
||||
Charset cs = (this.charset == null)
|
||||
? Charset.forName(encodingName)
|
||||
: this.charset;
|
||||
CharsetDecoder decoder = cs.newDecoder();
|
||||
|
||||
CodingErrorAction action;
|
||||
if (ignoreEncodingErrors)
|
||||
action = CodingErrorAction.REPLACE;
|
||||
else
|
||||
action = CodingErrorAction.REPORT;
|
||||
|
||||
return decoder
|
||||
.onMalformedInput(action)
|
||||
.onUnmappableCharacter(action);
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="ByteBuffers">
|
||||
/**
|
||||
* Make a byte buffer from an input stream.
|
||||
*/
|
||||
public ByteBuffer makeByteBuffer(InputStream in)
|
||||
throws IOException {
|
||||
int limit = in.available();
|
||||
if (limit < 1024) limit = 1024;
|
||||
ByteBuffer result = byteBufferCache.get(limit);
|
||||
int position = 0;
|
||||
while (in.available() != 0) {
|
||||
if (position >= limit)
|
||||
// expand buffer
|
||||
result = ByteBuffer.
|
||||
allocate(limit <<= 1).
|
||||
put((ByteBuffer)result.flip());
|
||||
int count = in.read(result.array(),
|
||||
position,
|
||||
limit - position);
|
||||
if (count < 0) break;
|
||||
result.position(position += count);
|
||||
}
|
||||
return (ByteBuffer)result.flip();
|
||||
}
|
||||
|
||||
public void recycleByteBuffer(ByteBuffer bb) {
|
||||
byteBufferCache.put(bb);
|
||||
}
|
||||
|
||||
/**
|
||||
* A single-element cache of direct byte buffers.
|
||||
*/
|
||||
private static class ByteBufferCache {
|
||||
private ByteBuffer cached;
|
||||
ByteBuffer get(int capacity) {
|
||||
if (capacity < 20480) capacity = 20480;
|
||||
ByteBuffer result =
|
||||
(cached != null && cached.capacity() >= capacity)
|
||||
? (ByteBuffer)cached.clear()
|
||||
: ByteBuffer.allocate(capacity + capacity>>1);
|
||||
cached = null;
|
||||
return result;
|
||||
}
|
||||
void put(ByteBuffer x) {
|
||||
cached = x;
|
||||
}
|
||||
}
|
||||
|
||||
private final ByteBufferCache byteBufferCache;
|
||||
// </editor-fold>
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="Content cache">
|
||||
public CharBuffer getCachedContent(JavaFileObject file) {
|
||||
ContentCacheEntry e = contentCache.get(file);
|
||||
if (e == null)
|
||||
return null;
|
||||
|
||||
if (!e.isValid(file)) {
|
||||
contentCache.remove(file);
|
||||
return null;
|
||||
}
|
||||
|
||||
return e.getValue();
|
||||
}
|
||||
|
||||
public void cache(JavaFileObject file, CharBuffer cb) {
|
||||
contentCache.put(file, new ContentCacheEntry(file, cb));
|
||||
}
|
||||
|
||||
public void flushCache(JavaFileObject file) {
|
||||
contentCache.remove(file);
|
||||
}
|
||||
|
||||
protected final Map<JavaFileObject, ContentCacheEntry> contentCache
|
||||
= new HashMap<JavaFileObject, ContentCacheEntry>();
|
||||
|
||||
protected static class ContentCacheEntry {
|
||||
final long timestamp;
|
||||
final SoftReference<CharBuffer> ref;
|
||||
|
||||
ContentCacheEntry(JavaFileObject file, CharBuffer cb) {
|
||||
this.timestamp = file.getLastModified();
|
||||
this.ref = new SoftReference<CharBuffer>(cb);
|
||||
}
|
||||
|
||||
boolean isValid(JavaFileObject file) {
|
||||
return timestamp == file.getLastModified();
|
||||
}
|
||||
|
||||
CharBuffer getValue() {
|
||||
return ref.get();
|
||||
}
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
public static Kind getKind(String name) {
|
||||
if (name.endsWith(Kind.CLASS.extension))
|
||||
return Kind.CLASS;
|
||||
else if (name.endsWith(Kind.SOURCE.extension))
|
||||
return Kind.SOURCE;
|
||||
else if (name.endsWith(Kind.HTML.extension))
|
||||
return Kind.HTML;
|
||||
else
|
||||
return Kind.OTHER;
|
||||
}
|
||||
|
||||
protected static <T> T nullCheck(T o) {
|
||||
o.getClass(); // null check
|
||||
return o;
|
||||
}
|
||||
|
||||
protected static <T> Collection<T> nullCheck(Collection<T> it) {
|
||||
for (T t : it)
|
||||
t.getClass(); // null check
|
||||
return it;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,412 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.EnumMap;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
import com.sun.tools.javac.util.AbstractDiagnosticFormatter.SimpleConfiguration;
|
||||
import com.sun.tools.javac.util.BasicDiagnosticFormatter.BasicConfiguration;
|
||||
|
||||
import static com.sun.tools.javac.api.DiagnosticFormatter.PositionKind.*;
|
||||
import static com.sun.tools.javac.util.BasicDiagnosticFormatter.BasicConfiguration.*;
|
||||
import static com.sun.tools.javac.util.LayoutCharacters.*;
|
||||
|
||||
/**
|
||||
* A basic formatter for diagnostic messages.
|
||||
* The basic formatter will format a diagnostic according to one of three format patterns, depending on whether
|
||||
* or not the source name and position are set. The formatter supports a printf-like string for patterns
|
||||
* with the following special characters:
|
||||
* <ul>
|
||||
* <li>%b: the base of the source name
|
||||
* <li>%f: the source name (full absolute path)
|
||||
* <li>%l: the line number of the diagnostic, derived from the character offset
|
||||
* <li>%c: the column number of the diagnostic, derived from the character offset
|
||||
* <li>%o: the character offset of the diagnostic if set
|
||||
* <li>%p: the prefix for the diagnostic, derived from the diagnostic type
|
||||
* <li>%t: the prefix as it normally appears in standard diagnostics. In this case, no prefix is
|
||||
* shown if the type is ERROR and if a source name is set
|
||||
* <li>%m: the text or the diagnostic, including any appropriate arguments
|
||||
* <li>%_: space delimiter, useful for formatting purposes
|
||||
* </ul>
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class BasicDiagnosticFormatter extends AbstractDiagnosticFormatter {
|
||||
|
||||
/**
|
||||
* Create a basic formatter based on the supplied options.
|
||||
*
|
||||
* @param options list of command-line options
|
||||
* @param msgs JavacMessages object used for i18n
|
||||
*/
|
||||
public BasicDiagnosticFormatter(Options options, JavacMessages msgs) {
|
||||
super(msgs, new BasicConfiguration(options));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a standard basic formatter
|
||||
*
|
||||
* @param msgs JavacMessages object used for i18n
|
||||
*/
|
||||
public BasicDiagnosticFormatter(JavacMessages msgs) {
|
||||
super(msgs, new BasicConfiguration());
|
||||
}
|
||||
|
||||
public String formatDiagnostic(JCDiagnostic d, Locale l) {
|
||||
if (l == null)
|
||||
l = messages.getCurrentLocale();
|
||||
String format = selectFormat(d);
|
||||
StringBuilder buf = new StringBuilder();
|
||||
for (int i = 0; i < format.length(); i++) {
|
||||
char c = format.charAt(i);
|
||||
boolean meta = false;
|
||||
if (c == '%' && i < format.length() - 1) {
|
||||
meta = true;
|
||||
c = format.charAt(++i);
|
||||
}
|
||||
buf.append(meta ? formatMeta(c, d, l) : String.valueOf(c));
|
||||
}
|
||||
if (depth == 0)
|
||||
return addSourceLineIfNeeded(d, buf.toString());
|
||||
else
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public String formatMessage(JCDiagnostic d, Locale l) {
|
||||
int currentIndentation = 0;
|
||||
StringBuilder buf = new StringBuilder();
|
||||
Collection<String> args = formatArguments(d, l);
|
||||
String msg = localize(l, d.getCode(), args.toArray());
|
||||
String[] lines = msg.split("\n");
|
||||
if (getConfiguration().getVisible().contains(DiagnosticPart.SUMMARY)) {
|
||||
currentIndentation += getConfiguration().getIndentation(DiagnosticPart.SUMMARY);
|
||||
buf.append(indent(lines[0], currentIndentation)); //summary
|
||||
}
|
||||
if (lines.length > 1 && getConfiguration().getVisible().contains(DiagnosticPart.DETAILS)) {
|
||||
currentIndentation += getConfiguration().getIndentation(DiagnosticPart.DETAILS);
|
||||
for (int i = 1;i < lines.length; i++) {
|
||||
buf.append("\n" + indent(lines[i], currentIndentation));
|
||||
}
|
||||
}
|
||||
if (d.isMultiline() && getConfiguration().getVisible().contains(DiagnosticPart.SUBDIAGNOSTICS)) {
|
||||
currentIndentation += getConfiguration().getIndentation(DiagnosticPart.SUBDIAGNOSTICS);
|
||||
for (String sub : formatSubdiagnostics(d, l)) {
|
||||
buf.append("\n" + indent(sub, currentIndentation));
|
||||
}
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
protected String addSourceLineIfNeeded(JCDiagnostic d, String msg) {
|
||||
if (!displaySource(d))
|
||||
return msg;
|
||||
else {
|
||||
BasicConfiguration conf = getConfiguration();
|
||||
int indentSource = conf.getIndentation(DiagnosticPart.SOURCE);
|
||||
String sourceLine = "\n" + formatSourceLine(d, indentSource);
|
||||
boolean singleLine = msg.indexOf("\n") == -1;
|
||||
if (singleLine || getConfiguration().getSourcePosition() == SourcePosition.BOTTOM)
|
||||
return msg + sourceLine;
|
||||
else
|
||||
return msg.replaceFirst("\n", Matcher.quoteReplacement(sourceLine) + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
protected String formatMeta(char c, JCDiagnostic d, Locale l) {
|
||||
switch (c) {
|
||||
case 'b':
|
||||
return formatSource(d, false, l);
|
||||
case 'e':
|
||||
return formatPosition(d, END, l);
|
||||
case 'f':
|
||||
return formatSource(d, true, l);
|
||||
case 'l':
|
||||
return formatPosition(d, LINE, l);
|
||||
case 'c':
|
||||
return formatPosition(d, COLUMN, l);
|
||||
case 'o':
|
||||
return formatPosition(d, OFFSET, l);
|
||||
case 'p':
|
||||
return formatKind(d, l);
|
||||
case 's':
|
||||
return formatPosition(d, START, l);
|
||||
case 't': {
|
||||
boolean usePrefix;
|
||||
switch (d.getType()) {
|
||||
case FRAGMENT:
|
||||
usePrefix = false;
|
||||
break;
|
||||
case ERROR:
|
||||
usePrefix = (d.getIntPosition() == Position.NOPOS);
|
||||
break;
|
||||
default:
|
||||
usePrefix = true;
|
||||
}
|
||||
if (usePrefix)
|
||||
return formatKind(d, l);
|
||||
else
|
||||
return "";
|
||||
}
|
||||
case 'm':
|
||||
return formatMessage(d, l);
|
||||
case 'L':
|
||||
return formatLintCategory(d, l);
|
||||
case '_':
|
||||
return " ";
|
||||
case '%':
|
||||
return "%";
|
||||
default:
|
||||
return String.valueOf(c);
|
||||
}
|
||||
}
|
||||
|
||||
private String selectFormat(JCDiagnostic d) {
|
||||
DiagnosticSource source = d.getDiagnosticSource();
|
||||
String format = getConfiguration().getFormat(BasicFormatKind.DEFAULT_NO_POS_FORMAT);
|
||||
if (source != null && source != DiagnosticSource.NO_SOURCE) {
|
||||
if (d.getIntPosition() != Position.NOPOS) {
|
||||
format = getConfiguration().getFormat(BasicFormatKind.DEFAULT_POS_FORMAT);
|
||||
} else if (source.getFile() != null &&
|
||||
source.getFile().getKind() == JavaFileObject.Kind.CLASS) {
|
||||
format = getConfiguration().getFormat(BasicFormatKind.DEFAULT_CLASS_FORMAT);
|
||||
}
|
||||
}
|
||||
return format;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicConfiguration getConfiguration() {
|
||||
//the following cast is always safe - see init
|
||||
return (BasicConfiguration)super.getConfiguration();
|
||||
}
|
||||
|
||||
static public class BasicConfiguration extends SimpleConfiguration {
|
||||
|
||||
protected Map<DiagnosticPart, Integer> indentationLevels;
|
||||
protected Map<BasicFormatKind, String> availableFormats;
|
||||
protected SourcePosition sourcePosition;
|
||||
|
||||
@SuppressWarnings("fallthrough")
|
||||
public BasicConfiguration(Options options) {
|
||||
super(options, EnumSet.of(DiagnosticPart.SUMMARY,
|
||||
DiagnosticPart.DETAILS,
|
||||
DiagnosticPart.SUBDIAGNOSTICS,
|
||||
DiagnosticPart.SOURCE));
|
||||
initFormat();
|
||||
initIndentation();
|
||||
if (options.isSet("oldDiags"))
|
||||
initOldFormat();
|
||||
String fmt = options.get("diagsFormat");
|
||||
if (fmt != null) {
|
||||
if (fmt.equals("OLD"))
|
||||
initOldFormat();
|
||||
else
|
||||
initFormats(fmt);
|
||||
}
|
||||
String srcPos = null;
|
||||
if ((((srcPos = options.get("sourcePosition")) != null)) &&
|
||||
srcPos.equals("bottom"))
|
||||
setSourcePosition(SourcePosition.BOTTOM);
|
||||
else
|
||||
setSourcePosition(SourcePosition.AFTER_SUMMARY);
|
||||
String indent = options.get("diagsIndentation");
|
||||
if (indent != null) {
|
||||
String[] levels = indent.split("\\|");
|
||||
try {
|
||||
switch (levels.length) {
|
||||
case 5:
|
||||
setIndentation(DiagnosticPart.JLS,
|
||||
Integer.parseInt(levels[4]));
|
||||
case 4:
|
||||
setIndentation(DiagnosticPart.SUBDIAGNOSTICS,
|
||||
Integer.parseInt(levels[3]));
|
||||
case 3:
|
||||
setIndentation(DiagnosticPart.SOURCE,
|
||||
Integer.parseInt(levels[2]));
|
||||
case 2:
|
||||
setIndentation(DiagnosticPart.DETAILS,
|
||||
Integer.parseInt(levels[1]));
|
||||
default:
|
||||
setIndentation(DiagnosticPart.SUMMARY,
|
||||
Integer.parseInt(levels[0]));
|
||||
}
|
||||
}
|
||||
catch (NumberFormatException ex) {
|
||||
initIndentation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public BasicConfiguration() {
|
||||
super(EnumSet.of(DiagnosticPart.SUMMARY,
|
||||
DiagnosticPart.DETAILS,
|
||||
DiagnosticPart.SUBDIAGNOSTICS,
|
||||
DiagnosticPart.SOURCE));
|
||||
initFormat();
|
||||
initIndentation();
|
||||
}
|
||||
|
||||
private void initFormat() {
|
||||
initFormats("%f:%l:%_%p%L%m", "%p%L%m", "%f:%_%p%L%m");
|
||||
}
|
||||
|
||||
private void initOldFormat() {
|
||||
initFormats("%f:%l:%_%t%L%m", "%p%L%m", "%f:%_%t%L%m");
|
||||
}
|
||||
|
||||
private void initFormats(String pos, String nopos, String clazz) {
|
||||
availableFormats = new EnumMap<BasicFormatKind, String>(BasicFormatKind.class);
|
||||
setFormat(BasicFormatKind.DEFAULT_POS_FORMAT, pos);
|
||||
setFormat(BasicFormatKind.DEFAULT_NO_POS_FORMAT, nopos);
|
||||
setFormat(BasicFormatKind.DEFAULT_CLASS_FORMAT, clazz);
|
||||
}
|
||||
|
||||
@SuppressWarnings("fallthrough")
|
||||
private void initFormats(String fmt) {
|
||||
String[] formats = fmt.split("\\|");
|
||||
switch (formats.length) {
|
||||
case 3:
|
||||
setFormat(BasicFormatKind.DEFAULT_CLASS_FORMAT, formats[2]);
|
||||
case 2:
|
||||
setFormat(BasicFormatKind.DEFAULT_NO_POS_FORMAT, formats[1]);
|
||||
default:
|
||||
setFormat(BasicFormatKind.DEFAULT_POS_FORMAT, formats[0]);
|
||||
}
|
||||
}
|
||||
|
||||
private void initIndentation() {
|
||||
indentationLevels = new HashMap<DiagnosticPart, Integer>();
|
||||
setIndentation(DiagnosticPart.SUMMARY, 0);
|
||||
setIndentation(DiagnosticPart.DETAILS, DetailsInc);
|
||||
setIndentation(DiagnosticPart.SUBDIAGNOSTICS, DiagInc);
|
||||
setIndentation(DiagnosticPart.SOURCE, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the amount of spaces for a given indentation kind
|
||||
* @param diagPart the diagnostic part for which the indentation is
|
||||
* to be retrieved
|
||||
* @return the amount of spaces used for the specified indentation kind
|
||||
*/
|
||||
public int getIndentation(DiagnosticPart diagPart) {
|
||||
return indentationLevels.get(diagPart);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the indentation level for various element of a given diagnostic -
|
||||
* this might lead to more readable diagnostics
|
||||
*
|
||||
* @param diagPart
|
||||
* @param nSpaces amount of spaces for the specified diagnostic part
|
||||
*/
|
||||
public void setIndentation(DiagnosticPart diagPart, int nSpaces) {
|
||||
indentationLevels.put(diagPart, nSpaces);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the source line positioning used by this formatter
|
||||
*
|
||||
* @param sourcePos a positioning value for source line
|
||||
*/
|
||||
public void setSourcePosition(SourcePosition sourcePos) {
|
||||
sourcePosition = sourcePos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the source line positioning used by this formatter
|
||||
*
|
||||
* @return the positioning value used by this formatter
|
||||
*/
|
||||
public SourcePosition getSourcePosition() {
|
||||
return sourcePosition;
|
||||
}
|
||||
//where
|
||||
/**
|
||||
* A source positioning value controls the position (within a given
|
||||
* diagnostic message) in which the source line the diagnostic refers to
|
||||
* should be displayed (if applicable)
|
||||
*/
|
||||
public enum SourcePosition {
|
||||
/**
|
||||
* Source line is displayed after the diagnostic message
|
||||
*/
|
||||
BOTTOM,
|
||||
/**
|
||||
* Source line is displayed after the first line of the diagnostic
|
||||
* message
|
||||
*/
|
||||
AFTER_SUMMARY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a metachar string for a specific format
|
||||
*
|
||||
* @param kind the format kind to be set
|
||||
* @param s the metachar string specifying the format
|
||||
*/
|
||||
public void setFormat(BasicFormatKind kind, String s) {
|
||||
availableFormats.put(kind, s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a metachar string for a specific format
|
||||
*
|
||||
* @param kind the format kind for which to get the metachar string
|
||||
*/
|
||||
public String getFormat(BasicFormatKind kind) {
|
||||
return availableFormats.get(kind);
|
||||
}
|
||||
//where
|
||||
/**
|
||||
* This enum contains all the kinds of formatting patterns supported
|
||||
* by a basic diagnostic formatter.
|
||||
*/
|
||||
public enum BasicFormatKind {
|
||||
/**
|
||||
* A format string to be used for diagnostics with a given position.
|
||||
*/
|
||||
DEFAULT_POS_FORMAT,
|
||||
/**
|
||||
* A format string to be used for diagnostics without a given position.
|
||||
*/
|
||||
DEFAULT_NO_POS_FORMAT,
|
||||
/**
|
||||
* A format string to be used for diagnostics regarding classfiles
|
||||
*/
|
||||
DEFAULT_CLASS_FORMAT;
|
||||
}
|
||||
}
|
||||
}
|
||||
369
jdkSrc/jdk8/com/sun/tools/javac/util/Bits.java
Normal file
369
jdkSrc/jdk8/com/sun/tools/javac/util/Bits.java
Normal file
@@ -0,0 +1,369 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/** A class for extensible, mutable bit sets.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class Bits {
|
||||
|
||||
// ____________ reset _________
|
||||
// / UNKNOWN \ <-------- / UNINIT \
|
||||
// \____________/ | \_________/
|
||||
// | | |
|
||||
// |assign | | any
|
||||
// | ___________ |
|
||||
// ------> / NORMAL \ <----
|
||||
// \___________/ |
|
||||
// | |
|
||||
// | |
|
||||
// -----------
|
||||
// any
|
||||
protected enum BitsState {
|
||||
/* A Bits instance is in UNKNOWN state if it has been explicitly reset.
|
||||
* It is possible to get to this state from any other by calling the
|
||||
* reset method. An instance in the UNKNOWN state can pass to the
|
||||
* NORMAL state after being assigned another Bits instance.
|
||||
*
|
||||
* Bits instances are final fields in Flow so the UNKNOWN state models
|
||||
* the null assignment.
|
||||
*/
|
||||
UNKNOWN,
|
||||
/* A Bits instance is in UNINIT when it is created with the default
|
||||
* constructor but it isn't explicitly reset. The main objective of this
|
||||
* internal state is to save some memory.
|
||||
*/
|
||||
UNINIT,
|
||||
/* The normal state is reached after creating a Bits instance from an
|
||||
* existing one or after applying any operation to an instance on UNINIT
|
||||
* or NORMAL state. From this state a bits instance can pass to the
|
||||
* UNKNOWN state by calling the reset method.
|
||||
*/
|
||||
NORMAL;
|
||||
|
||||
static BitsState getState(int[] someBits, boolean reset) {
|
||||
if (reset) {
|
||||
return UNKNOWN;
|
||||
} else {
|
||||
if (someBits != unassignedBits) {
|
||||
return NORMAL;
|
||||
} else {
|
||||
return UNINIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final static int wordlen = 32;
|
||||
private final static int wordshift = 5;
|
||||
private final static int wordmask = wordlen - 1;
|
||||
|
||||
public int[] bits = null;
|
||||
// This field will store last version of bits after every change.
|
||||
private static final int[] unassignedBits = new int[0];
|
||||
|
||||
protected BitsState currentState;
|
||||
|
||||
/** Construct an initially empty set.
|
||||
*/
|
||||
public Bits() {
|
||||
this(false);
|
||||
}
|
||||
|
||||
public Bits(Bits someBits) {
|
||||
this(someBits.dup().bits, BitsState.getState(someBits.bits, false));
|
||||
}
|
||||
|
||||
public Bits(boolean reset) {
|
||||
this(unassignedBits, BitsState.getState(unassignedBits, reset));
|
||||
}
|
||||
|
||||
/** Construct a set consisting initially of given bit vector.
|
||||
*/
|
||||
protected Bits(int[] bits, BitsState initState) {
|
||||
this.bits = bits;
|
||||
this.currentState = initState;
|
||||
switch (initState) {
|
||||
case UNKNOWN:
|
||||
this.bits = null;
|
||||
break;
|
||||
case NORMAL:
|
||||
Assert.check(bits != unassignedBits);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected void sizeTo(int len) {
|
||||
if (bits.length < len) {
|
||||
bits = Arrays.copyOf(bits, len);
|
||||
}
|
||||
}
|
||||
|
||||
/** This set = {}.
|
||||
*/
|
||||
public void clear() {
|
||||
Assert.check(currentState != BitsState.UNKNOWN);
|
||||
for (int i = 0; i < bits.length; i++) {
|
||||
bits[i] = 0;
|
||||
}
|
||||
currentState = BitsState.NORMAL;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
internalReset();
|
||||
}
|
||||
|
||||
protected void internalReset() {
|
||||
bits = null;
|
||||
currentState = BitsState.UNKNOWN;
|
||||
}
|
||||
|
||||
public boolean isReset() {
|
||||
return currentState == BitsState.UNKNOWN;
|
||||
}
|
||||
|
||||
public Bits assign(Bits someBits) {
|
||||
bits = someBits.dup().bits;
|
||||
currentState = BitsState.NORMAL;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Return a copy of this set.
|
||||
*/
|
||||
public Bits dup() {
|
||||
Assert.check(currentState != BitsState.UNKNOWN);
|
||||
Bits tmp = new Bits();
|
||||
tmp.bits = dupBits();
|
||||
currentState = BitsState.NORMAL;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
protected int[] dupBits() {
|
||||
int [] result;
|
||||
if (currentState != BitsState.NORMAL) {
|
||||
result = bits;
|
||||
} else {
|
||||
result = new int[bits.length];
|
||||
System.arraycopy(bits, 0, result, 0, bits.length);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Include x in this set.
|
||||
*/
|
||||
public void incl(int x) {
|
||||
Assert.check(currentState != BitsState.UNKNOWN);
|
||||
Assert.check(x >= 0, "Value of x " + x);
|
||||
sizeTo((x >>> wordshift) + 1);
|
||||
bits[x >>> wordshift] = bits[x >>> wordshift] |
|
||||
(1 << (x & wordmask));
|
||||
currentState = BitsState.NORMAL;
|
||||
}
|
||||
|
||||
|
||||
/** Include [start..limit) in this set.
|
||||
*/
|
||||
public void inclRange(int start, int limit) {
|
||||
Assert.check(currentState != BitsState.UNKNOWN);
|
||||
sizeTo((limit >>> wordshift) + 1);
|
||||
for (int x = start; x < limit; x++) {
|
||||
bits[x >>> wordshift] = bits[x >>> wordshift] |
|
||||
(1 << (x & wordmask));
|
||||
}
|
||||
currentState = BitsState.NORMAL;
|
||||
}
|
||||
|
||||
/** Exclude [start...end] from this set.
|
||||
*/
|
||||
public void excludeFrom(int start) {
|
||||
Assert.check(currentState != BitsState.UNKNOWN);
|
||||
Bits temp = new Bits();
|
||||
temp.sizeTo(bits.length);
|
||||
temp.inclRange(0, start);
|
||||
internalAndSet(temp);
|
||||
currentState = BitsState.NORMAL;
|
||||
}
|
||||
|
||||
/** Exclude x from this set.
|
||||
*/
|
||||
public void excl(int x) {
|
||||
Assert.check(currentState != BitsState.UNKNOWN);
|
||||
Assert.check(x >= 0);
|
||||
sizeTo((x >>> wordshift) + 1);
|
||||
bits[x >>> wordshift] = bits[x >>> wordshift] &
|
||||
~(1 << (x & wordmask));
|
||||
currentState = BitsState.NORMAL;
|
||||
}
|
||||
|
||||
/** Is x an element of this set?
|
||||
*/
|
||||
public boolean isMember(int x) {
|
||||
Assert.check(currentState != BitsState.UNKNOWN);
|
||||
return
|
||||
0 <= x && x < (bits.length << wordshift) &&
|
||||
(bits[x >>> wordshift] & (1 << (x & wordmask))) != 0;
|
||||
}
|
||||
|
||||
/** {@literal this set = this set & xs}.
|
||||
*/
|
||||
public Bits andSet(Bits xs) {
|
||||
Assert.check(currentState != BitsState.UNKNOWN);
|
||||
internalAndSet(xs);
|
||||
currentState = BitsState.NORMAL;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected void internalAndSet(Bits xs) {
|
||||
Assert.check(currentState != BitsState.UNKNOWN);
|
||||
sizeTo(xs.bits.length);
|
||||
for (int i = 0; i < xs.bits.length; i++) {
|
||||
bits[i] = bits[i] & xs.bits[i];
|
||||
}
|
||||
}
|
||||
|
||||
/** this set = this set | xs.
|
||||
*/
|
||||
public Bits orSet(Bits xs) {
|
||||
Assert.check(currentState != BitsState.UNKNOWN);
|
||||
sizeTo(xs.bits.length);
|
||||
for (int i = 0; i < xs.bits.length; i++) {
|
||||
bits[i] = bits[i] | xs.bits[i];
|
||||
}
|
||||
currentState = BitsState.NORMAL;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** this set = this set \ xs.
|
||||
*/
|
||||
public Bits diffSet(Bits xs) {
|
||||
Assert.check(currentState != BitsState.UNKNOWN);
|
||||
for (int i = 0; i < bits.length; i++) {
|
||||
if (i < xs.bits.length) {
|
||||
bits[i] = bits[i] & ~xs.bits[i];
|
||||
}
|
||||
}
|
||||
currentState = BitsState.NORMAL;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** this set = this set ^ xs.
|
||||
*/
|
||||
public Bits xorSet(Bits xs) {
|
||||
Assert.check(currentState != BitsState.UNKNOWN);
|
||||
sizeTo(xs.bits.length);
|
||||
for (int i = 0; i < xs.bits.length; i++) {
|
||||
bits[i] = bits[i] ^ xs.bits[i];
|
||||
}
|
||||
currentState = BitsState.NORMAL;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Count trailing zero bits in an int. Algorithm from "Hacker's
|
||||
* Delight" by Henry S. Warren Jr. (figure 5-13)
|
||||
*/
|
||||
private static int trailingZeroBits(int x) {
|
||||
Assert.check(wordlen == 32);
|
||||
if (x == 0) {
|
||||
return 32;
|
||||
}
|
||||
int n = 1;
|
||||
if ((x & 0xffff) == 0) { n += 16; x >>>= 16; }
|
||||
if ((x & 0x00ff) == 0) { n += 8; x >>>= 8; }
|
||||
if ((x & 0x000f) == 0) { n += 4; x >>>= 4; }
|
||||
if ((x & 0x0003) == 0) { n += 2; x >>>= 2; }
|
||||
return n - (x&1);
|
||||
}
|
||||
|
||||
/** Return the index of the least bit position ≥ x that is set.
|
||||
* If none are set, returns -1. This provides a nice way to iterate
|
||||
* over the members of a bit set:
|
||||
* <pre>{@code
|
||||
* for (int i = bits.nextBit(0); i>=0; i = bits.nextBit(i+1)) ...
|
||||
* }</pre>
|
||||
*/
|
||||
public int nextBit(int x) {
|
||||
Assert.check(currentState != BitsState.UNKNOWN);
|
||||
int windex = x >>> wordshift;
|
||||
if (windex >= bits.length) {
|
||||
return -1;
|
||||
}
|
||||
int word = bits[windex] & ~((1 << (x & wordmask))-1);
|
||||
while (true) {
|
||||
if (word != 0) {
|
||||
return (windex << wordshift) + trailingZeroBits(word);
|
||||
}
|
||||
windex++;
|
||||
if (windex >= bits.length) {
|
||||
return -1;
|
||||
}
|
||||
word = bits[windex];
|
||||
}
|
||||
}
|
||||
|
||||
/** a string representation of this set.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
if (bits != null && bits.length > 0) {
|
||||
char[] digits = new char[bits.length * wordlen];
|
||||
for (int i = 0; i < bits.length * wordlen; i++) {
|
||||
digits[i] = isMember(i) ? '1' : '0';
|
||||
}
|
||||
return new String(digits);
|
||||
} else {
|
||||
return "[]";
|
||||
}
|
||||
}
|
||||
|
||||
/** Test Bits.nextBit(int). */
|
||||
public static void main(String[] args) {
|
||||
java.util.Random r = new java.util.Random();
|
||||
Bits bits = new Bits();
|
||||
for (int i=0; i<125; i++) {
|
||||
int k;
|
||||
do {
|
||||
k = r.nextInt(250);
|
||||
} while (bits.isMember(k));
|
||||
System.out.println("adding " + k);
|
||||
bits.incl(k);
|
||||
}
|
||||
int count = 0;
|
||||
for (int i = bits.nextBit(0); i >= 0; i = bits.nextBit(i+1)) {
|
||||
System.out.println("found " + i);
|
||||
count ++;
|
||||
}
|
||||
if (count != 125) {
|
||||
throw new Error();
|
||||
}
|
||||
}
|
||||
}
|
||||
161
jdkSrc/jdk8/com/sun/tools/javac/util/ByteBuffer.java
Normal file
161
jdkSrc/jdk8/com/sun/tools/javac/util/ByteBuffer.java
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/** A byte buffer is a flexible array which grows when elements are
|
||||
* appended. There are also methods to append names to byte buffers
|
||||
* and to convert byte buffers to names.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class ByteBuffer {
|
||||
|
||||
/** An array holding the bytes in this buffer; can be grown.
|
||||
*/
|
||||
public byte[] elems;
|
||||
|
||||
/** The current number of defined bytes in this buffer.
|
||||
*/
|
||||
public int length;
|
||||
|
||||
/** Create a new byte buffer.
|
||||
*/
|
||||
public ByteBuffer() {
|
||||
this(64);
|
||||
}
|
||||
|
||||
/** Create a new byte buffer with an initial elements array
|
||||
* of given size.
|
||||
*/
|
||||
public ByteBuffer(int initialSize) {
|
||||
elems = new byte[initialSize];
|
||||
length = 0;
|
||||
}
|
||||
|
||||
/** Append byte to this buffer.
|
||||
*/
|
||||
public void appendByte(int b) {
|
||||
elems = ArrayUtils.ensureCapacity(elems, length);
|
||||
elems[length++] = (byte)b;
|
||||
}
|
||||
|
||||
/** Append `len' bytes from byte array,
|
||||
* starting at given `start' offset.
|
||||
*/
|
||||
public void appendBytes(byte[] bs, int start, int len) {
|
||||
elems = ArrayUtils.ensureCapacity(elems, length + len);
|
||||
System.arraycopy(bs, start, elems, length, len);
|
||||
length += len;
|
||||
}
|
||||
|
||||
/** Append all bytes from given byte array.
|
||||
*/
|
||||
public void appendBytes(byte[] bs) {
|
||||
appendBytes(bs, 0, bs.length);
|
||||
}
|
||||
|
||||
/** Append a character as a two byte number.
|
||||
*/
|
||||
public void appendChar(int x) {
|
||||
elems = ArrayUtils.ensureCapacity(elems, length + 1);
|
||||
elems[length ] = (byte)((x >> 8) & 0xFF);
|
||||
elems[length+1] = (byte)((x ) & 0xFF);
|
||||
length = length + 2;
|
||||
}
|
||||
|
||||
/** Append an integer as a four byte number.
|
||||
*/
|
||||
public void appendInt(int x) {
|
||||
elems = ArrayUtils.ensureCapacity(elems, length + 3);
|
||||
elems[length ] = (byte)((x >> 24) & 0xFF);
|
||||
elems[length+1] = (byte)((x >> 16) & 0xFF);
|
||||
elems[length+2] = (byte)((x >> 8) & 0xFF);
|
||||
elems[length+3] = (byte)((x ) & 0xFF);
|
||||
length = length + 4;
|
||||
}
|
||||
|
||||
/** Append a long as an eight byte number.
|
||||
*/
|
||||
public void appendLong(long x) {
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream(8);
|
||||
DataOutputStream bufout = new DataOutputStream(buffer);
|
||||
try {
|
||||
bufout.writeLong(x);
|
||||
appendBytes(buffer.toByteArray(), 0, 8);
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError("write");
|
||||
}
|
||||
}
|
||||
|
||||
/** Append a float as a four byte number.
|
||||
*/
|
||||
public void appendFloat(float x) {
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream(4);
|
||||
DataOutputStream bufout = new DataOutputStream(buffer);
|
||||
try {
|
||||
bufout.writeFloat(x);
|
||||
appendBytes(buffer.toByteArray(), 0, 4);
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError("write");
|
||||
}
|
||||
}
|
||||
|
||||
/** Append a double as a eight byte number.
|
||||
*/
|
||||
public void appendDouble(double x) {
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream(8);
|
||||
DataOutputStream bufout = new DataOutputStream(buffer);
|
||||
try {
|
||||
bufout.writeDouble(x);
|
||||
appendBytes(buffer.toByteArray(), 0, 8);
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError("write");
|
||||
}
|
||||
}
|
||||
|
||||
/** Append a name.
|
||||
*/
|
||||
public void appendName(Name name) {
|
||||
appendBytes(name.getByteArray(), name.getByteOffset(), name.getByteLength());
|
||||
}
|
||||
|
||||
/** Reset to zero length.
|
||||
*/
|
||||
public void reset() {
|
||||
length = 0;
|
||||
}
|
||||
|
||||
/** Convert contents to name.
|
||||
*/
|
||||
public Name toName(Names names) {
|
||||
return names.fromUtf(elems, 0, length);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
/**
|
||||
* An exception used for propogating exceptions found in client code
|
||||
* invoked from javac.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class ClientCodeException extends RuntimeException {
|
||||
|
||||
static final long serialVersionUID = -5674494409392415163L;
|
||||
|
||||
public ClientCodeException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
137
jdkSrc/jdk8/com/sun/tools/javac/util/Constants.java
Normal file
137
jdkSrc/jdk8/com/sun/tools/javac/util/Constants.java
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import com.sun.tools.javac.code.Type;
|
||||
|
||||
/**
|
||||
* Utilities for operating on constant values.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class Constants {
|
||||
|
||||
/**
|
||||
* Converts a constant in internal representation (in which
|
||||
* boolean, char, byte, short, and int are each represented by an
|
||||
* Integer) into standard representation. Other values (including
|
||||
* null) are returned unchanged.
|
||||
*/
|
||||
public static Object decode(Object value, Type type) {
|
||||
if (value instanceof Integer) {
|
||||
int i = (Integer) value;
|
||||
switch (type.getTag()) {
|
||||
case BOOLEAN: return i != 0;
|
||||
case CHAR: return (char) i;
|
||||
case BYTE: return (byte) i;
|
||||
case SHORT: return (short) i;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of a constant value (given in
|
||||
* internal representation), quoted and formatted as in Java source.
|
||||
*/
|
||||
public static String format(Object value, Type type) {
|
||||
value = decode(value, type);
|
||||
switch (type.getTag()) {
|
||||
case BYTE: return formatByte((Byte) value);
|
||||
case LONG: return formatLong((Long) value);
|
||||
case FLOAT: return formatFloat((Float) value);
|
||||
case DOUBLE: return formatDouble((Double) value);
|
||||
case CHAR: return formatChar((Character) value);
|
||||
}
|
||||
if (value instanceof String)
|
||||
return formatString((String) value);
|
||||
return value + "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of a constant value (given in
|
||||
* standard wrapped representation), quoted and formatted as in
|
||||
* Java source.
|
||||
*/
|
||||
public static String format(Object value) {
|
||||
if (value instanceof Byte) return formatByte((Byte) value);
|
||||
if (value instanceof Short) return formatShort((Short) value);
|
||||
if (value instanceof Long) return formatLong((Long) value);
|
||||
if (value instanceof Float) return formatFloat((Float) value);
|
||||
if (value instanceof Double) return formatDouble((Double) value);
|
||||
if (value instanceof Character) return formatChar((Character) value);
|
||||
if (value instanceof String) return formatString((String) value);
|
||||
if (value instanceof Integer ||
|
||||
value instanceof Boolean) return value.toString();
|
||||
else
|
||||
throw new IllegalArgumentException("Argument is not a primitive type or a string; it " +
|
||||
((value == null) ?
|
||||
"is a null value." :
|
||||
"has class " +
|
||||
value.getClass().getName()) + "." );
|
||||
}
|
||||
|
||||
private static String formatByte(byte b) {
|
||||
return String.format("(byte)0x%02x", b);
|
||||
}
|
||||
|
||||
private static String formatShort(short s) {
|
||||
return String.format("(short)%d", s);
|
||||
}
|
||||
|
||||
private static String formatLong(long lng) {
|
||||
return lng + "L";
|
||||
}
|
||||
|
||||
private static String formatFloat(float f) {
|
||||
if (Float.isNaN(f))
|
||||
return "0.0f/0.0f";
|
||||
else if (Float.isInfinite(f))
|
||||
return (f < 0) ? "-1.0f/0.0f" : "1.0f/0.0f";
|
||||
else
|
||||
return f + "f";
|
||||
}
|
||||
|
||||
private static String formatDouble(double d) {
|
||||
if (Double.isNaN(d))
|
||||
return "0.0/0.0";
|
||||
else if (Double.isInfinite(d))
|
||||
return (d < 0) ? "-1.0/0.0" : "1.0/0.0";
|
||||
else
|
||||
return d + "";
|
||||
}
|
||||
|
||||
private static String formatChar(char c) {
|
||||
return '\'' + Convert.quote(c) + '\'';
|
||||
}
|
||||
|
||||
private static String formatString(String s) {
|
||||
return '"' + Convert.quote(s) + '"';
|
||||
}
|
||||
}
|
||||
227
jdkSrc/jdk8/com/sun/tools/javac/util/Context.java
Normal file
227
jdkSrc/jdk8/com/sun/tools/javac/util/Context.java
Normal file
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Support for an abstract context, modelled loosely after ThreadLocal
|
||||
* but using a user-provided context instead of the current thread.
|
||||
*
|
||||
* <p>Within the compiler, a single Context is used for each
|
||||
* invocation of the compiler. The context is then used to ensure a
|
||||
* single copy of each compiler phase exists per compiler invocation.
|
||||
*
|
||||
* <p>The context can be used to assist in extending the compiler by
|
||||
* extending its components. To do that, the extended component must
|
||||
* be registered before the base component. We break initialization
|
||||
* cycles by (1) registering a factory for the component rather than
|
||||
* the component itself, and (2) a convention for a pattern of usage
|
||||
* in which each base component registers itself by calling an
|
||||
* instance method that is overridden in extended components. A base
|
||||
* phase supporting extension would look something like this:
|
||||
*
|
||||
* <p><pre>{@code
|
||||
* public class Phase {
|
||||
* protected static final Context.Key<Phase> phaseKey =
|
||||
* new Context.Key<Phase>();
|
||||
*
|
||||
* public static Phase instance(Context context) {
|
||||
* Phase instance = context.get(phaseKey);
|
||||
* if (instance == null)
|
||||
* // the phase has not been overridden
|
||||
* instance = new Phase(context);
|
||||
* return instance;
|
||||
* }
|
||||
*
|
||||
* protected Phase(Context context) {
|
||||
* context.put(phaseKey, this);
|
||||
* // other intitialization follows...
|
||||
* }
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>In the compiler, we simply use Phase.instance(context) to get
|
||||
* the reference to the phase. But in extensions of the compiler, we
|
||||
* must register extensions of the phases to replace the base phase,
|
||||
* and this must be done before any reference to the phase is accessed
|
||||
* using Phase.instance(). An extended phase might be declared thus:
|
||||
*
|
||||
* <p><pre>{@code
|
||||
* public class NewPhase extends Phase {
|
||||
* protected NewPhase(Context context) {
|
||||
* super(context);
|
||||
* }
|
||||
* public static void preRegister(final Context context) {
|
||||
* context.put(phaseKey, new Context.Factory<Phase>() {
|
||||
* public Phase make() {
|
||||
* return new NewPhase(context);
|
||||
* }
|
||||
* });
|
||||
* }
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>And is registered early in the extended compiler like this
|
||||
*
|
||||
* <p><pre>
|
||||
* NewPhase.preRegister(context);
|
||||
* </pre>
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class Context {
|
||||
/** The client creates an instance of this class for each key.
|
||||
*/
|
||||
public static class Key<T> {
|
||||
// note: we inherit identity equality from Object.
|
||||
}
|
||||
|
||||
/**
|
||||
* The client can register a factory for lazy creation of the
|
||||
* instance.
|
||||
*/
|
||||
public static interface Factory<T> {
|
||||
T make(Context c);
|
||||
};
|
||||
|
||||
/**
|
||||
* The underlying map storing the data.
|
||||
* We maintain the invariant that this table contains only
|
||||
* mappings of the form
|
||||
* {@literal Key<T> -> T }
|
||||
* or
|
||||
* {@literal Key<T> -> Factory<T> }
|
||||
*/
|
||||
private Map<Key<?>,Object> ht = new HashMap<Key<?>,Object>();
|
||||
|
||||
/** Set the factory for the key in this context. */
|
||||
public <T> void put(Key<T> key, Factory<T> fac) {
|
||||
checkState(ht);
|
||||
Object old = ht.put(key, fac);
|
||||
if (old != null)
|
||||
throw new AssertionError("duplicate context value");
|
||||
checkState(ft);
|
||||
ft.put(key, fac); // cannot be duplicate if unique in ht
|
||||
}
|
||||
|
||||
/** Set the value for the key in this context. */
|
||||
public <T> void put(Key<T> key, T data) {
|
||||
if (data instanceof Factory<?>)
|
||||
throw new AssertionError("T extends Context.Factory");
|
||||
checkState(ht);
|
||||
Object old = ht.put(key, data);
|
||||
if (old != null && !(old instanceof Factory<?>) && old != data && data != null)
|
||||
throw new AssertionError("duplicate context value");
|
||||
}
|
||||
|
||||
/** Get the value for the key in this context. */
|
||||
public <T> T get(Key<T> key) {
|
||||
checkState(ht);
|
||||
Object o = ht.get(key);
|
||||
if (o instanceof Factory<?>) {
|
||||
Factory<?> fac = (Factory<?>)o;
|
||||
o = fac.make(this);
|
||||
if (o instanceof Factory<?>)
|
||||
throw new AssertionError("T extends Context.Factory");
|
||||
Assert.check(ht.get(key) == o);
|
||||
}
|
||||
|
||||
/* The following cast can't fail unless there was
|
||||
* cheating elsewhere, because of the invariant on ht.
|
||||
* Since we found a key of type Key<T>, the value must
|
||||
* be of type T.
|
||||
*/
|
||||
return Context.<T>uncheckedCast(o);
|
||||
}
|
||||
|
||||
public Context() {}
|
||||
|
||||
/**
|
||||
* The table of preregistered factories.
|
||||
*/
|
||||
private Map<Key<?>,Factory<?>> ft = new HashMap<Key<?>,Factory<?>>();
|
||||
|
||||
public Context(Context prev) {
|
||||
kt.putAll(prev.kt); // retain all implicit keys
|
||||
ft.putAll(prev.ft); // retain all factory objects
|
||||
ht.putAll(prev.ft); // init main table with factories
|
||||
}
|
||||
|
||||
/*
|
||||
* The key table, providing a unique Key<T> for each Class<T>.
|
||||
*/
|
||||
private Map<Class<?>, Key<?>> kt = new HashMap<Class<?>, Key<?>>();
|
||||
|
||||
private <T> Key<T> key(Class<T> clss) {
|
||||
checkState(kt);
|
||||
Key<T> k = uncheckedCast(kt.get(clss));
|
||||
if (k == null) {
|
||||
k = new Key<T>();
|
||||
kt.put(clss, k);
|
||||
}
|
||||
return k;
|
||||
}
|
||||
|
||||
public <T> T get(Class<T> clazz) {
|
||||
return get(key(clazz));
|
||||
}
|
||||
|
||||
public <T> void put(Class<T> clazz, T data) {
|
||||
put(key(clazz), data);
|
||||
}
|
||||
public <T> void put(Class<T> clazz, Factory<T> fac) {
|
||||
put(key(clazz), fac);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: This method should be removed and Context should be made type safe.
|
||||
* This can be accomplished by using class literals as type tokens.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T> T uncheckedCast(Object o) {
|
||||
return (T)o;
|
||||
}
|
||||
|
||||
public void dump() {
|
||||
for (Object value : ht.values())
|
||||
System.err.println(value == null ? null : value.getClass());
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
ht = null;
|
||||
kt = null;
|
||||
ft = null;
|
||||
}
|
||||
|
||||
private static void checkState(Map<?,?> t) {
|
||||
if (t == null)
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
338
jdkSrc/jdk8/com/sun/tools/javac/util/Convert.java
Normal file
338
jdkSrc/jdk8/com/sun/tools/javac/util/Convert.java
Normal file
@@ -0,0 +1,338 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
/** Utility class for static conversion methods between numbers
|
||||
* and strings in various formats.
|
||||
*
|
||||
* <p>Note regarding UTF-8.
|
||||
* The JVMS defines its own version of the UTF-8 format so that it
|
||||
* contains no zero bytes (modified UTF-8). This is not actually the same
|
||||
* as Charset.forName("UTF-8").
|
||||
*
|
||||
* <p>
|
||||
* See also:
|
||||
* <ul>
|
||||
* <li><a href="https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4.7">
|
||||
* JVMS 4.4.7 </a></li>
|
||||
* <li><a href="https://docs.oracle.com/javase/7/docs/api/java/io/DataInput.html#modified-utf-8">
|
||||
java.io.DataInput: Modified UTF-8 </a></li>
|
||||
<li><a href="https://en.wikipedia.org/wiki/UTF-8#Modified_UTF-8">
|
||||
Modified UTF-8 (wikipedia) </a></li>
|
||||
* </ul>
|
||||
*
|
||||
* The methods here support modified UTF-8.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class Convert {
|
||||
|
||||
/** Convert string to integer.
|
||||
*/
|
||||
public static int string2int(String s, int radix)
|
||||
throws NumberFormatException {
|
||||
if (radix == 10) {
|
||||
return Integer.parseInt(s, radix);
|
||||
} else {
|
||||
char[] cs = s.toCharArray();
|
||||
int limit = Integer.MAX_VALUE / (radix/2);
|
||||
int n = 0;
|
||||
for (int i = 0; i < cs.length; i++) {
|
||||
int d = Character.digit(cs[i], radix);
|
||||
if (n < 0 ||
|
||||
n > limit ||
|
||||
n * radix > Integer.MAX_VALUE - d)
|
||||
throw new NumberFormatException();
|
||||
n = n * radix + d;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
/** Convert string to long integer.
|
||||
*/
|
||||
public static long string2long(String s, int radix)
|
||||
throws NumberFormatException {
|
||||
if (radix == 10) {
|
||||
return Long.parseLong(s, radix);
|
||||
} else {
|
||||
char[] cs = s.toCharArray();
|
||||
long limit = Long.MAX_VALUE / (radix/2);
|
||||
long n = 0;
|
||||
for (int i = 0; i < cs.length; i++) {
|
||||
int d = Character.digit(cs[i], radix);
|
||||
if (n < 0 ||
|
||||
n > limit ||
|
||||
n * radix > Long.MAX_VALUE - d)
|
||||
throw new NumberFormatException();
|
||||
n = n * radix + d;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
/* Conversion routines between names, strings, and byte arrays in Utf8 format
|
||||
*/
|
||||
|
||||
/** Convert `len' bytes from utf8 to characters.
|
||||
* Parameters are as in System.arraycopy
|
||||
* Return first index in `dst' past the last copied char.
|
||||
* @param src The array holding the bytes to convert.
|
||||
* @param sindex The start index from which bytes are converted.
|
||||
* @param dst The array holding the converted characters..
|
||||
* @param dindex The start index from which converted characters
|
||||
* are written.
|
||||
* @param len The maximum number of bytes to convert.
|
||||
*/
|
||||
public static int utf2chars(byte[] src, int sindex,
|
||||
char[] dst, int dindex,
|
||||
int len) {
|
||||
int i = sindex;
|
||||
int j = dindex;
|
||||
int limit = sindex + len;
|
||||
while (i < limit) {
|
||||
int b = src[i++] & 0xFF;
|
||||
if (b >= 0xE0) {
|
||||
b = (b & 0x0F) << 12;
|
||||
b = b | (src[i++] & 0x3F) << 6;
|
||||
b = b | (src[i++] & 0x3F);
|
||||
} else if (b >= 0xC0) {
|
||||
b = (b & 0x1F) << 6;
|
||||
b = b | (src[i++] & 0x3F);
|
||||
}
|
||||
dst[j++] = (char)b;
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
/** Return bytes in Utf8 representation as an array of characters.
|
||||
* @param src The array holding the bytes.
|
||||
* @param sindex The start index from which bytes are converted.
|
||||
* @param len The maximum number of bytes to convert.
|
||||
*/
|
||||
public static char[] utf2chars(byte[] src, int sindex, int len) {
|
||||
char[] dst = new char[len];
|
||||
int len1 = utf2chars(src, sindex, dst, 0, len);
|
||||
char[] result = new char[len1];
|
||||
System.arraycopy(dst, 0, result, 0, len1);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Return all bytes of a given array in Utf8 representation
|
||||
* as an array of characters.
|
||||
* @param src The array holding the bytes.
|
||||
*/
|
||||
public static char[] utf2chars(byte[] src) {
|
||||
return utf2chars(src, 0, src.length);
|
||||
}
|
||||
|
||||
/** Return bytes in Utf8 representation as a string.
|
||||
* @param src The array holding the bytes.
|
||||
* @param sindex The start index from which bytes are converted.
|
||||
* @param len The maximum number of bytes to convert.
|
||||
*/
|
||||
public static String utf2string(byte[] src, int sindex, int len) {
|
||||
char dst[] = new char[len];
|
||||
int len1 = utf2chars(src, sindex, dst, 0, len);
|
||||
return new String(dst, 0, len1);
|
||||
}
|
||||
|
||||
/** Return all bytes of a given array in Utf8 representation
|
||||
* as a string.
|
||||
* @param src The array holding the bytes.
|
||||
*/
|
||||
public static String utf2string(byte[] src) {
|
||||
return utf2string(src, 0, src.length);
|
||||
}
|
||||
|
||||
/** Copy characters in source array to bytes in target array,
|
||||
* converting them to Utf8 representation.
|
||||
* The target array must be large enough to hold the result.
|
||||
* returns first index in `dst' past the last copied byte.
|
||||
* @param src The array holding the characters to convert.
|
||||
* @param sindex The start index from which characters are converted.
|
||||
* @param dst The array holding the converted characters..
|
||||
* @param dindex The start index from which converted bytes
|
||||
* are written.
|
||||
* @param len The maximum number of characters to convert.
|
||||
*/
|
||||
public static int chars2utf(char[] src, int sindex,
|
||||
byte[] dst, int dindex,
|
||||
int len) {
|
||||
int j = dindex;
|
||||
int limit = sindex + len;
|
||||
for (int i = sindex; i < limit; i++) {
|
||||
char ch = src[i];
|
||||
if (1 <= ch && ch <= 0x7F) {
|
||||
dst[j++] = (byte)ch;
|
||||
} else if (ch <= 0x7FF) {
|
||||
dst[j++] = (byte)(0xC0 | (ch >> 6));
|
||||
dst[j++] = (byte)(0x80 | (ch & 0x3F));
|
||||
} else {
|
||||
dst[j++] = (byte)(0xE0 | (ch >> 12));
|
||||
dst[j++] = (byte)(0x80 | ((ch >> 6) & 0x3F));
|
||||
dst[j++] = (byte)(0x80 | (ch & 0x3F));
|
||||
}
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
/** Return characters as an array of bytes in Utf8 representation.
|
||||
* @param src The array holding the characters.
|
||||
* @param sindex The start index from which characters are converted.
|
||||
* @param len The maximum number of characters to convert.
|
||||
*/
|
||||
public static byte[] chars2utf(char[] src, int sindex, int len) {
|
||||
byte[] dst = new byte[len * 3];
|
||||
int len1 = chars2utf(src, sindex, dst, 0, len);
|
||||
byte[] result = new byte[len1];
|
||||
System.arraycopy(dst, 0, result, 0, len1);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Return all characters in given array as an array of bytes
|
||||
* in Utf8 representation.
|
||||
* @param src The array holding the characters.
|
||||
*/
|
||||
public static byte[] chars2utf(char[] src) {
|
||||
return chars2utf(src, 0, src.length);
|
||||
}
|
||||
|
||||
/** Return string as an array of bytes in in Utf8 representation.
|
||||
*/
|
||||
public static byte[] string2utf(String s) {
|
||||
return chars2utf(s.toCharArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes each character in a string that has an escape sequence or
|
||||
* is non-printable ASCII. Leaves non-ASCII characters alone.
|
||||
*/
|
||||
public static String quote(String s) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
buf.append(quote(s.charAt(i)));
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes a character if it has an escape sequence or is
|
||||
* non-printable ASCII. Leaves non-ASCII characters alone.
|
||||
*/
|
||||
public static String quote(char ch) {
|
||||
switch (ch) {
|
||||
case '\b': return "\\b";
|
||||
case '\f': return "\\f";
|
||||
case '\n': return "\\n";
|
||||
case '\r': return "\\r";
|
||||
case '\t': return "\\t";
|
||||
case '\'': return "\\'";
|
||||
case '\"': return "\\\"";
|
||||
case '\\': return "\\\\";
|
||||
default:
|
||||
return (isPrintableAscii(ch))
|
||||
? String.valueOf(ch)
|
||||
: String.format("\\u%04x", (int) ch);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is a character printable ASCII?
|
||||
*/
|
||||
private static boolean isPrintableAscii(char ch) {
|
||||
return ch >= ' ' && ch <= '~';
|
||||
}
|
||||
|
||||
/** Escape all unicode characters in string.
|
||||
*/
|
||||
public static String escapeUnicode(String s) {
|
||||
int len = s.length();
|
||||
int i = 0;
|
||||
while (i < len) {
|
||||
char ch = s.charAt(i);
|
||||
if (ch > 255) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(s.substring(0, i));
|
||||
while (i < len) {
|
||||
ch = s.charAt(i);
|
||||
if (ch > 255) {
|
||||
buf.append("\\u");
|
||||
buf.append(Character.forDigit((ch >> 12) % 16, 16));
|
||||
buf.append(Character.forDigit((ch >> 8) % 16, 16));
|
||||
buf.append(Character.forDigit((ch >> 4) % 16, 16));
|
||||
buf.append(Character.forDigit((ch ) % 16, 16));
|
||||
} else {
|
||||
buf.append(ch);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
s = buf.toString();
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Conversion routines for qualified name splitting
|
||||
*/
|
||||
/** Return the last part of a class name.
|
||||
*/
|
||||
public static Name shortName(Name classname) {
|
||||
return classname.subName(
|
||||
classname.lastIndexOf((byte)'.') + 1, classname.getByteLength());
|
||||
}
|
||||
|
||||
public static String shortName(String classname) {
|
||||
return classname.substring(classname.lastIndexOf('.') + 1);
|
||||
}
|
||||
|
||||
/** Return the package name of a class name, excluding the trailing '.',
|
||||
* "" if not existent.
|
||||
*/
|
||||
public static Name packagePart(Name classname) {
|
||||
return classname.subName(0, classname.lastIndexOf((byte)'.'));
|
||||
}
|
||||
|
||||
public static String packagePart(String classname) {
|
||||
int lastDot = classname.lastIndexOf('.');
|
||||
return (lastDot < 0 ? "" : classname.substring(0, lastDot));
|
||||
}
|
||||
|
||||
public static List<Name> enclosingCandidates(Name name) {
|
||||
List<Name> names = List.nil();
|
||||
int index;
|
||||
while ((index = name.lastIndexOf((byte)'$')) > 0) {
|
||||
name = name.subName(0, index);
|
||||
names = names.prepend(name);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
}
|
||||
220
jdkSrc/jdk8/com/sun/tools/javac/util/DiagnosticSource.java
Normal file
220
jdkSrc/jdk8/com/sun/tools/javac/util/DiagnosticSource.java
Normal file
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.nio.CharBuffer;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
import com.sun.tools.javac.file.JavacFileManager;
|
||||
import com.sun.tools.javac.tree.EndPosTable;
|
||||
|
||||
import static com.sun.tools.javac.util.LayoutCharacters.*;
|
||||
|
||||
/**
|
||||
* A simple abstraction of a source file, as needed for use in a diagnostic message.
|
||||
* Provides access to the line and position in a line for any given character offset.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class DiagnosticSource {
|
||||
|
||||
/* constant DiagnosticSource to be used when sourcefile is missing */
|
||||
public static final DiagnosticSource NO_SOURCE = new DiagnosticSource() {
|
||||
@Override
|
||||
protected boolean findLine(int pos) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
public DiagnosticSource(JavaFileObject fo, AbstractLog log) {
|
||||
this.fileObject = fo;
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
private DiagnosticSource() {}
|
||||
|
||||
/** Return the underlying file object handled by this
|
||||
* DiagnosticSource object.
|
||||
*/
|
||||
public JavaFileObject getFile() {
|
||||
return fileObject;
|
||||
}
|
||||
|
||||
/** Return the one-based line number associated with a given pos
|
||||
* for the current source file. Zero is returned if no line exists
|
||||
* for the given position.
|
||||
*/
|
||||
public int getLineNumber(int pos) {
|
||||
try {
|
||||
if (findLine(pos)) {
|
||||
return line;
|
||||
}
|
||||
return 0;
|
||||
} finally {
|
||||
buf = null;
|
||||
}
|
||||
}
|
||||
|
||||
/** Return the one-based column number associated with a given pos
|
||||
* for the current source file. Zero is returned if no column exists
|
||||
* for the given position.
|
||||
*/
|
||||
public int getColumnNumber(int pos, boolean expandTabs) {
|
||||
try {
|
||||
if (findLine(pos)) {
|
||||
int column = 0;
|
||||
for (int bp = lineStart; bp < pos; bp++) {
|
||||
if (bp >= bufLen) {
|
||||
return 0;
|
||||
}
|
||||
if (buf[bp] == '\t' && expandTabs) {
|
||||
column = (column / TabInc * TabInc) + TabInc;
|
||||
} else {
|
||||
column++;
|
||||
}
|
||||
}
|
||||
return column + 1; // positions are one-based
|
||||
}
|
||||
return 0;
|
||||
} finally {
|
||||
buf = null;
|
||||
}
|
||||
}
|
||||
|
||||
/** Return the content of the line containing a given pos.
|
||||
*/
|
||||
public String getLine(int pos) {
|
||||
try {
|
||||
if (!findLine(pos))
|
||||
return null;
|
||||
|
||||
int lineEnd = lineStart;
|
||||
while (lineEnd < bufLen && buf[lineEnd] != CR && buf[lineEnd] != LF)
|
||||
lineEnd++;
|
||||
if (lineEnd - lineStart == 0)
|
||||
return null;
|
||||
return new String(buf, lineStart, lineEnd - lineStart);
|
||||
} finally {
|
||||
buf = null;
|
||||
}
|
||||
}
|
||||
|
||||
public EndPosTable getEndPosTable() {
|
||||
return endPosTable;
|
||||
}
|
||||
|
||||
public void setEndPosTable(EndPosTable t) {
|
||||
if (endPosTable != null && endPosTable != t)
|
||||
throw new IllegalStateException("endPosTable already set");
|
||||
endPosTable = t;
|
||||
}
|
||||
|
||||
/** Find the line in the buffer that contains the current position
|
||||
* @param pos Character offset into the buffer
|
||||
*/
|
||||
protected boolean findLine(int pos) {
|
||||
if (pos == Position.NOPOS)
|
||||
return false;
|
||||
|
||||
try {
|
||||
// try and recover buffer from soft reference cache
|
||||
if (buf == null && refBuf != null)
|
||||
buf = refBuf.get();
|
||||
|
||||
if (buf == null) {
|
||||
buf = initBuf(fileObject);
|
||||
lineStart = 0;
|
||||
line = 1;
|
||||
} else if (lineStart > pos) { // messages don't come in order
|
||||
lineStart = 0;
|
||||
line = 1;
|
||||
}
|
||||
|
||||
int bp = lineStart;
|
||||
while (bp < bufLen && bp < pos) {
|
||||
switch (buf[bp++]) {
|
||||
case CR:
|
||||
if (bp < bufLen && buf[bp] == LF) bp++;
|
||||
line++;
|
||||
lineStart = bp;
|
||||
break;
|
||||
case LF:
|
||||
line++;
|
||||
lineStart = bp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return bp <= bufLen;
|
||||
} catch (IOException e) {
|
||||
log.directError("source.unavailable");
|
||||
buf = new char[0];
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected char[] initBuf(JavaFileObject fileObject) throws IOException {
|
||||
char[] buf;
|
||||
CharSequence cs = fileObject.getCharContent(true);
|
||||
if (cs instanceof CharBuffer) {
|
||||
CharBuffer cb = (CharBuffer) cs;
|
||||
buf = JavacFileManager.toArray(cb);
|
||||
bufLen = cb.limit();
|
||||
} else {
|
||||
buf = cs.toString().toCharArray();
|
||||
bufLen = buf.length;
|
||||
}
|
||||
refBuf = new SoftReference<char[]>(buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/** The underlying file object. */
|
||||
protected JavaFileObject fileObject;
|
||||
|
||||
protected EndPosTable endPosTable;
|
||||
|
||||
/** A soft reference to the content of the file object. */
|
||||
protected SoftReference<char[]> refBuf;
|
||||
|
||||
/** A temporary hard reference to the content of the file object. */
|
||||
protected char[] buf;
|
||||
|
||||
/** The length of the content. */
|
||||
protected int bufLen;
|
||||
|
||||
/** The start of a line found by findLine. */
|
||||
protected int lineStart;
|
||||
|
||||
/** The line number of a line found by findLine. */
|
||||
protected int line;
|
||||
|
||||
/** A log for reporting errors, such as errors accessing the content. */
|
||||
protected AbstractLog log;
|
||||
}
|
||||
63
jdkSrc/jdk8/com/sun/tools/javac/util/FatalError.java
Normal file
63
jdkSrc/jdk8/com/sun/tools/javac/util/FatalError.java
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
/** Throwing an instance of this class causes immediate termination
|
||||
* of the main compiler method. It is used when some non-recoverable
|
||||
* error has been detected in the compiler environment at runtime.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class FatalError extends Error {
|
||||
private static final long serialVersionUID = 0;
|
||||
|
||||
/** Construct a <code>FatalError</code> with the specified detail message.
|
||||
* @param d A diagnostic containing the reason for failure.
|
||||
*/
|
||||
public FatalError(JCDiagnostic d) {
|
||||
super(d.toString());
|
||||
}
|
||||
|
||||
/** Construct a <code>FatalError</code> with the specified detail message
|
||||
* and cause.
|
||||
* @param d A diagnostic containing the reason for failure.
|
||||
* @param t An exception causing the error
|
||||
*/
|
||||
public FatalError(JCDiagnostic d, Throwable t) {
|
||||
super(d.toString(), t);
|
||||
}
|
||||
|
||||
/** Construct a <code>FatalError</code> with the specified detail message.
|
||||
* @param s An English(!) string describing the failure, typically because
|
||||
* the diagnostic resources are missing.
|
||||
*/
|
||||
public FatalError(String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
39
jdkSrc/jdk8/com/sun/tools/javac/util/Filter.java
Normal file
39
jdkSrc/jdk8/com/sun/tools/javac/util/Filter.java
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
/**
|
||||
* Simple filter acting as a boolean predicate. Method accepts return true if
|
||||
* the supplied element matches against the filter.
|
||||
*/
|
||||
public interface Filter<T> {
|
||||
/**
|
||||
* Does this element match against the filter?
|
||||
* @param t element to be checked
|
||||
* @return true if the element satisfy constraints imposed by filter
|
||||
*/
|
||||
boolean accepts(T t);
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.Locale;
|
||||
import javax.tools.Diagnostic;
|
||||
|
||||
import com.sun.tools.javac.api.DiagnosticFormatter;
|
||||
import com.sun.tools.javac.api.DiagnosticFormatter.Configuration;
|
||||
import com.sun.tools.javac.api.DiagnosticFormatter.Configuration.DiagnosticPart;
|
||||
import com.sun.tools.javac.api.DiagnosticFormatter.Configuration.MultilineLimit;
|
||||
import com.sun.tools.javac.api.DiagnosticFormatter.PositionKind;
|
||||
|
||||
/**
|
||||
* A delegated diagnostic formatter delegates all formatting
|
||||
* actions to an underlying formatter (aka the delegated formatter).
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class ForwardingDiagnosticFormatter<D extends Diagnostic<?>, F extends DiagnosticFormatter<D>>
|
||||
implements DiagnosticFormatter<D> {
|
||||
|
||||
/**
|
||||
* The delegated formatter
|
||||
*/
|
||||
protected F formatter;
|
||||
|
||||
/*
|
||||
* configuration object used by this formatter
|
||||
*/
|
||||
protected ForwardingConfiguration configuration;
|
||||
|
||||
public ForwardingDiagnosticFormatter(F formatter) {
|
||||
this.formatter = formatter;
|
||||
this.configuration = new ForwardingConfiguration(formatter.getConfiguration());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying delegated formatter
|
||||
* @return delegate formatter
|
||||
*/
|
||||
public F getDelegatedFormatter() {
|
||||
return formatter;
|
||||
}
|
||||
|
||||
public Configuration getConfiguration() {
|
||||
return configuration;
|
||||
}
|
||||
|
||||
public boolean displaySource(D diag) {
|
||||
return formatter.displaySource(diag);
|
||||
}
|
||||
|
||||
public String format(D diag, Locale l) {
|
||||
return formatter.format(diag, l);
|
||||
}
|
||||
|
||||
public String formatKind(D diag, Locale l) {
|
||||
return formatter.formatKind(diag, l);
|
||||
}
|
||||
|
||||
public String formatMessage(D diag, Locale l) {
|
||||
return formatter.formatMessage(diag, l);
|
||||
}
|
||||
|
||||
public String formatPosition(D diag, PositionKind pk, Locale l) {
|
||||
return formatter.formatPosition(diag, pk, l);
|
||||
}
|
||||
|
||||
public String formatSource(D diag, boolean fullname, Locale l) {
|
||||
return formatter.formatSource(diag, fullname, l);
|
||||
}
|
||||
|
||||
/**
|
||||
* A delegated formatter configuration delegates all configurations settings
|
||||
* to an underlying configuration object (aka the delegated configuration).
|
||||
*/
|
||||
public static class ForwardingConfiguration implements DiagnosticFormatter.Configuration {
|
||||
|
||||
/** The configurationr object to which the forwarding configuration delegates some settings */
|
||||
protected Configuration configuration;
|
||||
|
||||
public ForwardingConfiguration(Configuration configuration) {
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying delegated configuration.
|
||||
* @return delegated configuration
|
||||
*/
|
||||
public Configuration getDelegatedConfiguration() {
|
||||
return configuration;
|
||||
}
|
||||
|
||||
public int getMultilineLimit(MultilineLimit limit) {
|
||||
return configuration.getMultilineLimit(limit);
|
||||
}
|
||||
|
||||
public Set<DiagnosticPart> getVisible() {
|
||||
return configuration.getVisible();
|
||||
}
|
||||
|
||||
public void setMultilineLimit(MultilineLimit limit, int value) {
|
||||
configuration.setMultilineLimit(limit, value);
|
||||
}
|
||||
|
||||
public void setVisible(Set<DiagnosticPart> diagParts) {
|
||||
configuration.setVisible(diagParts);
|
||||
}
|
||||
}
|
||||
}
|
||||
197
jdkSrc/jdk8/com/sun/tools/javac/util/GraphUtils.java
Normal file
197
jdkSrc/jdk8/com/sun/tools/javac/util/GraphUtils.java
Normal file
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
/** <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class GraphUtils {
|
||||
|
||||
/**
|
||||
* Basic interface for defining various dependency kinds. All dependency kinds
|
||||
* must at least support basic capabilities to tell the DOT engine how to render them.
|
||||
*/
|
||||
public interface DependencyKind {
|
||||
/**
|
||||
* Returns the DOT representation (to be used in a {@code style} attribute
|
||||
* that's most suited for this dependency kind.
|
||||
*/
|
||||
String getDotStyle();
|
||||
}
|
||||
|
||||
/**
|
||||
* This class is a basic abstract class for representing a node.
|
||||
* A node is associated with a given data.
|
||||
*/
|
||||
public static abstract class Node<D> {
|
||||
public final D data;
|
||||
|
||||
public Node(D data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of the dependency kinds supported by this node.
|
||||
*/
|
||||
public abstract DependencyKind[] getSupportedDependencyKinds();
|
||||
|
||||
/**
|
||||
* Get all dependencies, regardless of their kind.
|
||||
*/
|
||||
public abstract Iterable<? extends Node<D>> getAllDependencies();
|
||||
|
||||
/**
|
||||
* Get a name for the dependency (of given kind) linking this node to a given node
|
||||
*/
|
||||
public abstract String getDependencyName(Node<D> to, DependencyKind dk);
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return data.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class specialized Node, by adding elements that are required in order
|
||||
* to perform Tarjan computation of strongly connected components.
|
||||
*/
|
||||
public static abstract class TarjanNode<D> extends Node<D> implements Comparable<TarjanNode<D>> {
|
||||
int index = -1;
|
||||
int lowlink;
|
||||
boolean active;
|
||||
|
||||
public TarjanNode(D data) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
public abstract Iterable<? extends TarjanNode<D>> getAllDependencies();
|
||||
|
||||
public abstract Iterable<? extends TarjanNode<D>> getDependenciesByKind(DependencyKind dk);
|
||||
|
||||
public int compareTo(TarjanNode<D> o) {
|
||||
return (index < o.index) ? -1 : (index == o.index) ? 0 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tarjan's algorithm to determine strongly connected components of a
|
||||
* directed graph in linear time. Works on TarjanNode.
|
||||
*/
|
||||
public static <D, N extends TarjanNode<D>> List<? extends List<? extends N>> tarjan(Iterable<? extends N> nodes) {
|
||||
Tarjan<D, N> tarjan = new Tarjan<>();
|
||||
return tarjan.findSCC(nodes);
|
||||
}
|
||||
|
||||
//where
|
||||
private static class Tarjan<D, N extends TarjanNode<D>> {
|
||||
|
||||
/** Unique node identifier. */
|
||||
int index = 0;
|
||||
|
||||
/** List of SCCs found so far. */
|
||||
ListBuffer<List<N>> sccs = new ListBuffer<>();
|
||||
|
||||
/** Stack of all reacheable nodes from given root. */
|
||||
ListBuffer<N> stack = new ListBuffer<>();
|
||||
|
||||
private List<? extends List<? extends N>> findSCC(Iterable<? extends N> nodes) {
|
||||
for (N node : nodes) {
|
||||
if (node.index == -1) {
|
||||
findSCC(node);
|
||||
}
|
||||
}
|
||||
return sccs.toList();
|
||||
}
|
||||
|
||||
private void findSCC(N v) {
|
||||
visitNode(v);
|
||||
for (TarjanNode<D> tn : v.getAllDependencies()) {
|
||||
@SuppressWarnings("unchecked")
|
||||
N n = (N)tn;
|
||||
if (n.index == -1) {
|
||||
//it's the first time we see this node
|
||||
findSCC(n);
|
||||
v.lowlink = Math.min(v.lowlink, n.lowlink);
|
||||
} else if (stack.contains(n)) {
|
||||
//this node is already reachable from current root
|
||||
v.lowlink = Math.min(v.lowlink, n.index);
|
||||
}
|
||||
}
|
||||
if (v.lowlink == v.index) {
|
||||
//v is the root of a SCC
|
||||
addSCC(v);
|
||||
}
|
||||
}
|
||||
|
||||
private void visitNode(N n) {
|
||||
n.index = index;
|
||||
n.lowlink = index;
|
||||
index++;
|
||||
stack.prepend(n);
|
||||
n.active = true;
|
||||
}
|
||||
|
||||
private void addSCC(N v) {
|
||||
N n;
|
||||
ListBuffer<N> cycle = new ListBuffer<>();
|
||||
do {
|
||||
n = stack.remove();
|
||||
n.active = false;
|
||||
cycle.add(n);
|
||||
} while (n != v);
|
||||
sccs.add(cycle.toList());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Debugging: dot representation of a set of connected nodes. The resulting
|
||||
* dot representation will use {@code Node.toString} to display node labels
|
||||
* and {@code Node.printDependency} to display edge labels. The resulting
|
||||
* representation is also customizable with a graph name and a header.
|
||||
*/
|
||||
public static <D> String toDot(Iterable<? extends TarjanNode<D>> nodes, String name, String header) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(String.format("digraph %s {\n", name));
|
||||
buf.append(String.format("label = \"%s\";\n", header));
|
||||
//dump nodes
|
||||
for (TarjanNode<D> n : nodes) {
|
||||
buf.append(String.format("%s [label = \"%s\"];\n", n.hashCode(), n.toString()));
|
||||
}
|
||||
//dump arcs
|
||||
for (TarjanNode<D> from : nodes) {
|
||||
for (DependencyKind dk : from.getSupportedDependencyKinds()) {
|
||||
for (TarjanNode<D> to : from.getDependenciesByKind(dk)) {
|
||||
buf.append(String.format("%s -> %s [label = \" %s \" style = %s ];\n",
|
||||
from.hashCode(), to.hashCode(), from.getDependencyName(to, dk), dk.getDotStyle()));
|
||||
}
|
||||
}
|
||||
}
|
||||
buf.append("}\n");
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
198
jdkSrc/jdk8/com/sun/tools/javac/util/IntHashTable.java
Normal file
198
jdkSrc/jdk8/com/sun/tools/javac/util/IntHashTable.java
Normal file
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
/**
|
||||
* A hash table that maps Object to int.
|
||||
*
|
||||
* This is a custom hash table optimised for the Object -> int
|
||||
* maps. This is done to avoid unnecessary object allocation in the image set.
|
||||
*
|
||||
* @author Charles Turner
|
||||
* @author Per Bothner
|
||||
*/
|
||||
public class IntHashTable {
|
||||
private static final int DEFAULT_INITIAL_SIZE = 64;
|
||||
protected Object[] objs; // the domain set
|
||||
protected int[] ints; // the image set
|
||||
protected int mask; // used to clip int's into the domain
|
||||
protected int num_bindings; // the number of mappings (including DELETED)
|
||||
private final static Object DELETED = new Object();
|
||||
|
||||
/**
|
||||
* Construct an Object -> int hash table.
|
||||
*
|
||||
* The default size of the hash table is 64 mappings.
|
||||
*/
|
||||
public IntHashTable() {
|
||||
objs = new Object[DEFAULT_INITIAL_SIZE];
|
||||
ints = new int[DEFAULT_INITIAL_SIZE];
|
||||
mask = DEFAULT_INITIAL_SIZE - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an Object -> int hash table with a specified amount of mappings.
|
||||
* @param capacity The number of default mappings in this hash table.
|
||||
*/
|
||||
public IntHashTable(int capacity) {
|
||||
int log2Size = 4;
|
||||
while (capacity > (1 << log2Size)) {
|
||||
log2Size++;
|
||||
}
|
||||
capacity = 1 << log2Size;
|
||||
objs = new Object[capacity];
|
||||
ints = new int[capacity];
|
||||
mask = capacity - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the hash code of a given object.
|
||||
*
|
||||
* @param key The object whose hash code is to be computed.
|
||||
* @return zero if the object is null, otherwise the identityHashCode
|
||||
*/
|
||||
public int hash(Object key) {
|
||||
return System.identityHashCode(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find either the index of a key's value, or the index of an available space.
|
||||
*
|
||||
* @param key The key to whose value you want to find.
|
||||
* @param hash The hash code of this key.
|
||||
* @return Either the index of the key's value, or an index pointing to
|
||||
* unoccupied space.
|
||||
*/
|
||||
public int lookup(Object key, int hash) {
|
||||
Object node;
|
||||
int hash1 = hash ^ (hash >>> 15);
|
||||
int hash2 = (hash ^ (hash << 6)) | 1; //ensure coprimeness
|
||||
int deleted = -1;
|
||||
for (int i = hash1 & mask;; i = (i + hash2) & mask) {
|
||||
node = objs[i];
|
||||
if (node == key)
|
||||
return i;
|
||||
if (node == null)
|
||||
return deleted >= 0 ? deleted : i;
|
||||
if (node == DELETED && deleted < 0)
|
||||
deleted = i;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup a given key's value in the hash table.
|
||||
*
|
||||
* @param key The key whose value you want to find.
|
||||
* @return Either the index of the key's value, or an index pointing to
|
||||
* unoccupied space.
|
||||
*/
|
||||
public int lookup(Object key) {
|
||||
return lookup(key, hash(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value stored at the specified index in the table.
|
||||
*
|
||||
* @param index The index to inspect, as returned from {@link #lookup}
|
||||
* @return A non-negative integer if the index contains a non-null
|
||||
* value, or -1 if it does.
|
||||
*/
|
||||
public int getFromIndex(int index) {
|
||||
Object node = objs[index];
|
||||
return node == null || node == DELETED ? -1 : ints[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates the specified key with the specified value in this map.
|
||||
*
|
||||
* @param key key with which the specified value is to be associated.
|
||||
* @param value value to be associated with the specified key.
|
||||
* @param index the index at which to place this binding, as returned
|
||||
* from {@link #lookup}.
|
||||
* @return previous value associated with specified key, or -1 if there was
|
||||
* no mapping for key.
|
||||
*/
|
||||
public int putAtIndex(Object key, int value, int index) {
|
||||
Object old = objs[index];
|
||||
if (old == null || old == DELETED) {
|
||||
objs[index] = key;
|
||||
ints[index] = value;
|
||||
if (old != DELETED)
|
||||
num_bindings++;
|
||||
if (3 * num_bindings >= 2 * objs.length)
|
||||
rehash();
|
||||
return -1;
|
||||
} else { // update existing mapping
|
||||
int oldValue = ints[index];
|
||||
ints[index] = value;
|
||||
return oldValue;
|
||||
}
|
||||
}
|
||||
|
||||
public int remove(Object key) {
|
||||
int index = lookup(key);
|
||||
Object old = objs[index];
|
||||
if (old == null || old == DELETED)
|
||||
return -1;
|
||||
objs[index] = DELETED;
|
||||
return ints[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand the hash table when it exceeds the load factor.
|
||||
*
|
||||
* Rehash the existing objects.
|
||||
*/
|
||||
protected void rehash() {
|
||||
Object[] oldObjsTable = objs;
|
||||
int[] oldIntsTable = ints;
|
||||
int oldCapacity = oldObjsTable.length;
|
||||
int newCapacity = oldCapacity << 1;
|
||||
Object[] newObjTable = new Object[newCapacity];
|
||||
int[] newIntTable = new int[newCapacity];
|
||||
int newMask = newCapacity - 1;
|
||||
objs = newObjTable;
|
||||
ints = newIntTable;
|
||||
mask = newMask;
|
||||
num_bindings = 0; // this is recomputed below
|
||||
Object key;
|
||||
for (int i = oldIntsTable.length; --i >= 0;) {
|
||||
key = oldObjsTable[i];
|
||||
if (key != null && key != DELETED)
|
||||
putAtIndex(key, oldIntsTable[i], lookup(key, hash(key)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all mappings from this map.
|
||||
*/
|
||||
public void clear() {
|
||||
for (int i = objs.length; --i >= 0;) {
|
||||
objs[i] = null;
|
||||
}
|
||||
num_bindings = 0;
|
||||
}
|
||||
}
|
||||
641
jdkSrc/jdk8/com/sun/tools/javac/util/JCDiagnostic.java
Normal file
641
jdkSrc/jdk8/com/sun/tools/javac/util/JCDiagnostic.java
Normal file
@@ -0,0 +1,641 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.tools.Diagnostic;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
import com.sun.tools.javac.api.DiagnosticFormatter;
|
||||
import com.sun.tools.javac.code.Lint.LintCategory;
|
||||
import com.sun.tools.javac.tree.EndPosTable;
|
||||
import com.sun.tools.javac.tree.JCTree;
|
||||
|
||||
import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticType.*;
|
||||
|
||||
/** An abstraction of a diagnostic message generated by the compiler.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class JCDiagnostic implements Diagnostic<JavaFileObject> {
|
||||
/** A factory for creating diagnostic objects. */
|
||||
public static class Factory {
|
||||
/** The context key for the diagnostic factory. */
|
||||
protected static final Context.Key<JCDiagnostic.Factory> diagnosticFactoryKey =
|
||||
new Context.Key<JCDiagnostic.Factory>();
|
||||
|
||||
/** Get the Factory instance for this context. */
|
||||
public static Factory instance(Context context) {
|
||||
Factory instance = context.get(diagnosticFactoryKey);
|
||||
if (instance == null)
|
||||
instance = new Factory(context);
|
||||
return instance;
|
||||
}
|
||||
|
||||
DiagnosticFormatter<JCDiagnostic> formatter;
|
||||
final String prefix;
|
||||
final Set<DiagnosticFlag> defaultErrorFlags;
|
||||
|
||||
/** Create a new diagnostic factory. */
|
||||
protected Factory(Context context) {
|
||||
this(JavacMessages.instance(context), "compiler");
|
||||
context.put(diagnosticFactoryKey, this);
|
||||
|
||||
final Options options = Options.instance(context);
|
||||
initOptions(options);
|
||||
options.addListener(new Runnable() {
|
||||
public void run() {
|
||||
initOptions(options);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void initOptions(Options options) {
|
||||
if (options.isSet("onlySyntaxErrorsUnrecoverable"))
|
||||
defaultErrorFlags.add(DiagnosticFlag.RECOVERABLE);
|
||||
}
|
||||
|
||||
/** Create a new diagnostic factory. */
|
||||
public Factory(JavacMessages messages, String prefix) {
|
||||
this.prefix = prefix;
|
||||
this.formatter = new BasicDiagnosticFormatter(messages);
|
||||
defaultErrorFlags = EnumSet.of(DiagnosticFlag.MANDATORY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an error diagnostic.
|
||||
* @param source The source of the compilation unit, if any, in which to report the error.
|
||||
* @param pos The source position at which to report the error.
|
||||
* @param key The key for the localized error message.
|
||||
* @param args Fields of the error message.
|
||||
*/
|
||||
public JCDiagnostic error(
|
||||
DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
|
||||
return create(ERROR, null, defaultErrorFlags, source, pos, key, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a warning diagnostic that will not be hidden by the -nowarn or -Xlint:none options.
|
||||
* @param source The source of the compilation unit, if any, in which to report the warning.
|
||||
* @param pos The source position at which to report the warning.
|
||||
* @param key The key for the localized warning message.
|
||||
* @param args Fields of the warning message.
|
||||
* @see MandatoryWarningHandler
|
||||
*/
|
||||
public JCDiagnostic mandatoryWarning(
|
||||
DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
|
||||
return create(WARNING, null, EnumSet.of(DiagnosticFlag.MANDATORY), source, pos, key, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a warning diagnostic that will not be hidden by the -nowarn or -Xlint:none options.
|
||||
* @param lc The lint category for the diagnostic
|
||||
* @param source The source of the compilation unit, if any, in which to report the warning.
|
||||
* @param pos The source position at which to report the warning.
|
||||
* @param key The key for the localized warning message.
|
||||
* @param args Fields of the warning message.
|
||||
* @see MandatoryWarningHandler
|
||||
*/
|
||||
public JCDiagnostic mandatoryWarning(
|
||||
LintCategory lc,
|
||||
DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
|
||||
return create(WARNING, lc, EnumSet.of(DiagnosticFlag.MANDATORY), source, pos, key, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a warning diagnostic.
|
||||
* @param lc The lint category for the diagnostic
|
||||
* @param key The key for the localized error message.
|
||||
* @param args Fields of the warning message.
|
||||
* @see MandatoryWarningHandler
|
||||
*/
|
||||
public JCDiagnostic warning(
|
||||
LintCategory lc, String key, Object... args) {
|
||||
return create(WARNING, lc, EnumSet.noneOf(DiagnosticFlag.class), null, null, key, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a warning diagnostic.
|
||||
* @param source The source of the compilation unit, if any, in which to report the warning.
|
||||
* @param pos The source position at which to report the warning.
|
||||
* @param key The key for the localized warning message.
|
||||
* @param args Fields of the warning message.
|
||||
*/
|
||||
public JCDiagnostic warning(
|
||||
DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
|
||||
return create(WARNING, null, EnumSet.noneOf(DiagnosticFlag.class), source, pos, key, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a warning diagnostic.
|
||||
* @param lc The lint category for the diagnostic
|
||||
* @param source The source of the compilation unit, if any, in which to report the warning.
|
||||
* @param pos The source position at which to report the warning.
|
||||
* @param key The key for the localized warning message.
|
||||
* @param args Fields of the warning message.
|
||||
* @see MandatoryWarningHandler
|
||||
*/
|
||||
public JCDiagnostic warning(
|
||||
LintCategory lc, DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
|
||||
return create(WARNING, lc, EnumSet.noneOf(DiagnosticFlag.class), source, pos, key, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a note diagnostic that will not be hidden by the -nowarn or -Xlint:none options.
|
||||
* @param key The key for the localized message.
|
||||
* @param args Fields of the message.
|
||||
* @see MandatoryWarningHandler
|
||||
*/
|
||||
public JCDiagnostic mandatoryNote(DiagnosticSource source, String key, Object... args) {
|
||||
return create(NOTE, null, EnumSet.of(DiagnosticFlag.MANDATORY), source, null, key, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a note diagnostic.
|
||||
* @param key The key for the localized error message.
|
||||
* @param args Fields of the message.
|
||||
*/
|
||||
public JCDiagnostic note(String key, Object... args) {
|
||||
return create(NOTE, null, EnumSet.noneOf(DiagnosticFlag.class), null, null, key, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a note diagnostic.
|
||||
* @param source The source of the compilation unit, if any, in which to report the note.
|
||||
* @param pos The source position at which to report the note.
|
||||
* @param key The key for the localized message.
|
||||
* @param args Fields of the message.
|
||||
*/
|
||||
public JCDiagnostic note(
|
||||
DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
|
||||
return create(NOTE, null, EnumSet.noneOf(DiagnosticFlag.class), source, pos, key, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a fragment diagnostic, for use as an argument in other diagnostics
|
||||
* @param key The key for the localized message.
|
||||
* @param args Fields of the message.
|
||||
*/
|
||||
public JCDiagnostic fragment(String key, Object... args) {
|
||||
return create(FRAGMENT, null, EnumSet.noneOf(DiagnosticFlag.class), null, null, key, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new diagnostic of the given kind, which is not mandatory and which has
|
||||
* no lint category.
|
||||
* @param kind The diagnostic kind
|
||||
* @param source The source of the compilation unit, if any, in which to report the message.
|
||||
* @param pos The source position at which to report the message.
|
||||
* @param key The key for the localized message.
|
||||
* @param args Fields of the message.
|
||||
*/
|
||||
public JCDiagnostic create(
|
||||
DiagnosticType kind, DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
|
||||
return create(kind, null, EnumSet.noneOf(DiagnosticFlag.class), source, pos, key, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new diagnostic of the given kind.
|
||||
* @param kind The diagnostic kind
|
||||
* @param lc The lint category, if applicable, or null
|
||||
* @param flags The set of flags for the diagnostic
|
||||
* @param source The source of the compilation unit, if any, in which to report the message.
|
||||
* @param pos The source position at which to report the message.
|
||||
* @param key The key for the localized message.
|
||||
* @param args Fields of the message.
|
||||
*/
|
||||
public JCDiagnostic create(
|
||||
DiagnosticType kind, LintCategory lc, Set<DiagnosticFlag> flags, DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
|
||||
return new JCDiagnostic(formatter, kind, lc, flags, source, pos, qualify(kind, key), args);
|
||||
}
|
||||
|
||||
protected String qualify(DiagnosticType t, String key) {
|
||||
return prefix + "." + t.key + "." + key;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create a fragment diagnostic, for use as an argument in other diagnostics
|
||||
* @param key The key for the localized error message.
|
||||
* @param args Fields of the error message.
|
||||
*
|
||||
*/
|
||||
@Deprecated
|
||||
public static JCDiagnostic fragment(String key, Object... args) {
|
||||
return new JCDiagnostic(getFragmentFormatter(),
|
||||
FRAGMENT,
|
||||
null,
|
||||
EnumSet.noneOf(DiagnosticFlag.class),
|
||||
null,
|
||||
null,
|
||||
"compiler." + FRAGMENT.key + "." + key,
|
||||
args);
|
||||
}
|
||||
//where
|
||||
@Deprecated
|
||||
public static DiagnosticFormatter<JCDiagnostic> getFragmentFormatter() {
|
||||
if (fragmentFormatter == null) {
|
||||
fragmentFormatter = new BasicDiagnosticFormatter(JavacMessages.getDefaultMessages());
|
||||
}
|
||||
return fragmentFormatter;
|
||||
}
|
||||
|
||||
/**
|
||||
* A DiagnosticType defines the type of the diagnostic.
|
||||
**/
|
||||
public enum DiagnosticType {
|
||||
/** A fragment of an enclosing diagnostic. */
|
||||
FRAGMENT("misc"),
|
||||
/** A note: similar to, but less serious than, a warning. */
|
||||
NOTE("note"),
|
||||
/** A warning. */
|
||||
WARNING("warn"),
|
||||
/** An error. */
|
||||
ERROR("err");
|
||||
|
||||
final String key;
|
||||
|
||||
/** Create a DiagnosticType.
|
||||
* @param key A string used to create the resource key for the diagnostic.
|
||||
*/
|
||||
DiagnosticType(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A DiagnosticPosition provides information about the positions in a file
|
||||
* that gave rise to a diagnostic. It always defines a "preferred" position
|
||||
* that most accurately defines the location of the diagnostic, it may also
|
||||
* provide a related tree node that spans that location.
|
||||
*/
|
||||
public static interface DiagnosticPosition {
|
||||
/** Gets the tree node, if any, to which the diagnostic applies. */
|
||||
JCTree getTree();
|
||||
/** If there is a tree node, get the start position of the tree node.
|
||||
* Otherwise, just returns the same as getPreferredPosition(). */
|
||||
int getStartPosition();
|
||||
/** Get the position within the file that most accurately defines the
|
||||
* location for the diagnostic. */
|
||||
int getPreferredPosition();
|
||||
/** If there is a tree node, and if endPositions are available, get
|
||||
* the end position of the tree node. Otherwise, just returns the
|
||||
* same as getPreferredPosition(). */
|
||||
int getEndPosition(EndPosTable endPosTable);
|
||||
}
|
||||
|
||||
/**
|
||||
* A DiagnosticPosition that simply identifies a position, but no related
|
||||
* tree node, as the location for a diagnostic. Used for scanner and parser
|
||||
* diagnostics. */
|
||||
public static class SimpleDiagnosticPosition implements DiagnosticPosition {
|
||||
public SimpleDiagnosticPosition(int pos) {
|
||||
this.pos = pos;
|
||||
}
|
||||
|
||||
public JCTree getTree() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getStartPosition() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
public int getPreferredPosition() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
public int getEndPosition(EndPosTable endPosTable) {
|
||||
return pos;
|
||||
}
|
||||
|
||||
private final int pos;
|
||||
}
|
||||
|
||||
public enum DiagnosticFlag {
|
||||
MANDATORY,
|
||||
RESOLVE_ERROR,
|
||||
SYNTAX,
|
||||
RECOVERABLE,
|
||||
NON_DEFERRABLE,
|
||||
COMPRESSED
|
||||
}
|
||||
|
||||
private final DiagnosticType type;
|
||||
private final DiagnosticSource source;
|
||||
private final DiagnosticPosition position;
|
||||
private final String key;
|
||||
protected final Object[] args;
|
||||
private final Set<DiagnosticFlag> flags;
|
||||
private final LintCategory lintCategory;
|
||||
|
||||
/** source line position (set lazily) */
|
||||
private SourcePosition sourcePosition;
|
||||
|
||||
/**
|
||||
* This class is used to defer the line/column position fetch logic after diagnostic construction.
|
||||
*/
|
||||
class SourcePosition {
|
||||
|
||||
private final int line;
|
||||
private final int column;
|
||||
|
||||
SourcePosition() {
|
||||
int n = (position == null ? Position.NOPOS : position.getPreferredPosition());
|
||||
if (n == Position.NOPOS || source == null)
|
||||
line = column = -1;
|
||||
else {
|
||||
line = source.getLineNumber(n);
|
||||
column = source.getColumnNumber(n, true);
|
||||
}
|
||||
}
|
||||
|
||||
public int getLineNumber() {
|
||||
return line;
|
||||
}
|
||||
|
||||
public int getColumnNumber() {
|
||||
return column;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a diagnostic object.
|
||||
* @param formatter the formatter to use for the diagnostic
|
||||
* @param dt the type of diagnostic
|
||||
* @param lc the lint category for the diagnostic
|
||||
* @param source the name of the source file, or null if none.
|
||||
* @param pos the character offset within the source file, if given.
|
||||
* @param key a resource key to identify the text of the diagnostic
|
||||
* @param args arguments to be included in the text of the diagnostic
|
||||
*/
|
||||
protected JCDiagnostic(DiagnosticFormatter<JCDiagnostic> formatter,
|
||||
DiagnosticType dt,
|
||||
LintCategory lc,
|
||||
Set<DiagnosticFlag> flags,
|
||||
DiagnosticSource source,
|
||||
DiagnosticPosition pos,
|
||||
String key,
|
||||
Object... args) {
|
||||
if (source == null && pos != null && pos.getPreferredPosition() != Position.NOPOS)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
this.defaultFormatter = formatter;
|
||||
this.type = dt;
|
||||
this.lintCategory = lc;
|
||||
this.flags = flags;
|
||||
this.source = source;
|
||||
this.position = pos;
|
||||
this.key = key;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of this diagnostic.
|
||||
* @return the type of this diagnostic
|
||||
*/
|
||||
public DiagnosticType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the subdiagnostic list
|
||||
* @return subdiagnostic list
|
||||
*/
|
||||
public List<JCDiagnostic> getSubdiagnostics() {
|
||||
return List.nil();
|
||||
}
|
||||
|
||||
public boolean isMultiline() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether or not this diagnostic is required to be shown.
|
||||
* @return true if this diagnostic is required to be shown.
|
||||
*/
|
||||
public boolean isMandatory() {
|
||||
return flags.contains(DiagnosticFlag.MANDATORY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this diagnostic has an associated lint category.
|
||||
*/
|
||||
public boolean hasLintCategory() {
|
||||
return (lintCategory != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the associated lint category, or null if none.
|
||||
*/
|
||||
public LintCategory getLintCategory() {
|
||||
return lintCategory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the source file referred to by this diagnostic.
|
||||
* @return the name of the source referred to with this diagnostic, or null if none
|
||||
*/
|
||||
public JavaFileObject getSource() {
|
||||
if (source == null)
|
||||
return null;
|
||||
else
|
||||
return source.getFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the source referred to by this diagnostic.
|
||||
* @return the source referred to with this diagnostic, or null if none
|
||||
*/
|
||||
public DiagnosticSource getDiagnosticSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
protected int getIntStartPosition() {
|
||||
return (position == null ? Position.NOPOS : position.getStartPosition());
|
||||
}
|
||||
|
||||
protected int getIntPosition() {
|
||||
return (position == null ? Position.NOPOS : position.getPreferredPosition());
|
||||
}
|
||||
|
||||
protected int getIntEndPosition() {
|
||||
return (position == null ? Position.NOPOS : position.getEndPosition(source.getEndPosTable()));
|
||||
}
|
||||
|
||||
public long getStartPosition() {
|
||||
return getIntStartPosition();
|
||||
}
|
||||
|
||||
public long getPosition() {
|
||||
return getIntPosition();
|
||||
}
|
||||
|
||||
public long getEndPosition() {
|
||||
return getIntEndPosition();
|
||||
}
|
||||
|
||||
public DiagnosticPosition getDiagnosticPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the line number within the source referred to by this diagnostic.
|
||||
* @return the line number within the source referred to by this diagnostic
|
||||
*/
|
||||
public long getLineNumber() {
|
||||
if (sourcePosition == null) {
|
||||
sourcePosition = new SourcePosition();
|
||||
}
|
||||
return sourcePosition.getLineNumber();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the column number within the line of source referred to by this diagnostic.
|
||||
* @return the column number within the line of source referred to by this diagnostic
|
||||
*/
|
||||
public long getColumnNumber() {
|
||||
if (sourcePosition == null) {
|
||||
sourcePosition = new SourcePosition();
|
||||
}
|
||||
return sourcePosition.getColumnNumber();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the arguments to be included in the text of the diagnostic.
|
||||
* @return the arguments to be included in the text of the diagnostic
|
||||
*/
|
||||
public Object[] getArgs() {
|
||||
return args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the prefix string associated with this type of diagnostic.
|
||||
* @return the prefix string associated with this type of diagnostic
|
||||
*/
|
||||
public String getPrefix() {
|
||||
return getPrefix(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the prefix string associated with a particular type of diagnostic.
|
||||
* @return the prefix string associated with a particular type of diagnostic
|
||||
*/
|
||||
public String getPrefix(DiagnosticType dt) {
|
||||
return defaultFormatter.formatKind(this, Locale.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the standard presentation of this diagnostic.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return defaultFormatter.format(this,Locale.getDefault());
|
||||
}
|
||||
|
||||
private DiagnosticFormatter<JCDiagnostic> defaultFormatter;
|
||||
@Deprecated
|
||||
private static DiagnosticFormatter<JCDiagnostic> fragmentFormatter;
|
||||
|
||||
// Methods for javax.tools.Diagnostic
|
||||
|
||||
public Diagnostic.Kind getKind() {
|
||||
switch (type) {
|
||||
case NOTE:
|
||||
return Diagnostic.Kind.NOTE;
|
||||
case WARNING:
|
||||
return flags.contains(DiagnosticFlag.MANDATORY)
|
||||
? Diagnostic.Kind.MANDATORY_WARNING
|
||||
: Diagnostic.Kind.WARNING;
|
||||
case ERROR:
|
||||
return Diagnostic.Kind.ERROR;
|
||||
default:
|
||||
return Diagnostic.Kind.OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public String getMessage(Locale locale) {
|
||||
return defaultFormatter.formatMessage(this, locale);
|
||||
}
|
||||
|
||||
public void setFlag(DiagnosticFlag flag) {
|
||||
flags.add(flag);
|
||||
|
||||
if (type == DiagnosticType.ERROR) {
|
||||
switch (flag) {
|
||||
case SYNTAX:
|
||||
flags.remove(DiagnosticFlag.RECOVERABLE);
|
||||
break;
|
||||
case RESOLVE_ERROR:
|
||||
flags.add(DiagnosticFlag.RECOVERABLE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isFlagSet(DiagnosticFlag flag) {
|
||||
return flags.contains(flag);
|
||||
}
|
||||
|
||||
public static class MultilineDiagnostic extends JCDiagnostic {
|
||||
|
||||
private final List<JCDiagnostic> subdiagnostics;
|
||||
|
||||
public MultilineDiagnostic(JCDiagnostic other, List<JCDiagnostic> subdiagnostics) {
|
||||
super(other.defaultFormatter,
|
||||
other.getType(),
|
||||
other.getLintCategory(),
|
||||
other.flags,
|
||||
other.getDiagnosticSource(),
|
||||
other.position,
|
||||
other.getCode(),
|
||||
other.getArgs());
|
||||
this.subdiagnostics = subdiagnostics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JCDiagnostic> getSubdiagnostics() {
|
||||
return subdiagnostics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMultiline() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
202
jdkSrc/jdk8/com/sun/tools/javac/util/JavacMessages.java
Normal file
202
jdkSrc/jdk8/com/sun/tools/javac/util/JavacMessages.java
Normal file
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import com.sun.tools.javac.api.Messages;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.MissingResourceException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Support for formatted localized messages.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class JavacMessages implements Messages {
|
||||
/** The context key for the JavacMessages object. */
|
||||
public static final Context.Key<JavacMessages> messagesKey =
|
||||
new Context.Key<JavacMessages>();
|
||||
|
||||
/** Get the JavacMessages instance for this context. */
|
||||
public static JavacMessages instance(Context context) {
|
||||
JavacMessages instance = context.get(messagesKey);
|
||||
if (instance == null)
|
||||
instance = new JavacMessages(context);
|
||||
return instance;
|
||||
}
|
||||
|
||||
private Map<Locale, SoftReference<List<ResourceBundle>>> bundleCache;
|
||||
|
||||
private List<String> bundleNames;
|
||||
|
||||
private Locale currentLocale;
|
||||
private List<ResourceBundle> currentBundles;
|
||||
|
||||
public Locale getCurrentLocale() {
|
||||
return currentLocale;
|
||||
}
|
||||
|
||||
public void setCurrentLocale(Locale locale) {
|
||||
if (locale == null) {
|
||||
locale = Locale.getDefault();
|
||||
}
|
||||
this.currentBundles = getBundles(locale);
|
||||
this.currentLocale = locale;
|
||||
}
|
||||
|
||||
/** Creates a JavacMessages object.
|
||||
*/
|
||||
public JavacMessages(Context context) {
|
||||
this(defaultBundleName, context.get(Locale.class));
|
||||
context.put(messagesKey, this);
|
||||
}
|
||||
|
||||
/** Creates a JavacMessages object.
|
||||
* @param bundleName the name to identify the resource bundle of localized messages.
|
||||
*/
|
||||
public JavacMessages(String bundleName) throws MissingResourceException {
|
||||
this(bundleName, null);
|
||||
}
|
||||
|
||||
/** Creates a JavacMessages object.
|
||||
* @param bundleName the name to identify the resource bundle of localized messages.
|
||||
*/
|
||||
public JavacMessages(String bundleName, Locale locale) throws MissingResourceException {
|
||||
bundleNames = List.nil();
|
||||
bundleCache = new HashMap<Locale, SoftReference<List<ResourceBundle>>>();
|
||||
add(bundleName);
|
||||
setCurrentLocale(locale);
|
||||
}
|
||||
|
||||
public JavacMessages() throws MissingResourceException {
|
||||
this(defaultBundleName);
|
||||
}
|
||||
|
||||
public void add(String bundleName) throws MissingResourceException {
|
||||
bundleNames = bundleNames.prepend(bundleName);
|
||||
if (!bundleCache.isEmpty())
|
||||
bundleCache.clear();
|
||||
currentBundles = null;
|
||||
}
|
||||
|
||||
public List<ResourceBundle> getBundles(Locale locale) {
|
||||
if (locale == currentLocale && currentBundles != null)
|
||||
return currentBundles;
|
||||
SoftReference<List<ResourceBundle>> bundles = bundleCache.get(locale);
|
||||
List<ResourceBundle> bundleList = bundles == null ? null : bundles.get();
|
||||
if (bundleList == null) {
|
||||
bundleList = List.nil();
|
||||
for (String bundleName : bundleNames) {
|
||||
try {
|
||||
ResourceBundle rb = ResourceBundle.getBundle(bundleName, locale);
|
||||
bundleList = bundleList.prepend(rb);
|
||||
} catch (MissingResourceException e) {
|
||||
throw new InternalError("Cannot find javac resource bundle for locale " + locale);
|
||||
}
|
||||
}
|
||||
bundleCache.put(locale, new SoftReference<List<ResourceBundle>>(bundleList));
|
||||
}
|
||||
return bundleList;
|
||||
}
|
||||
|
||||
/** Gets the localized string corresponding to a key, formatted with a set of args.
|
||||
*/
|
||||
public String getLocalizedString(String key, Object... args) {
|
||||
return getLocalizedString(currentLocale, key, args);
|
||||
}
|
||||
|
||||
public String getLocalizedString(Locale l, String key, Object... args) {
|
||||
if (l == null)
|
||||
l = getCurrentLocale();
|
||||
return getLocalizedString(getBundles(l), key, args);
|
||||
}
|
||||
|
||||
/* Static access:
|
||||
* javac has a firmly entrenched notion of a default message bundle
|
||||
* which it can access from any static context. This is used to get
|
||||
* easy access to simple localized strings.
|
||||
*/
|
||||
|
||||
private static final String defaultBundleName =
|
||||
"com.sun.tools.javac.resources.compiler";
|
||||
private static ResourceBundle defaultBundle;
|
||||
private static JavacMessages defaultMessages;
|
||||
|
||||
|
||||
/**
|
||||
* Gets a localized string from the compiler's default bundle.
|
||||
*/
|
||||
// used to support legacy Log.getLocalizedString
|
||||
static String getDefaultLocalizedString(String key, Object... args) {
|
||||
return getLocalizedString(List.of(getDefaultBundle()), key, args);
|
||||
}
|
||||
|
||||
// used to support legacy static Diagnostic.fragment
|
||||
@Deprecated
|
||||
static JavacMessages getDefaultMessages() {
|
||||
if (defaultMessages == null)
|
||||
defaultMessages = new JavacMessages(defaultBundleName);
|
||||
return defaultMessages;
|
||||
}
|
||||
|
||||
public static ResourceBundle getDefaultBundle() {
|
||||
try {
|
||||
if (defaultBundle == null)
|
||||
defaultBundle = ResourceBundle.getBundle(defaultBundleName);
|
||||
return defaultBundle;
|
||||
}
|
||||
catch (MissingResourceException e) {
|
||||
throw new Error("Fatal: Resource for compiler is missing", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static String getLocalizedString(List<ResourceBundle> bundles,
|
||||
String key,
|
||||
Object... args) {
|
||||
String msg = null;
|
||||
for (List<ResourceBundle> l = bundles; l.nonEmpty() && msg == null; l = l.tail) {
|
||||
ResourceBundle rb = l.head;
|
||||
try {
|
||||
msg = rb.getString(key);
|
||||
}
|
||||
catch (MissingResourceException e) {
|
||||
// ignore, try other bundles in list
|
||||
}
|
||||
}
|
||||
if (msg == null) {
|
||||
msg = "compiler message file broken: key=" + key +
|
||||
" arguments={0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}";
|
||||
}
|
||||
return MessageFormat.format(msg, args);
|
||||
}
|
||||
}
|
||||
71
jdkSrc/jdk8/com/sun/tools/javac/util/LayoutCharacters.java
Normal file
71
jdkSrc/jdk8/com/sun/tools/javac/util/LayoutCharacters.java
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
/** An interface containing layout character constants used in Java
|
||||
* programs.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public interface LayoutCharacters {
|
||||
|
||||
/** Tabulator column increment.
|
||||
*/
|
||||
final static int TabInc = 8;
|
||||
|
||||
/** Standard indentation for subdiagnostics
|
||||
*/
|
||||
final static int DiagInc = 4;
|
||||
|
||||
/** Standard indentation for additional diagnostic lines
|
||||
*/
|
||||
final static int DetailsInc = 2;
|
||||
|
||||
/** Tabulator character.
|
||||
*/
|
||||
final static byte TAB = 0x9;
|
||||
|
||||
/** Line feed character.
|
||||
*/
|
||||
final static byte LF = 0xA;
|
||||
|
||||
/** Form feed character.
|
||||
*/
|
||||
final static byte FF = 0xC;
|
||||
|
||||
/** Carriage return character.
|
||||
*/
|
||||
final static byte CR = 0xD;
|
||||
|
||||
/** End of input character. Used as a sentinel to denote the
|
||||
* character one beyond the last defined character in a
|
||||
* source file.
|
||||
*/
|
||||
final static byte EOI = 0x1A;
|
||||
}
|
||||
540
jdkSrc/jdk8/com/sun/tools/javac/util/List.java
Normal file
540
jdkSrc/jdk8/com/sun/tools/javac/util/List.java
Normal file
@@ -0,0 +1,540 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.AbstractCollection;
|
||||
import java.util.ListIterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/** A class for generic linked lists. Links are supposed to be
|
||||
* immutable, the only exception being the incremental construction of
|
||||
* lists via ListBuffers. List is the main container class in
|
||||
* GJC. Most data structures and algorithms in GJC use lists rather
|
||||
* than arrays.
|
||||
*
|
||||
* <p>Lists are always trailed by a sentinel element, whose head and tail
|
||||
* are both null.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class List<A> extends AbstractCollection<A> implements java.util.List<A> {
|
||||
|
||||
/** The first element of the list, supposed to be immutable.
|
||||
*/
|
||||
public A head;
|
||||
|
||||
/** The remainder of the list except for its first element, supposed
|
||||
* to be immutable.
|
||||
*/
|
||||
//@Deprecated
|
||||
public List<A> tail;
|
||||
|
||||
/** Construct a list given its head and tail.
|
||||
*/
|
||||
List(A head, List<A> tail) {
|
||||
this.tail = tail;
|
||||
this.head = head;
|
||||
}
|
||||
|
||||
/** Construct an empty list.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <A> List<A> nil() {
|
||||
return (List<A>)EMPTY_LIST;
|
||||
}
|
||||
|
||||
private static final List<?> EMPTY_LIST = new List<Object>(null,null) {
|
||||
public List<Object> setTail(List<Object> tail) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
public boolean isEmpty() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/** Returns the list obtained from 'l' after removing all elements 'elem'
|
||||
*/
|
||||
public static <A> List<A> filter(List<A> l, A elem) {
|
||||
Assert.checkNonNull(elem);
|
||||
List<A> res = List.nil();
|
||||
for (A a : l) {
|
||||
if (a != null && !a.equals(elem)) {
|
||||
res = res.prepend(a);
|
||||
}
|
||||
}
|
||||
return res.reverse();
|
||||
}
|
||||
|
||||
public List<A> intersect(List<A> that) {
|
||||
ListBuffer<A> buf = new ListBuffer<>();
|
||||
for (A el : this) {
|
||||
if (that.contains(el)) {
|
||||
buf.append(el);
|
||||
}
|
||||
}
|
||||
return buf.toList();
|
||||
}
|
||||
|
||||
public List<A> diff(List<A> that) {
|
||||
ListBuffer<A> buf = new ListBuffer<>();
|
||||
for (A el : this) {
|
||||
if (!that.contains(el)) {
|
||||
buf.append(el);
|
||||
}
|
||||
}
|
||||
return buf.toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new list from the first {@code n} elements of this list
|
||||
*/
|
||||
public List<A> take(int n) {
|
||||
ListBuffer<A> buf = new ListBuffer<>();
|
||||
int count = 0;
|
||||
for (A el : this) {
|
||||
if (count++ == n) break;
|
||||
buf.append(el);
|
||||
}
|
||||
return buf.toList();
|
||||
}
|
||||
|
||||
/** Construct a list consisting of given element.
|
||||
*/
|
||||
public static <A> List<A> of(A x1) {
|
||||
return new List<A>(x1, List.<A>nil());
|
||||
}
|
||||
|
||||
/** Construct a list consisting of given elements.
|
||||
*/
|
||||
public static <A> List<A> of(A x1, A x2) {
|
||||
return new List<A>(x1, of(x2));
|
||||
}
|
||||
|
||||
/** Construct a list consisting of given elements.
|
||||
*/
|
||||
public static <A> List<A> of(A x1, A x2, A x3) {
|
||||
return new List<A>(x1, of(x2, x3));
|
||||
}
|
||||
|
||||
/** Construct a list consisting of given elements.
|
||||
*/
|
||||
@SuppressWarnings({"varargs", "unchecked"})
|
||||
public static <A> List<A> of(A x1, A x2, A x3, A... rest) {
|
||||
return new List<A>(x1, new List<A>(x2, new List<A>(x3, from(rest))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a list consisting all elements of given array.
|
||||
* @param array an array; if {@code null} return an empty list
|
||||
*/
|
||||
public static <A> List<A> from(A[] array) {
|
||||
List<A> xs = nil();
|
||||
if (array != null)
|
||||
for (int i = array.length - 1; i >= 0; i--)
|
||||
xs = new List<A>(array[i], xs);
|
||||
return xs;
|
||||
}
|
||||
|
||||
public static <A> List<A> from(Iterable<? extends A> coll) {
|
||||
ListBuffer<A> xs = new ListBuffer<>();
|
||||
for (A a : coll) {
|
||||
xs.append(a);
|
||||
}
|
||||
return xs.toList();
|
||||
}
|
||||
|
||||
/** Construct a list consisting of a given number of identical elements.
|
||||
* @param len The number of elements in the list.
|
||||
* @param init The value of each element.
|
||||
*/
|
||||
@Deprecated
|
||||
public static <A> List<A> fill(int len, A init) {
|
||||
List<A> l = nil();
|
||||
for (int i = 0; i < len; i++) l = new List<A>(init, l);
|
||||
return l;
|
||||
}
|
||||
|
||||
/** Does list have no elements?
|
||||
*/
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return tail == null;
|
||||
}
|
||||
|
||||
/** Does list have elements?
|
||||
*/
|
||||
//@Deprecated
|
||||
public boolean nonEmpty() {
|
||||
return tail != null;
|
||||
}
|
||||
|
||||
/** Return the number of elements in this list.
|
||||
*/
|
||||
//@Deprecated
|
||||
public int length() {
|
||||
List<A> l = this;
|
||||
int len = 0;
|
||||
while (l.tail != null) {
|
||||
l = l.tail;
|
||||
len++;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
@Override
|
||||
public int size() {
|
||||
return length();
|
||||
}
|
||||
|
||||
public List<A> setTail(List<A> tail) {
|
||||
this.tail = tail;
|
||||
return tail;
|
||||
}
|
||||
|
||||
/** Prepend given element to front of list, forming and returning
|
||||
* a new list.
|
||||
*/
|
||||
public List<A> prepend(A x) {
|
||||
return new List<A>(x, this);
|
||||
}
|
||||
|
||||
/** Prepend given list of elements to front of list, forming and returning
|
||||
* a new list.
|
||||
*/
|
||||
public List<A> prependList(List<A> xs) {
|
||||
if (this.isEmpty()) return xs;
|
||||
if (xs.isEmpty()) return this;
|
||||
if (xs.tail.isEmpty()) return prepend(xs.head);
|
||||
// return this.prependList(xs.tail).prepend(xs.head);
|
||||
List<A> result = this;
|
||||
List<A> rev = xs.reverse();
|
||||
Assert.check(rev != xs);
|
||||
// since xs.reverse() returned a new list, we can reuse the
|
||||
// individual List objects, instead of allocating new ones.
|
||||
while (rev.nonEmpty()) {
|
||||
List<A> h = rev;
|
||||
rev = rev.tail;
|
||||
h.setTail(result);
|
||||
result = h;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Reverse list.
|
||||
* If the list is empty or a singleton, then the same list is returned.
|
||||
* Otherwise a new list is formed.
|
||||
*/
|
||||
public List<A> reverse() {
|
||||
// if it is empty or a singleton, return itself
|
||||
if (isEmpty() || tail.isEmpty())
|
||||
return this;
|
||||
|
||||
List<A> rev = nil();
|
||||
for (List<A> l = this; l.nonEmpty(); l = l.tail)
|
||||
rev = new List<A>(l.head, rev);
|
||||
return rev;
|
||||
}
|
||||
|
||||
/** Append given element at length, forming and returning
|
||||
* a new list.
|
||||
*/
|
||||
public List<A> append(A x) {
|
||||
return of(x).prependList(this);
|
||||
}
|
||||
|
||||
/** Append given list at length, forming and returning
|
||||
* a new list.
|
||||
*/
|
||||
public List<A> appendList(List<A> x) {
|
||||
return x.prependList(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append given list buffer at length, forming and returning a new
|
||||
* list.
|
||||
*/
|
||||
public List<A> appendList(ListBuffer<A> x) {
|
||||
return appendList(x.toList());
|
||||
}
|
||||
|
||||
/** Copy successive elements of this list into given vector until
|
||||
* list is exhausted or end of vector is reached.
|
||||
*/
|
||||
@Override @SuppressWarnings("unchecked")
|
||||
public <T> T[] toArray(T[] vec) {
|
||||
int i = 0;
|
||||
List<A> l = this;
|
||||
Object[] dest = vec;
|
||||
while (l.nonEmpty() && i < vec.length) {
|
||||
dest[i] = l.head;
|
||||
l = l.tail;
|
||||
i++;
|
||||
}
|
||||
if (l.isEmpty()) {
|
||||
if (i < vec.length)
|
||||
vec[i] = null;
|
||||
return vec;
|
||||
}
|
||||
|
||||
vec = (T[])Array.newInstance(vec.getClass().getComponentType(), size());
|
||||
return toArray(vec);
|
||||
}
|
||||
|
||||
public Object[] toArray() {
|
||||
return toArray(new Object[size()]);
|
||||
}
|
||||
|
||||
/** Form a string listing all elements with given separator character.
|
||||
*/
|
||||
public String toString(String sep) {
|
||||
if (isEmpty()) {
|
||||
return "";
|
||||
} else {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(head);
|
||||
for (List<A> l = tail; l.nonEmpty(); l = l.tail) {
|
||||
buf.append(sep);
|
||||
buf.append(l.head);
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/** Form a string listing all elements with comma as the separator character.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return toString(",");
|
||||
}
|
||||
|
||||
/** Compute a hash code, overrides Object
|
||||
* @see java.util.List#hashCode
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
List<A> l = this;
|
||||
int h = 1;
|
||||
while (l.tail != null) {
|
||||
h = h * 31 + (l.head == null ? 0 : l.head.hashCode());
|
||||
l = l.tail;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
/** Is this list the same as other list?
|
||||
* @see java.util.List#equals
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other instanceof List<?>)
|
||||
return equals(this, (List<?>)other);
|
||||
if (other instanceof java.util.List<?>) {
|
||||
List<A> t = this;
|
||||
Iterator<?> oIter = ((java.util.List<?>) other).iterator();
|
||||
while (t.tail != null && oIter.hasNext()) {
|
||||
Object o = oIter.next();
|
||||
if ( !(t.head == null ? o == null : t.head.equals(o)))
|
||||
return false;
|
||||
t = t.tail;
|
||||
}
|
||||
return (t.isEmpty() && !oIter.hasNext());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Are the two lists the same?
|
||||
*/
|
||||
public static boolean equals(List<?> xs, List<?> ys) {
|
||||
while (xs.tail != null && ys.tail != null) {
|
||||
if (xs.head == null) {
|
||||
if (ys.head != null) return false;
|
||||
} else {
|
||||
if (!xs.head.equals(ys.head)) return false;
|
||||
}
|
||||
xs = xs.tail;
|
||||
ys = ys.tail;
|
||||
}
|
||||
return xs.tail == null && ys.tail == null;
|
||||
}
|
||||
|
||||
/** Does the list contain the specified element?
|
||||
*/
|
||||
@Override
|
||||
public boolean contains(Object x) {
|
||||
List<A> l = this;
|
||||
while (l.tail != null) {
|
||||
if (x == null) {
|
||||
if (l.head == null) return true;
|
||||
} else {
|
||||
if (l.head.equals(x)) return true;
|
||||
}
|
||||
l = l.tail;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** The last element in the list, if any, or null.
|
||||
*/
|
||||
public A last() {
|
||||
A last = null;
|
||||
List<A> t = this;
|
||||
while (t.tail != null) {
|
||||
last = t.head;
|
||||
t = t.tail;
|
||||
}
|
||||
return last;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> List<T> convert(Class<T> klass, List<?> list) {
|
||||
if (list == null)
|
||||
return null;
|
||||
for (Object o : list)
|
||||
klass.cast(o);
|
||||
return (List<T>)list;
|
||||
}
|
||||
|
||||
private static final Iterator<?> EMPTYITERATOR = new Iterator<Object>() {
|
||||
public boolean hasNext() {
|
||||
return false;
|
||||
}
|
||||
public Object next() {
|
||||
throw new java.util.NoSuchElementException();
|
||||
}
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <A> Iterator<A> emptyIterator() {
|
||||
return (Iterator<A>)EMPTYITERATOR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<A> iterator() {
|
||||
if (tail == null)
|
||||
return emptyIterator();
|
||||
return new Iterator<A>() {
|
||||
List<A> elems = List.this;
|
||||
public boolean hasNext() {
|
||||
return elems.tail != null;
|
||||
}
|
||||
public A next() {
|
||||
if (elems.tail == null)
|
||||
throw new NoSuchElementException();
|
||||
A result = elems.head;
|
||||
elems = elems.tail;
|
||||
return result;
|
||||
}
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public A get(int index) {
|
||||
if (index < 0)
|
||||
throw new IndexOutOfBoundsException(String.valueOf(index));
|
||||
|
||||
List<A> l = this;
|
||||
for (int i = index; i-- > 0 && !l.isEmpty(); l = l.tail)
|
||||
;
|
||||
|
||||
if (l.isEmpty())
|
||||
throw new IndexOutOfBoundsException("Index: " + index + ", " +
|
||||
"Size: " + size());
|
||||
return l.head;
|
||||
}
|
||||
|
||||
public boolean addAll(int index, Collection<? extends A> c) {
|
||||
if (c.isEmpty())
|
||||
return false;
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public A set(int index, A element) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void add(int index, A element) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public A remove(int index) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public int indexOf(Object o) {
|
||||
int i = 0;
|
||||
for (List<A> l = this; l.tail != null; l = l.tail, i++) {
|
||||
if (l.head == null ? o == null : l.head.equals(o))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int lastIndexOf(Object o) {
|
||||
int last = -1;
|
||||
int i = 0;
|
||||
for (List<A> l = this; l.tail != null; l = l.tail, i++) {
|
||||
if (l.head == null ? o == null : l.head.equals(o))
|
||||
last = i;
|
||||
}
|
||||
return last;
|
||||
}
|
||||
|
||||
public ListIterator<A> listIterator() {
|
||||
return Collections.unmodifiableList(new ArrayList<A>(this)).listIterator();
|
||||
}
|
||||
|
||||
public ListIterator<A> listIterator(int index) {
|
||||
return Collections.unmodifiableList(new ArrayList<A>(this)).listIterator(index);
|
||||
}
|
||||
|
||||
public java.util.List<A> subList(int fromIndex, int toIndex) {
|
||||
if (fromIndex < 0 || toIndex > size() || fromIndex > toIndex)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
ArrayList<A> a = new ArrayList<A>(toIndex - fromIndex);
|
||||
int i = 0;
|
||||
for (List<A> l = this; l.tail != null; l = l.tail, i++) {
|
||||
if (i == toIndex)
|
||||
break;
|
||||
if (i >= fromIndex)
|
||||
a.add(l.head);
|
||||
}
|
||||
|
||||
return Collections.unmodifiableList(a);
|
||||
}
|
||||
}
|
||||
273
jdkSrc/jdk8/com/sun/tools/javac/util/ListBuffer.java
Normal file
273
jdkSrc/jdk8/com/sun/tools/javac/util/ListBuffer.java
Normal file
@@ -0,0 +1,273 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import java.util.AbstractQueue;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/** A class for constructing lists by appending elements. Modelled after
|
||||
* java.lang.StringBuffer.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class ListBuffer<A> extends AbstractQueue<A> {
|
||||
|
||||
public static <T> ListBuffer<T> of(T x) {
|
||||
ListBuffer<T> lb = new ListBuffer<T>();
|
||||
lb.add(x);
|
||||
return lb;
|
||||
}
|
||||
|
||||
/** The list of elements of this buffer.
|
||||
*/
|
||||
private List<A> elems;
|
||||
|
||||
/** A pointer pointing to the last element of 'elems' containing data,
|
||||
* or null if the list is empty.
|
||||
*/
|
||||
private List<A> last;
|
||||
|
||||
/** The number of element in this buffer.
|
||||
*/
|
||||
private int count;
|
||||
|
||||
/** Has a list been created from this buffer yet?
|
||||
*/
|
||||
private boolean shared;
|
||||
|
||||
/** Create a new initially empty list buffer.
|
||||
*/
|
||||
public ListBuffer() {
|
||||
clear();
|
||||
}
|
||||
|
||||
public final void clear() {
|
||||
this.elems = List.nil();
|
||||
this.last = null;
|
||||
count = 0;
|
||||
shared = false;
|
||||
}
|
||||
|
||||
/** Return the number of elements in this buffer.
|
||||
*/
|
||||
public int length() {
|
||||
return count;
|
||||
}
|
||||
public int size() {
|
||||
return count;
|
||||
}
|
||||
|
||||
/** Is buffer empty?
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return count == 0;
|
||||
}
|
||||
|
||||
/** Is buffer not empty?
|
||||
*/
|
||||
public boolean nonEmpty() {
|
||||
return count != 0;
|
||||
}
|
||||
|
||||
/** Copy list and sets last.
|
||||
*/
|
||||
private void copy() {
|
||||
if (elems.nonEmpty()) {
|
||||
List<A> orig = elems;
|
||||
|
||||
elems = last = List.<A>of(orig.head);
|
||||
|
||||
while ((orig = orig.tail).nonEmpty()) {
|
||||
last.tail = List.<A>of(orig.head);
|
||||
last = last.tail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Prepend an element to buffer.
|
||||
*/
|
||||
public ListBuffer<A> prepend(A x) {
|
||||
elems = elems.prepend(x);
|
||||
if (last == null) last = elems;
|
||||
count++;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Append an element to buffer.
|
||||
*/
|
||||
public ListBuffer<A> append(A x) {
|
||||
x.getClass(); // null check
|
||||
if (shared) copy();
|
||||
List<A> newLast = List.<A>of(x);
|
||||
if (last != null) {
|
||||
last.tail = newLast;
|
||||
last = newLast;
|
||||
} else {
|
||||
elems = last = newLast;
|
||||
}
|
||||
count++;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Append all elements in a list to buffer.
|
||||
*/
|
||||
public ListBuffer<A> appendList(List<A> xs) {
|
||||
while (xs.nonEmpty()) {
|
||||
append(xs.head);
|
||||
xs = xs.tail;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Append all elements in a list to buffer.
|
||||
*/
|
||||
public ListBuffer<A> appendList(ListBuffer<A> xs) {
|
||||
return appendList(xs.toList());
|
||||
}
|
||||
|
||||
/** Append all elements in an array to buffer.
|
||||
*/
|
||||
public ListBuffer<A> appendArray(A[] xs) {
|
||||
for (int i = 0; i < xs.length; i++) {
|
||||
append(xs[i]);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Convert buffer to a list of all its elements.
|
||||
*/
|
||||
public List<A> toList() {
|
||||
shared = true;
|
||||
return elems;
|
||||
}
|
||||
|
||||
/** Does the list contain the specified element?
|
||||
*/
|
||||
public boolean contains(Object x) {
|
||||
return elems.contains(x);
|
||||
}
|
||||
|
||||
/** Convert buffer to an array
|
||||
*/
|
||||
public <T> T[] toArray(T[] vec) {
|
||||
return elems.toArray(vec);
|
||||
}
|
||||
public Object[] toArray() {
|
||||
return toArray(new Object[size()]);
|
||||
}
|
||||
|
||||
/** The first element in this buffer.
|
||||
*/
|
||||
public A first() {
|
||||
return elems.head;
|
||||
}
|
||||
|
||||
/** Return first element in this buffer and remove
|
||||
*/
|
||||
public A next() {
|
||||
A x = elems.head;
|
||||
if (!elems.isEmpty()) {
|
||||
elems = elems.tail;
|
||||
if (elems.isEmpty()) last = null;
|
||||
count--;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
/** An enumeration of all elements in this buffer.
|
||||
*/
|
||||
public Iterator<A> iterator() {
|
||||
return new Iterator<A>() {
|
||||
List<A> elems = ListBuffer.this.elems;
|
||||
public boolean hasNext() {
|
||||
return !elems.isEmpty();
|
||||
}
|
||||
public A next() {
|
||||
if (elems.isEmpty())
|
||||
throw new NoSuchElementException();
|
||||
A elem = elems.head;
|
||||
elems = elems.tail;
|
||||
return elem;
|
||||
}
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public boolean add(A a) {
|
||||
append(a);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean remove(Object o) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public boolean containsAll(Collection<?> c) {
|
||||
for (Object x: c) {
|
||||
if (!contains(x))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean addAll(Collection<? extends A> c) {
|
||||
for (A a: c)
|
||||
append(a);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean removeAll(Collection<?> c) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public boolean retainAll(Collection<?> c) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public boolean offer(A a) {
|
||||
append(a);
|
||||
return true;
|
||||
}
|
||||
|
||||
public A poll() {
|
||||
return next();
|
||||
}
|
||||
|
||||
public A peek() {
|
||||
return first();
|
||||
}
|
||||
|
||||
public A last() {
|
||||
return last != null ? last.head : null;
|
||||
}
|
||||
}
|
||||
738
jdkSrc/jdk8/com/sun/tools/javac/util/Log.java
Normal file
738
jdkSrc/jdk8/com/sun/tools/javac/util/Log.java
Normal file
@@ -0,0 +1,738 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
import javax.tools.DiagnosticListener;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
import com.sun.tools.javac.api.DiagnosticFormatter;
|
||||
import com.sun.tools.javac.main.Main;
|
||||
import com.sun.tools.javac.main.Option;
|
||||
import com.sun.tools.javac.tree.EndPosTable;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
|
||||
|
||||
import static com.sun.tools.javac.main.Option.*;
|
||||
|
||||
/** A class for error logs. Reports errors and warnings, and
|
||||
* keeps track of error numbers and positions.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class Log extends AbstractLog {
|
||||
/** The context key for the log. */
|
||||
public static final Context.Key<Log> logKey
|
||||
= new Context.Key<Log>();
|
||||
|
||||
/** The context key for the output PrintWriter. */
|
||||
public static final Context.Key<PrintWriter> outKey =
|
||||
new Context.Key<PrintWriter>();
|
||||
|
||||
/* TODO: Should unify this with prefix handling in JCDiagnostic.Factory. */
|
||||
public enum PrefixKind {
|
||||
JAVAC("javac."),
|
||||
COMPILER_MISC("compiler.misc.");
|
||||
PrefixKind(String v) {
|
||||
value = v;
|
||||
}
|
||||
public String key(String k) {
|
||||
return value + k;
|
||||
}
|
||||
final String value;
|
||||
}
|
||||
|
||||
/**
|
||||
* DiagnosticHandler's provide the initial handling for diagnostics.
|
||||
* When a diagnostic handler is created and has been initialized, it
|
||||
* should install itself as the current diagnostic handler. When a
|
||||
* client has finished using a handler, the client should call
|
||||
* {@code log.removeDiagnosticHandler();}
|
||||
*
|
||||
* Note that javax.tools.DiagnosticListener (if set) is called later in the
|
||||
* diagnostic pipeline.
|
||||
*/
|
||||
public static abstract class DiagnosticHandler {
|
||||
/**
|
||||
* The previously installed diagnostic handler.
|
||||
*/
|
||||
protected DiagnosticHandler prev;
|
||||
|
||||
/**
|
||||
* Install this diagnostic handler as the current one,
|
||||
* recording the previous one.
|
||||
*/
|
||||
protected void install(Log log) {
|
||||
prev = log.diagnosticHandler;
|
||||
log.diagnosticHandler = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a diagnostic.
|
||||
*/
|
||||
public abstract void report(JCDiagnostic diag);
|
||||
}
|
||||
|
||||
/**
|
||||
* A DiagnosticHandler that discards all diagnostics.
|
||||
*/
|
||||
public static class DiscardDiagnosticHandler extends DiagnosticHandler {
|
||||
public DiscardDiagnosticHandler(Log log) {
|
||||
install(log);
|
||||
}
|
||||
|
||||
public void report(JCDiagnostic diag) { }
|
||||
}
|
||||
|
||||
/**
|
||||
* A DiagnosticHandler that can defer some or all diagnostics,
|
||||
* by buffering them for later examination and/or reporting.
|
||||
* If a diagnostic is not deferred, or is subsequently reported
|
||||
* with reportAllDiagnostics(), it will be reported to the previously
|
||||
* active diagnostic handler.
|
||||
*/
|
||||
public static class DeferredDiagnosticHandler extends DiagnosticHandler {
|
||||
private Queue<JCDiagnostic> deferred = new ListBuffer<>();
|
||||
private final Filter<JCDiagnostic> filter;
|
||||
|
||||
public DeferredDiagnosticHandler(Log log) {
|
||||
this(log, null);
|
||||
}
|
||||
|
||||
public DeferredDiagnosticHandler(Log log, Filter<JCDiagnostic> filter) {
|
||||
this.filter = filter;
|
||||
install(log);
|
||||
}
|
||||
|
||||
public void report(JCDiagnostic diag) {
|
||||
if (!diag.isFlagSet(JCDiagnostic.DiagnosticFlag.NON_DEFERRABLE) &&
|
||||
(filter == null || filter.accepts(diag))) {
|
||||
deferred.add(diag);
|
||||
} else {
|
||||
prev.report(diag);
|
||||
}
|
||||
}
|
||||
|
||||
public Queue<JCDiagnostic> getDiagnostics() {
|
||||
return deferred;
|
||||
}
|
||||
|
||||
/** Report all deferred diagnostics. */
|
||||
public void reportDeferredDiagnostics() {
|
||||
reportDeferredDiagnostics(EnumSet.allOf(JCDiagnostic.Kind.class));
|
||||
}
|
||||
|
||||
/** Report selected deferred diagnostics. */
|
||||
public void reportDeferredDiagnostics(Set<JCDiagnostic.Kind> kinds) {
|
||||
JCDiagnostic d;
|
||||
while ((d = deferred.poll()) != null) {
|
||||
if (kinds.contains(d.getKind()))
|
||||
prev.report(d);
|
||||
}
|
||||
deferred = null; // prevent accidental ongoing use
|
||||
}
|
||||
}
|
||||
|
||||
public enum WriterKind { NOTICE, WARNING, ERROR };
|
||||
|
||||
protected PrintWriter errWriter;
|
||||
|
||||
protected PrintWriter warnWriter;
|
||||
|
||||
protected PrintWriter noticeWriter;
|
||||
|
||||
/** The maximum number of errors/warnings that are reported.
|
||||
*/
|
||||
protected int MaxErrors;
|
||||
protected int MaxWarnings;
|
||||
|
||||
/** Switch: prompt user on each error.
|
||||
*/
|
||||
public boolean promptOnError;
|
||||
|
||||
/** Switch: emit warning messages.
|
||||
*/
|
||||
public boolean emitWarnings;
|
||||
|
||||
/** Switch: suppress note messages.
|
||||
*/
|
||||
public boolean suppressNotes;
|
||||
|
||||
/** Print stack trace on errors?
|
||||
*/
|
||||
public boolean dumpOnError;
|
||||
|
||||
/** Print multiple errors for same source locations.
|
||||
*/
|
||||
public boolean multipleErrors;
|
||||
|
||||
/**
|
||||
* Diagnostic listener, if provided through programmatic
|
||||
* interface to javac (JSR 199).
|
||||
*/
|
||||
protected DiagnosticListener<? super JavaFileObject> diagListener;
|
||||
|
||||
/**
|
||||
* Formatter for diagnostics.
|
||||
*/
|
||||
private DiagnosticFormatter<JCDiagnostic> diagFormatter;
|
||||
|
||||
/**
|
||||
* Keys for expected diagnostics.
|
||||
*/
|
||||
public Set<String> expectDiagKeys;
|
||||
|
||||
/**
|
||||
* Set to true if a compressed diagnostic is reported
|
||||
*/
|
||||
public boolean compressedOutput;
|
||||
|
||||
/**
|
||||
* JavacMessages object used for localization.
|
||||
*/
|
||||
private JavacMessages messages;
|
||||
|
||||
/**
|
||||
* Handler for initial dispatch of diagnostics.
|
||||
*/
|
||||
private DiagnosticHandler diagnosticHandler;
|
||||
|
||||
/** Construct a log with given I/O redirections.
|
||||
*/
|
||||
protected Log(Context context, PrintWriter errWriter, PrintWriter warnWriter, PrintWriter noticeWriter) {
|
||||
super(JCDiagnostic.Factory.instance(context));
|
||||
context.put(logKey, this);
|
||||
this.errWriter = errWriter;
|
||||
this.warnWriter = warnWriter;
|
||||
this.noticeWriter = noticeWriter;
|
||||
|
||||
@SuppressWarnings("unchecked") // FIXME
|
||||
DiagnosticListener<? super JavaFileObject> dl =
|
||||
context.get(DiagnosticListener.class);
|
||||
this.diagListener = dl;
|
||||
|
||||
diagnosticHandler = new DefaultDiagnosticHandler();
|
||||
|
||||
messages = JavacMessages.instance(context);
|
||||
messages.add(Main.javacBundleName);
|
||||
|
||||
final Options options = Options.instance(context);
|
||||
initOptions(options);
|
||||
options.addListener(new Runnable() {
|
||||
public void run() {
|
||||
initOptions(options);
|
||||
}
|
||||
});
|
||||
}
|
||||
// where
|
||||
private void initOptions(Options options) {
|
||||
this.dumpOnError = options.isSet(DOE);
|
||||
this.promptOnError = options.isSet(PROMPT);
|
||||
this.emitWarnings = options.isUnset(XLINT_CUSTOM, "none");
|
||||
this.suppressNotes = options.isSet("suppressNotes");
|
||||
this.MaxErrors = getIntOption(options, XMAXERRS, getDefaultMaxErrors());
|
||||
this.MaxWarnings = getIntOption(options, XMAXWARNS, getDefaultMaxWarnings());
|
||||
|
||||
boolean rawDiagnostics = options.isSet("rawDiagnostics");
|
||||
this.diagFormatter = rawDiagnostics ? new RawDiagnosticFormatter(options) :
|
||||
new BasicDiagnosticFormatter(options, messages);
|
||||
|
||||
String ek = options.get("expectKeys");
|
||||
if (ek != null)
|
||||
expectDiagKeys = new HashSet<String>(Arrays.asList(ek.split(", *")));
|
||||
}
|
||||
|
||||
private int getIntOption(Options options, Option option, int defaultValue) {
|
||||
String s = options.get(option);
|
||||
try {
|
||||
if (s != null) {
|
||||
int n = Integer.parseInt(s);
|
||||
return (n <= 0 ? Integer.MAX_VALUE : n);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
// silently ignore ill-formed numbers
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/** Default value for -Xmaxerrs.
|
||||
*/
|
||||
protected int getDefaultMaxErrors() {
|
||||
return 100;
|
||||
}
|
||||
|
||||
/** Default value for -Xmaxwarns.
|
||||
*/
|
||||
protected int getDefaultMaxWarnings() {
|
||||
return 100;
|
||||
}
|
||||
|
||||
/** The default writer for diagnostics
|
||||
*/
|
||||
static PrintWriter defaultWriter(Context context) {
|
||||
PrintWriter result = context.get(outKey);
|
||||
if (result == null)
|
||||
context.put(outKey, result = new PrintWriter(System.err));
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Construct a log with default settings.
|
||||
*/
|
||||
protected Log(Context context) {
|
||||
this(context, defaultWriter(context));
|
||||
}
|
||||
|
||||
/** Construct a log with all output redirected.
|
||||
*/
|
||||
protected Log(Context context, PrintWriter defaultWriter) {
|
||||
this(context, defaultWriter, defaultWriter, defaultWriter);
|
||||
}
|
||||
|
||||
/** Get the Log instance for this context. */
|
||||
public static Log instance(Context context) {
|
||||
Log instance = context.get(logKey);
|
||||
if (instance == null)
|
||||
instance = new Log(context);
|
||||
return instance;
|
||||
}
|
||||
|
||||
/** The number of errors encountered so far.
|
||||
*/
|
||||
public int nerrors = 0;
|
||||
|
||||
/** The number of warnings encountered so far.
|
||||
*/
|
||||
public int nwarnings = 0;
|
||||
|
||||
/** A set of all errors generated so far. This is used to avoid printing an
|
||||
* error message more than once. For each error, a pair consisting of the
|
||||
* source file name and source code position of the error is added to the set.
|
||||
*/
|
||||
private Set<Pair<JavaFileObject, Integer>> recorded = new HashSet<Pair<JavaFileObject,Integer>>();
|
||||
|
||||
public boolean hasDiagnosticListener() {
|
||||
return diagListener != null;
|
||||
}
|
||||
|
||||
public void setEndPosTable(JavaFileObject name, EndPosTable endPosTable) {
|
||||
name.getClass(); // null check
|
||||
getSource(name).setEndPosTable(endPosTable);
|
||||
}
|
||||
|
||||
/** Return current sourcefile.
|
||||
*/
|
||||
public JavaFileObject currentSourceFile() {
|
||||
return source == null ? null : source.getFile();
|
||||
}
|
||||
|
||||
/** Get the current diagnostic formatter.
|
||||
*/
|
||||
public DiagnosticFormatter<JCDiagnostic> getDiagnosticFormatter() {
|
||||
return diagFormatter;
|
||||
}
|
||||
|
||||
/** Set the current diagnostic formatter.
|
||||
*/
|
||||
public void setDiagnosticFormatter(DiagnosticFormatter<JCDiagnostic> diagFormatter) {
|
||||
this.diagFormatter = diagFormatter;
|
||||
}
|
||||
|
||||
public PrintWriter getWriter(WriterKind kind) {
|
||||
switch (kind) {
|
||||
case NOTICE: return noticeWriter;
|
||||
case WARNING: return warnWriter;
|
||||
case ERROR: return errWriter;
|
||||
default: throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
public void setWriter(WriterKind kind, PrintWriter pw) {
|
||||
pw.getClass();
|
||||
switch (kind) {
|
||||
case NOTICE: noticeWriter = pw; break;
|
||||
case WARNING: warnWriter = pw; break;
|
||||
case ERROR: errWriter = pw; break;
|
||||
default: throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
public void setWriters(PrintWriter pw) {
|
||||
pw.getClass();
|
||||
noticeWriter = warnWriter = errWriter = pw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Propagate the previous log's information.
|
||||
*/
|
||||
public void initRound(Log other) {
|
||||
this.noticeWriter = other.noticeWriter;
|
||||
this.warnWriter = other.warnWriter;
|
||||
this.errWriter = other.errWriter;
|
||||
this.sourceMap = other.sourceMap;
|
||||
this.recorded = other.recorded;
|
||||
this.nerrors = other.nerrors;
|
||||
this.nwarnings = other.nwarnings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the specified diagnostic handler with the
|
||||
* handler that was current at the time this handler was created.
|
||||
* The given handler must be the currently installed handler;
|
||||
* it must be specified explicitly for clarity and consistency checking.
|
||||
*/
|
||||
public void popDiagnosticHandler(DiagnosticHandler h) {
|
||||
Assert.check(diagnosticHandler == h);
|
||||
diagnosticHandler = h.prev;
|
||||
}
|
||||
|
||||
/** Flush the logs
|
||||
*/
|
||||
public void flush() {
|
||||
errWriter.flush();
|
||||
warnWriter.flush();
|
||||
noticeWriter.flush();
|
||||
}
|
||||
|
||||
public void flush(WriterKind kind) {
|
||||
getWriter(kind).flush();
|
||||
}
|
||||
|
||||
/** Returns true if an error needs to be reported for a given
|
||||
* source name and pos.
|
||||
*/
|
||||
protected boolean shouldReport(JavaFileObject file, int pos) {
|
||||
if (multipleErrors || file == null)
|
||||
return true;
|
||||
|
||||
Pair<JavaFileObject,Integer> coords = new Pair<JavaFileObject,Integer>(file, pos);
|
||||
boolean shouldReport = !recorded.contains(coords);
|
||||
if (shouldReport)
|
||||
recorded.add(coords);
|
||||
return shouldReport;
|
||||
}
|
||||
|
||||
/** Prompt user after an error.
|
||||
*/
|
||||
public void prompt() {
|
||||
if (promptOnError) {
|
||||
System.err.println(localize("resume.abort"));
|
||||
try {
|
||||
while (true) {
|
||||
switch (System.in.read()) {
|
||||
case 'a': case 'A':
|
||||
System.exit(-1);
|
||||
return;
|
||||
case 'r': case 'R':
|
||||
return;
|
||||
case 'x': case 'X':
|
||||
throw new AssertionError("user abort");
|
||||
default:
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
}
|
||||
|
||||
/** Print the faulty source code line and point to the error.
|
||||
* @param pos Buffer index of the error position, must be on current line
|
||||
*/
|
||||
private void printErrLine(int pos, PrintWriter writer) {
|
||||
String line = (source == null ? null : source.getLine(pos));
|
||||
if (line == null)
|
||||
return;
|
||||
int col = source.getColumnNumber(pos, false);
|
||||
|
||||
printRawLines(writer, line);
|
||||
for (int i = 0; i < col - 1; i++) {
|
||||
writer.print((line.charAt(i) == '\t') ? "\t" : " ");
|
||||
}
|
||||
writer.println("^");
|
||||
writer.flush();
|
||||
}
|
||||
|
||||
public void printNewline() {
|
||||
noticeWriter.println();
|
||||
}
|
||||
|
||||
public void printNewline(WriterKind wk) {
|
||||
getWriter(wk).println();
|
||||
}
|
||||
|
||||
public void printLines(String key, Object... args) {
|
||||
printRawLines(noticeWriter, localize(key, args));
|
||||
}
|
||||
|
||||
public void printLines(PrefixKind pk, String key, Object... args) {
|
||||
printRawLines(noticeWriter, localize(pk, key, args));
|
||||
}
|
||||
|
||||
public void printLines(WriterKind wk, String key, Object... args) {
|
||||
printRawLines(getWriter(wk), localize(key, args));
|
||||
}
|
||||
|
||||
public void printLines(WriterKind wk, PrefixKind pk, String key, Object... args) {
|
||||
printRawLines(getWriter(wk), localize(pk, key, args));
|
||||
}
|
||||
|
||||
/** Print the text of a message, translating newlines appropriately
|
||||
* for the platform.
|
||||
*/
|
||||
public void printRawLines(String msg) {
|
||||
printRawLines(noticeWriter, msg);
|
||||
}
|
||||
|
||||
/** Print the text of a message, translating newlines appropriately
|
||||
* for the platform.
|
||||
*/
|
||||
public void printRawLines(WriterKind kind, String msg) {
|
||||
printRawLines(getWriter(kind), msg);
|
||||
}
|
||||
|
||||
/** Print the text of a message, translating newlines appropriately
|
||||
* for the platform.
|
||||
*/
|
||||
public static void printRawLines(PrintWriter writer, String msg) {
|
||||
int nl;
|
||||
while ((nl = msg.indexOf('\n')) != -1) {
|
||||
writer.println(msg.substring(0, nl));
|
||||
msg = msg.substring(nl+1);
|
||||
}
|
||||
if (msg.length() != 0) writer.println(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the localized text of a "verbose" message to the
|
||||
* noticeWriter stream.
|
||||
*/
|
||||
public void printVerbose(String key, Object... args) {
|
||||
printRawLines(noticeWriter, localize("verbose." + key, args));
|
||||
}
|
||||
|
||||
protected void directError(String key, Object... args) {
|
||||
printRawLines(errWriter, localize(key, args));
|
||||
errWriter.flush();
|
||||
}
|
||||
|
||||
/** Report a warning that cannot be suppressed.
|
||||
* @param pos The source position at which to report the warning.
|
||||
* @param key The key for the localized warning message.
|
||||
* @param args Fields of the warning message.
|
||||
*/
|
||||
public void strictWarning(DiagnosticPosition pos, String key, Object ... args) {
|
||||
writeDiagnostic(diags.warning(source, pos, key, args));
|
||||
nwarnings++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Primary method to report a diagnostic.
|
||||
* @param diagnostic
|
||||
*/
|
||||
public void report(JCDiagnostic diagnostic) {
|
||||
diagnosticHandler.report(diagnostic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Common diagnostic handling.
|
||||
* The diagnostic is counted, and depending on the options and how many diagnostics have been
|
||||
* reported so far, the diagnostic may be handed off to writeDiagnostic.
|
||||
*/
|
||||
private class DefaultDiagnosticHandler extends DiagnosticHandler {
|
||||
public void report(JCDiagnostic diagnostic) {
|
||||
if (expectDiagKeys != null)
|
||||
expectDiagKeys.remove(diagnostic.getCode());
|
||||
|
||||
switch (diagnostic.getType()) {
|
||||
case FRAGMENT:
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
case NOTE:
|
||||
// Print out notes only when we are permitted to report warnings
|
||||
// Notes are only generated at the end of a compilation, so should be small
|
||||
// in number.
|
||||
if ((emitWarnings || diagnostic.isMandatory()) && !suppressNotes) {
|
||||
writeDiagnostic(diagnostic);
|
||||
}
|
||||
break;
|
||||
|
||||
case WARNING:
|
||||
if (emitWarnings || diagnostic.isMandatory()) {
|
||||
if (nwarnings < MaxWarnings) {
|
||||
writeDiagnostic(diagnostic);
|
||||
nwarnings++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ERROR:
|
||||
if (nerrors < MaxErrors
|
||||
&& shouldReport(diagnostic.getSource(), diagnostic.getIntPosition())) {
|
||||
writeDiagnostic(diagnostic);
|
||||
nerrors++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (diagnostic.isFlagSet(JCDiagnostic.DiagnosticFlag.COMPRESSED)) {
|
||||
compressedOutput = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write out a diagnostic.
|
||||
*/
|
||||
protected void writeDiagnostic(JCDiagnostic diag) {
|
||||
if (diagListener != null) {
|
||||
diagListener.report(diag);
|
||||
return;
|
||||
}
|
||||
|
||||
PrintWriter writer = getWriterForDiagnosticType(diag.getType());
|
||||
|
||||
printRawLines(writer, diagFormatter.format(diag, messages.getCurrentLocale()));
|
||||
|
||||
if (promptOnError) {
|
||||
switch (diag.getType()) {
|
||||
case ERROR:
|
||||
case WARNING:
|
||||
prompt();
|
||||
}
|
||||
}
|
||||
|
||||
if (dumpOnError)
|
||||
new RuntimeException().printStackTrace(writer);
|
||||
|
||||
writer.flush();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
protected PrintWriter getWriterForDiagnosticType(DiagnosticType dt) {
|
||||
switch (dt) {
|
||||
case FRAGMENT:
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
case NOTE:
|
||||
return noticeWriter;
|
||||
|
||||
case WARNING:
|
||||
return warnWriter;
|
||||
|
||||
case ERROR:
|
||||
return errWriter;
|
||||
|
||||
default:
|
||||
throw new Error();
|
||||
}
|
||||
}
|
||||
|
||||
/** Find a localized string in the resource bundle.
|
||||
* Because this method is static, it ignores the locale.
|
||||
* Use localize(key, args) when possible.
|
||||
* @param key The key for the localized string.
|
||||
* @param args Fields to substitute into the string.
|
||||
*/
|
||||
public static String getLocalizedString(String key, Object ... args) {
|
||||
return JavacMessages.getDefaultLocalizedString(PrefixKind.COMPILER_MISC.key(key), args);
|
||||
}
|
||||
|
||||
/** Find a localized string in the resource bundle.
|
||||
* @param key The key for the localized string.
|
||||
* @param args Fields to substitute into the string.
|
||||
*/
|
||||
public String localize(String key, Object... args) {
|
||||
return localize(PrefixKind.COMPILER_MISC, key, args);
|
||||
}
|
||||
|
||||
/** Find a localized string in the resource bundle.
|
||||
* @param key The key for the localized string.
|
||||
* @param args Fields to substitute into the string.
|
||||
*/
|
||||
public String localize(PrefixKind pk, String key, Object... args) {
|
||||
if (useRawMessages)
|
||||
return pk.key(key);
|
||||
else
|
||||
return messages.getLocalizedString(pk.key(key), args);
|
||||
}
|
||||
// where
|
||||
// backdoor hook for testing, should transition to use -XDrawDiagnostics
|
||||
private static boolean useRawMessages = false;
|
||||
|
||||
/***************************************************************************
|
||||
* raw error messages without internationalization; used for experimentation
|
||||
* and quick prototyping
|
||||
***************************************************************************/
|
||||
|
||||
/** print an error or warning message:
|
||||
*/
|
||||
private void printRawError(int pos, String msg) {
|
||||
if (source == null || pos == Position.NOPOS) {
|
||||
printRawLines(errWriter, "error: " + msg);
|
||||
} else {
|
||||
int line = source.getLineNumber(pos);
|
||||
JavaFileObject file = source.getFile();
|
||||
if (file != null)
|
||||
printRawLines(errWriter,
|
||||
file.getName() + ":" +
|
||||
line + ": " + msg);
|
||||
printErrLine(pos, errWriter);
|
||||
}
|
||||
errWriter.flush();
|
||||
}
|
||||
|
||||
/** report an error:
|
||||
*/
|
||||
public void rawError(int pos, String msg) {
|
||||
if (nerrors < MaxErrors && shouldReport(currentSourceFile(), pos)) {
|
||||
printRawError(pos, msg);
|
||||
prompt();
|
||||
nerrors++;
|
||||
}
|
||||
errWriter.flush();
|
||||
}
|
||||
|
||||
/** report a warning:
|
||||
*/
|
||||
public void rawWarning(int pos, String msg) {
|
||||
if (nwarnings < MaxWarnings && emitWarnings) {
|
||||
printRawError(pos, "warning: " + msg);
|
||||
}
|
||||
prompt();
|
||||
nwarnings++;
|
||||
errWriter.flush();
|
||||
}
|
||||
|
||||
public static String format(String fmt, Object... args) {
|
||||
return String.format((java.util.Locale)null, fmt, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
import com.sun.tools.javac.code.Lint.LintCategory;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
|
||||
|
||||
|
||||
/**
|
||||
* A handler to process mandatory warnings, setting up a deferred diagnostic
|
||||
* to be printed at the end of the compilation if some warnings get suppressed
|
||||
* because too many warnings have already been generated.
|
||||
*
|
||||
* Note that the SuppressWarnings annotation can be used to suppress warnings
|
||||
* about conditions that would otherwise merit a warning. Such processing
|
||||
* is done when the condition is detected, and in those cases, no call is
|
||||
* made on any API to generate a warning at all. In consequence, this handler only
|
||||
* gets to handle those warnings that JLS says must be generated.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class MandatoryWarningHandler {
|
||||
|
||||
/**
|
||||
* The kinds of different deferred diagnostics that might be generated
|
||||
* if a mandatory warning is suppressed because too many warnings have
|
||||
* already been output.
|
||||
*
|
||||
* The parameter is a fragment used to build an I18N message key for Log.
|
||||
*/
|
||||
private enum DeferredDiagnosticKind {
|
||||
/**
|
||||
* This kind is used when a single specific file is found to have warnings
|
||||
* and no similar warnings have already been given.
|
||||
* It generates a message like:
|
||||
* FILE has ISSUES
|
||||
*/
|
||||
IN_FILE(".filename"),
|
||||
/**
|
||||
* This kind is used when a single specific file is found to have warnings
|
||||
* and when similar warnings have already been reported for the file.
|
||||
* It generates a message like:
|
||||
* FILE has additional ISSUES
|
||||
*/
|
||||
ADDITIONAL_IN_FILE(".filename.additional"),
|
||||
/**
|
||||
* This kind is used when multiple files have been found to have warnings,
|
||||
* and none of them have had any similar warnings.
|
||||
* It generates a message like:
|
||||
* Some files have ISSUES
|
||||
*/
|
||||
IN_FILES(".plural"),
|
||||
/**
|
||||
* This kind is used when multiple files have been found to have warnings,
|
||||
* and some of them have had already had specific similar warnings.
|
||||
* It generates a message like:
|
||||
* Some files have additional ISSUES
|
||||
*/
|
||||
ADDITIONAL_IN_FILES(".plural.additional");
|
||||
|
||||
DeferredDiagnosticKind(String v) { value = v; }
|
||||
String getKey(String prefix) { return prefix + value; }
|
||||
|
||||
private final String value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a handler for mandatory warnings.
|
||||
* @param log The log on which to generate any diagnostics
|
||||
* @param verbose Specify whether or not detailed messages about
|
||||
* individual instances should be given, or whether an aggregate
|
||||
* message should be generated at the end of the compilation.
|
||||
* Typically set via -Xlint:option.
|
||||
* @param enforceMandatory
|
||||
* True if mandatory warnings and notes are being enforced.
|
||||
* @param prefix A common prefix for the set of message keys for
|
||||
* the messages that may be generated.
|
||||
* @param lc An associated lint category for the warnings, or null if none.
|
||||
*/
|
||||
public MandatoryWarningHandler(Log log, boolean verbose,
|
||||
boolean enforceMandatory, String prefix,
|
||||
LintCategory lc) {
|
||||
this.log = log;
|
||||
this.verbose = verbose;
|
||||
this.prefix = prefix;
|
||||
this.enforceMandatory = enforceMandatory;
|
||||
this.lintCategory = lc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Report a mandatory warning.
|
||||
*/
|
||||
public void report(DiagnosticPosition pos, String msg, Object... args) {
|
||||
JavaFileObject currentSource = log.currentSourceFile();
|
||||
|
||||
if (verbose) {
|
||||
if (sourcesWithReportedWarnings == null)
|
||||
sourcesWithReportedWarnings = new HashSet<JavaFileObject>();
|
||||
|
||||
if (log.nwarnings < log.MaxWarnings) {
|
||||
// generate message and remember the source file
|
||||
logMandatoryWarning(pos, msg, args);
|
||||
sourcesWithReportedWarnings.add(currentSource);
|
||||
} else if (deferredDiagnosticKind == null) {
|
||||
// set up deferred message
|
||||
if (sourcesWithReportedWarnings.contains(currentSource)) {
|
||||
// more errors in a file that already has reported warnings
|
||||
deferredDiagnosticKind = DeferredDiagnosticKind.ADDITIONAL_IN_FILE;
|
||||
} else {
|
||||
// warnings in a new source file
|
||||
deferredDiagnosticKind = DeferredDiagnosticKind.IN_FILE;
|
||||
}
|
||||
deferredDiagnosticSource = currentSource;
|
||||
deferredDiagnosticArg = currentSource;
|
||||
} else if ((deferredDiagnosticKind == DeferredDiagnosticKind.IN_FILE
|
||||
|| deferredDiagnosticKind == DeferredDiagnosticKind.ADDITIONAL_IN_FILE)
|
||||
&& !equal(deferredDiagnosticSource, currentSource)) {
|
||||
// additional errors in more than one source file
|
||||
deferredDiagnosticKind = DeferredDiagnosticKind.ADDITIONAL_IN_FILES;
|
||||
deferredDiagnosticArg = null;
|
||||
}
|
||||
} else {
|
||||
if (deferredDiagnosticKind == null) {
|
||||
// warnings in a single source
|
||||
deferredDiagnosticKind = DeferredDiagnosticKind.IN_FILE;
|
||||
deferredDiagnosticSource = currentSource;
|
||||
deferredDiagnosticArg = currentSource;
|
||||
} else if (deferredDiagnosticKind == DeferredDiagnosticKind.IN_FILE &&
|
||||
!equal(deferredDiagnosticSource, currentSource)) {
|
||||
// warnings in multiple source files
|
||||
deferredDiagnosticKind = DeferredDiagnosticKind.IN_FILES;
|
||||
deferredDiagnosticArg = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Report any diagnostic that might have been deferred by previous calls of report().
|
||||
*/
|
||||
public void reportDeferredDiagnostic() {
|
||||
if (deferredDiagnosticKind != null) {
|
||||
if (deferredDiagnosticArg == null)
|
||||
logMandatoryNote(deferredDiagnosticSource, deferredDiagnosticKind.getKey(prefix));
|
||||
else
|
||||
logMandatoryNote(deferredDiagnosticSource, deferredDiagnosticKind.getKey(prefix), deferredDiagnosticArg);
|
||||
|
||||
if (!verbose)
|
||||
logMandatoryNote(deferredDiagnosticSource, prefix + ".recompile");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check two objects, each possibly null, are either both null or are equal.
|
||||
*/
|
||||
private static boolean equal(Object o1, Object o2) {
|
||||
return ((o1 == null || o2 == null) ? (o1 == o2) : o1.equals(o2));
|
||||
}
|
||||
|
||||
/**
|
||||
* The log to which to report warnings.
|
||||
*/
|
||||
private Log log;
|
||||
|
||||
/**
|
||||
* Whether or not to report individual warnings, or simply to report a
|
||||
* single aggregate warning at the end of the compilation.
|
||||
*/
|
||||
private boolean verbose;
|
||||
|
||||
/**
|
||||
* The common prefix for all I18N message keys generated by this handler.
|
||||
*/
|
||||
private String prefix;
|
||||
|
||||
/**
|
||||
* A set containing the names of the source files for which specific
|
||||
* warnings have been generated -- i.e. in verbose mode. If a source name
|
||||
* appears in this list, then deferred diagnostics will be phrased to
|
||||
* include "additionally"...
|
||||
*/
|
||||
private Set<JavaFileObject> sourcesWithReportedWarnings;
|
||||
|
||||
/**
|
||||
* A variable indicating the latest best guess at what the final
|
||||
* deferred diagnostic will be. Initially as specific and helpful
|
||||
* as possible, as more warnings are reported, the scope of the
|
||||
* diagnostic will be broadened.
|
||||
*/
|
||||
private DeferredDiagnosticKind deferredDiagnosticKind;
|
||||
|
||||
/**
|
||||
* If deferredDiagnosticKind is IN_FILE or ADDITIONAL_IN_FILE, this variable
|
||||
* gives the value of log.currentSource() for the file in question.
|
||||
*/
|
||||
private JavaFileObject deferredDiagnosticSource;
|
||||
|
||||
/**
|
||||
* An optional argument to be used when constructing the
|
||||
* deferred diagnostic message, based on deferredDiagnosticKind.
|
||||
* This variable should normally be set/updated whenever
|
||||
* deferredDiagnosticKind is updated.
|
||||
*/
|
||||
private Object deferredDiagnosticArg;
|
||||
|
||||
/**
|
||||
* True if mandatory warnings and notes are being enforced.
|
||||
*/
|
||||
private final boolean enforceMandatory;
|
||||
|
||||
/**
|
||||
* A LintCategory to be included in point-of-use diagnostics to indicate
|
||||
* how messages might be suppressed (i.e. with @SuppressWarnings).
|
||||
*/
|
||||
private final LintCategory lintCategory;
|
||||
|
||||
/**
|
||||
* Reports a mandatory warning to the log. If mandatory warnings
|
||||
* are not being enforced, treat this as an ordinary warning.
|
||||
*/
|
||||
private void logMandatoryWarning(DiagnosticPosition pos, String msg,
|
||||
Object... args) {
|
||||
// Note: the following log methods are safe if lintCategory is null.
|
||||
if (enforceMandatory)
|
||||
log.mandatoryWarning(lintCategory, pos, msg, args);
|
||||
else
|
||||
log.warning(lintCategory, pos, msg, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports a mandatory note to the log. If mandatory notes are
|
||||
* not being enforced, treat this as an ordinary note.
|
||||
*/
|
||||
private void logMandatoryNote(JavaFileObject file, String msg, Object... args) {
|
||||
if (enforceMandatory)
|
||||
log.mandatoryNote(file, msg, args);
|
||||
else
|
||||
log.note(file, msg, args);
|
||||
}
|
||||
}
|
||||
247
jdkSrc/jdk8/com/sun/tools/javac/util/Name.java
Normal file
247
jdkSrc/jdk8/com/sun/tools/javac/util/Name.java
Normal file
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
/** An abstraction for internal compiler strings. They are stored in
|
||||
* Utf8 format. Names are stored in a Name.Table, and are unique within
|
||||
* that table.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public abstract class Name implements javax.lang.model.element.Name {
|
||||
|
||||
public final Table table;
|
||||
|
||||
protected Name(Table table) {
|
||||
this.table = table;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public boolean contentEquals(CharSequence cs) {
|
||||
return toString().equals(cs.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public int length() {
|
||||
return toString().length();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public char charAt(int index) {
|
||||
return toString().charAt(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public CharSequence subSequence(int start, int end) {
|
||||
return toString().subSequence(start, end);
|
||||
}
|
||||
|
||||
/** Return the concatenation of this name and name `n'.
|
||||
*/
|
||||
public Name append(Name n) {
|
||||
int len = getByteLength();
|
||||
byte[] bs = new byte[len + n.getByteLength()];
|
||||
getBytes(bs, 0);
|
||||
n.getBytes(bs, len);
|
||||
return table.fromUtf(bs, 0, bs.length);
|
||||
}
|
||||
|
||||
/** Return the concatenation of this name, the given ASCII
|
||||
* character, and name `n'.
|
||||
*/
|
||||
public Name append(char c, Name n) {
|
||||
int len = getByteLength();
|
||||
byte[] bs = new byte[len + 1 + n.getByteLength()];
|
||||
getBytes(bs, 0);
|
||||
bs[len] = (byte) c;
|
||||
n.getBytes(bs, len+1);
|
||||
return table.fromUtf(bs, 0, bs.length);
|
||||
}
|
||||
|
||||
/** An arbitrary but consistent complete order among all Names.
|
||||
*/
|
||||
public int compareTo(Name other) {
|
||||
return other.getIndex() - this.getIndex();
|
||||
}
|
||||
|
||||
/** Return true if this is the empty name.
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return getByteLength() == 0;
|
||||
}
|
||||
|
||||
/** Returns last occurrence of byte b in this name, -1 if not found.
|
||||
*/
|
||||
public int lastIndexOf(byte b) {
|
||||
byte[] bytes = getByteArray();
|
||||
int offset = getByteOffset();
|
||||
int i = getByteLength() - 1;
|
||||
while (i >= 0 && bytes[offset + i] != b) i--;
|
||||
return i;
|
||||
}
|
||||
|
||||
/** Does this name start with prefix?
|
||||
*/
|
||||
public boolean startsWith(Name prefix) {
|
||||
byte[] thisBytes = this.getByteArray();
|
||||
int thisOffset = this.getByteOffset();
|
||||
int thisLength = this.getByteLength();
|
||||
byte[] prefixBytes = prefix.getByteArray();
|
||||
int prefixOffset = prefix.getByteOffset();
|
||||
int prefixLength = prefix.getByteLength();
|
||||
|
||||
int i = 0;
|
||||
while (i < prefixLength &&
|
||||
i < thisLength &&
|
||||
thisBytes[thisOffset + i] == prefixBytes[prefixOffset + i])
|
||||
i++;
|
||||
return i == prefixLength;
|
||||
}
|
||||
|
||||
/** Returns the sub-name starting at position start, up to and
|
||||
* excluding position end.
|
||||
*/
|
||||
public Name subName(int start, int end) {
|
||||
if (end < start) end = start;
|
||||
return table.fromUtf(getByteArray(), getByteOffset() + start, end - start);
|
||||
}
|
||||
|
||||
/** Return the string representation of this name.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return Convert.utf2string(getByteArray(), getByteOffset(), getByteLength());
|
||||
}
|
||||
|
||||
/** Return the Utf8 representation of this name.
|
||||
*/
|
||||
public byte[] toUtf() {
|
||||
byte[] bs = new byte[getByteLength()];
|
||||
getBytes(bs, 0);
|
||||
return bs;
|
||||
}
|
||||
|
||||
/* Get a "reasonably small" value that uniquely identifies this name
|
||||
* within its name table.
|
||||
*/
|
||||
public abstract int getIndex();
|
||||
|
||||
/** Get the length (in bytes) of this name.
|
||||
*/
|
||||
public abstract int getByteLength();
|
||||
|
||||
/** Returns i'th byte of this name.
|
||||
*/
|
||||
public abstract byte getByteAt(int i);
|
||||
|
||||
/** Copy all bytes of this name to buffer cs, starting at start.
|
||||
*/
|
||||
public void getBytes(byte cs[], int start) {
|
||||
System.arraycopy(getByteArray(), getByteOffset(), cs, start, getByteLength());
|
||||
}
|
||||
|
||||
/** Get the underlying byte array for this name. The contents of the
|
||||
* array must not be modified.
|
||||
*/
|
||||
public abstract byte[] getByteArray();
|
||||
|
||||
/** Get the start offset of this name within its byte array.
|
||||
*/
|
||||
public abstract int getByteOffset();
|
||||
|
||||
/** An abstraction for the hash table used to create unique Name instances.
|
||||
*/
|
||||
public static abstract class Table {
|
||||
/** Standard name table.
|
||||
*/
|
||||
public final Names names;
|
||||
|
||||
Table(Names names) {
|
||||
this.names = names;
|
||||
}
|
||||
|
||||
/** Get the name from the characters in cs[start..start+len-1].
|
||||
*/
|
||||
public abstract Name fromChars(char[] cs, int start, int len);
|
||||
|
||||
/** Get the name for the characters in string s.
|
||||
*/
|
||||
public Name fromString(String s) {
|
||||
char[] cs = s.toCharArray();
|
||||
return fromChars(cs, 0, cs.length);
|
||||
}
|
||||
|
||||
/** Get the name for the bytes in array cs.
|
||||
* Assume that bytes are in utf8 format.
|
||||
*/
|
||||
public Name fromUtf(byte[] cs) {
|
||||
return fromUtf(cs, 0, cs.length);
|
||||
}
|
||||
|
||||
/** get the name for the bytes in cs[start..start+len-1].
|
||||
* Assume that bytes are in utf8 format.
|
||||
*/
|
||||
public abstract Name fromUtf(byte[] cs, int start, int len);
|
||||
|
||||
/** Release any resources used by this table.
|
||||
*/
|
||||
public abstract void dispose();
|
||||
|
||||
/** The hashcode of a name.
|
||||
*/
|
||||
protected static int hashValue(byte bytes[], int offset, int length) {
|
||||
int h = 0;
|
||||
int off = offset;
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
h = (h << 5) - h + bytes[off++];
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
/** Compare two subarrays
|
||||
*/
|
||||
protected static boolean equals(byte[] bytes1, int offset1,
|
||||
byte[] bytes2, int offset2, int length) {
|
||||
int i = 0;
|
||||
while (i < length && bytes1[offset1 + i] == bytes2[offset2 + i]) {
|
||||
i++;
|
||||
}
|
||||
return i == length;
|
||||
}
|
||||
}
|
||||
}
|
||||
346
jdkSrc/jdk8/com/sun/tools/javac/util/Names.java
Normal file
346
jdkSrc/jdk8/com/sun/tools/javac/util/Names.java
Normal file
@@ -0,0 +1,346 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
/**
|
||||
* Access to the compiler's name table. STandard names are defined,
|
||||
* as well as methods to create new names.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class Names {
|
||||
|
||||
public static final Context.Key<Names> namesKey = new Context.Key<Names>();
|
||||
|
||||
public static Names instance(Context context) {
|
||||
Names instance = context.get(namesKey);
|
||||
if (instance == null) {
|
||||
instance = new Names(context);
|
||||
context.put(namesKey, instance);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
// operators and punctuation
|
||||
public final Name asterisk;
|
||||
public final Name comma;
|
||||
public final Name empty;
|
||||
public final Name hyphen;
|
||||
public final Name one;
|
||||
public final Name period;
|
||||
public final Name semicolon;
|
||||
public final Name slash;
|
||||
public final Name slashequals;
|
||||
|
||||
// keywords
|
||||
public final Name _class;
|
||||
public final Name _default;
|
||||
public final Name _super;
|
||||
public final Name _this;
|
||||
|
||||
// field and method names
|
||||
public final Name _name;
|
||||
public final Name addSuppressed;
|
||||
public final Name any;
|
||||
public final Name append;
|
||||
public final Name clinit;
|
||||
public final Name clone;
|
||||
public final Name close;
|
||||
public final Name compareTo;
|
||||
public final Name deserializeLambda;
|
||||
public final Name desiredAssertionStatus;
|
||||
public final Name equals;
|
||||
public final Name error;
|
||||
public final Name family;
|
||||
public final Name finalize;
|
||||
public final Name forName;
|
||||
public final Name getClass;
|
||||
public final Name getClassLoader;
|
||||
public final Name getComponentType;
|
||||
public final Name getDeclaringClass;
|
||||
public final Name getMessage;
|
||||
public final Name hasNext;
|
||||
public final Name hashCode;
|
||||
public final Name init;
|
||||
public final Name initCause;
|
||||
public final Name iterator;
|
||||
public final Name length;
|
||||
public final Name next;
|
||||
public final Name ordinal;
|
||||
public final Name serialVersionUID;
|
||||
public final Name toString;
|
||||
public final Name value;
|
||||
public final Name valueOf;
|
||||
public final Name values;
|
||||
|
||||
// class names
|
||||
public final Name java_io_Serializable;
|
||||
public final Name java_lang_AutoCloseable;
|
||||
public final Name java_lang_Class;
|
||||
public final Name java_lang_Cloneable;
|
||||
public final Name java_lang_Enum;
|
||||
public final Name java_lang_Object;
|
||||
public final Name java_lang_invoke_MethodHandle;
|
||||
|
||||
// names of builtin classes
|
||||
public final Name Array;
|
||||
public final Name Bound;
|
||||
public final Name Method;
|
||||
|
||||
// package names
|
||||
public final Name java_lang;
|
||||
|
||||
// attribute names
|
||||
public final Name Annotation;
|
||||
public final Name AnnotationDefault;
|
||||
public final Name BootstrapMethods;
|
||||
public final Name Bridge;
|
||||
public final Name CharacterRangeTable;
|
||||
public final Name Code;
|
||||
public final Name CompilationID;
|
||||
public final Name ConstantValue;
|
||||
public final Name Deprecated;
|
||||
public final Name EnclosingMethod;
|
||||
public final Name Enum;
|
||||
public final Name Exceptions;
|
||||
public final Name InnerClasses;
|
||||
public final Name LineNumberTable;
|
||||
public final Name LocalVariableTable;
|
||||
public final Name LocalVariableTypeTable;
|
||||
public final Name MethodParameters;
|
||||
public final Name RuntimeInvisibleAnnotations;
|
||||
public final Name RuntimeInvisibleParameterAnnotations;
|
||||
public final Name RuntimeInvisibleTypeAnnotations;
|
||||
public final Name RuntimeVisibleAnnotations;
|
||||
public final Name RuntimeVisibleParameterAnnotations;
|
||||
public final Name RuntimeVisibleTypeAnnotations;
|
||||
public final Name Signature;
|
||||
public final Name SourceFile;
|
||||
public final Name SourceID;
|
||||
public final Name StackMap;
|
||||
public final Name StackMapTable;
|
||||
public final Name Synthetic;
|
||||
public final Name Value;
|
||||
public final Name Varargs;
|
||||
|
||||
// members of java.lang.annotation.ElementType
|
||||
public final Name ANNOTATION_TYPE;
|
||||
public final Name CONSTRUCTOR;
|
||||
public final Name FIELD;
|
||||
public final Name LOCAL_VARIABLE;
|
||||
public final Name METHOD;
|
||||
public final Name PACKAGE;
|
||||
public final Name PARAMETER;
|
||||
public final Name TYPE;
|
||||
public final Name TYPE_PARAMETER;
|
||||
public final Name TYPE_USE;
|
||||
|
||||
// members of java.lang.annotation.RetentionPolicy
|
||||
public final Name CLASS;
|
||||
public final Name RUNTIME;
|
||||
public final Name SOURCE;
|
||||
|
||||
// other identifiers
|
||||
public final Name T;
|
||||
public final Name deprecated;
|
||||
public final Name ex;
|
||||
public final Name package_info;
|
||||
|
||||
//lambda-related
|
||||
public final Name lambda;
|
||||
public final Name metafactory;
|
||||
public final Name altMetafactory;
|
||||
public final Name dollarThis;
|
||||
|
||||
public final Name.Table table;
|
||||
|
||||
public Names(Context context) {
|
||||
Options options = Options.instance(context);
|
||||
table = createTable(options);
|
||||
|
||||
// operators and punctuation
|
||||
asterisk = fromString("*");
|
||||
comma = fromString(",");
|
||||
empty = fromString("");
|
||||
hyphen = fromString("-");
|
||||
one = fromString("1");
|
||||
period = fromString(".");
|
||||
semicolon = fromString(";");
|
||||
slash = fromString("/");
|
||||
slashequals = fromString("/=");
|
||||
|
||||
// keywords
|
||||
_class = fromString("class");
|
||||
_default = fromString("default");
|
||||
_super = fromString("super");
|
||||
_this = fromString("this");
|
||||
|
||||
// field and method names
|
||||
_name = fromString("name");
|
||||
addSuppressed = fromString("addSuppressed");
|
||||
any = fromString("<any>");
|
||||
append = fromString("append");
|
||||
clinit = fromString("<clinit>");
|
||||
clone = fromString("clone");
|
||||
close = fromString("close");
|
||||
compareTo = fromString("compareTo");
|
||||
deserializeLambda = fromString("$deserializeLambda$");
|
||||
desiredAssertionStatus = fromString("desiredAssertionStatus");
|
||||
equals = fromString("equals");
|
||||
error = fromString("<error>");
|
||||
family = fromString("family");
|
||||
finalize = fromString("finalize");
|
||||
forName = fromString("forName");
|
||||
getClass = fromString("getClass");
|
||||
getClassLoader = fromString("getClassLoader");
|
||||
getComponentType = fromString("getComponentType");
|
||||
getDeclaringClass = fromString("getDeclaringClass");
|
||||
getMessage = fromString("getMessage");
|
||||
hasNext = fromString("hasNext");
|
||||
hashCode = fromString("hashCode");
|
||||
init = fromString("<init>");
|
||||
initCause = fromString("initCause");
|
||||
iterator = fromString("iterator");
|
||||
length = fromString("length");
|
||||
next = fromString("next");
|
||||
ordinal = fromString("ordinal");
|
||||
serialVersionUID = fromString("serialVersionUID");
|
||||
toString = fromString("toString");
|
||||
value = fromString("value");
|
||||
valueOf = fromString("valueOf");
|
||||
values = fromString("values");
|
||||
dollarThis = fromString("$this");
|
||||
|
||||
// class names
|
||||
java_io_Serializable = fromString("java.io.Serializable");
|
||||
java_lang_AutoCloseable = fromString("java.lang.AutoCloseable");
|
||||
java_lang_Class = fromString("java.lang.Class");
|
||||
java_lang_Cloneable = fromString("java.lang.Cloneable");
|
||||
java_lang_Enum = fromString("java.lang.Enum");
|
||||
java_lang_Object = fromString("java.lang.Object");
|
||||
java_lang_invoke_MethodHandle = fromString("java.lang.invoke.MethodHandle");
|
||||
|
||||
// names of builtin classes
|
||||
Array = fromString("Array");
|
||||
Bound = fromString("Bound");
|
||||
Method = fromString("Method");
|
||||
|
||||
// package names
|
||||
java_lang = fromString("java.lang");
|
||||
|
||||
// attribute names
|
||||
Annotation = fromString("Annotation");
|
||||
AnnotationDefault = fromString("AnnotationDefault");
|
||||
BootstrapMethods = fromString("BootstrapMethods");
|
||||
Bridge = fromString("Bridge");
|
||||
CharacterRangeTable = fromString("CharacterRangeTable");
|
||||
Code = fromString("Code");
|
||||
CompilationID = fromString("CompilationID");
|
||||
ConstantValue = fromString("ConstantValue");
|
||||
Deprecated = fromString("Deprecated");
|
||||
EnclosingMethod = fromString("EnclosingMethod");
|
||||
Enum = fromString("Enum");
|
||||
Exceptions = fromString("Exceptions");
|
||||
InnerClasses = fromString("InnerClasses");
|
||||
LineNumberTable = fromString("LineNumberTable");
|
||||
LocalVariableTable = fromString("LocalVariableTable");
|
||||
LocalVariableTypeTable = fromString("LocalVariableTypeTable");
|
||||
MethodParameters = fromString("MethodParameters");
|
||||
RuntimeInvisibleAnnotations = fromString("RuntimeInvisibleAnnotations");
|
||||
RuntimeInvisibleParameterAnnotations = fromString("RuntimeInvisibleParameterAnnotations");
|
||||
RuntimeInvisibleTypeAnnotations = fromString("RuntimeInvisibleTypeAnnotations");
|
||||
RuntimeVisibleAnnotations = fromString("RuntimeVisibleAnnotations");
|
||||
RuntimeVisibleParameterAnnotations = fromString("RuntimeVisibleParameterAnnotations");
|
||||
RuntimeVisibleTypeAnnotations = fromString("RuntimeVisibleTypeAnnotations");
|
||||
Signature = fromString("Signature");
|
||||
SourceFile = fromString("SourceFile");
|
||||
SourceID = fromString("SourceID");
|
||||
StackMap = fromString("StackMap");
|
||||
StackMapTable = fromString("StackMapTable");
|
||||
Synthetic = fromString("Synthetic");
|
||||
Value = fromString("Value");
|
||||
Varargs = fromString("Varargs");
|
||||
|
||||
// members of java.lang.annotation.ElementType
|
||||
ANNOTATION_TYPE = fromString("ANNOTATION_TYPE");
|
||||
CONSTRUCTOR = fromString("CONSTRUCTOR");
|
||||
FIELD = fromString("FIELD");
|
||||
LOCAL_VARIABLE = fromString("LOCAL_VARIABLE");
|
||||
METHOD = fromString("METHOD");
|
||||
PACKAGE = fromString("PACKAGE");
|
||||
PARAMETER = fromString("PARAMETER");
|
||||
TYPE = fromString("TYPE");
|
||||
TYPE_PARAMETER = fromString("TYPE_PARAMETER");
|
||||
TYPE_USE = fromString("TYPE_USE");
|
||||
|
||||
// members of java.lang.annotation.RetentionPolicy
|
||||
CLASS = fromString("CLASS");
|
||||
RUNTIME = fromString("RUNTIME");
|
||||
SOURCE = fromString("SOURCE");
|
||||
|
||||
// other identifiers
|
||||
T = fromString("T");
|
||||
deprecated = fromString("deprecated");
|
||||
ex = fromString("ex");
|
||||
package_info = fromString("package-info");
|
||||
|
||||
//lambda-related
|
||||
lambda = fromString("lambda$");
|
||||
metafactory = fromString("metafactory");
|
||||
altMetafactory = fromString("altMetafactory");
|
||||
}
|
||||
|
||||
protected Name.Table createTable(Options options) {
|
||||
boolean useUnsharedTable = options.isSet("useUnsharedTable");
|
||||
if (useUnsharedTable)
|
||||
return new UnsharedNameTable(this);
|
||||
else
|
||||
return new SharedNameTable(this);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
table.dispose();
|
||||
}
|
||||
|
||||
public Name fromChars(char[] cs, int start, int len) {
|
||||
return table.fromChars(cs, start, len);
|
||||
}
|
||||
|
||||
public Name fromString(String s) {
|
||||
return table.fromString(s);
|
||||
}
|
||||
|
||||
public Name fromUtf(byte[] cs) {
|
||||
return table.fromUtf(cs);
|
||||
}
|
||||
|
||||
public Name fromUtf(byte[] cs, int start, int len) {
|
||||
return table.fromUtf(cs, start, len);
|
||||
}
|
||||
}
|
||||
183
jdkSrc/jdk8/com/sun/tools/javac/util/Options.java
Normal file
183
jdkSrc/jdk8/com/sun/tools/javac/util/Options.java
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import java.util.*;
|
||||
import com.sun.tools.javac.main.Option;
|
||||
import static com.sun.tools.javac.main.Option.*;
|
||||
|
||||
/** A table of all command-line options.
|
||||
* If an option has an argument, the option name is mapped to the argument.
|
||||
* If a set option has no argument, it is mapped to itself.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class Options {
|
||||
private static final long serialVersionUID = 0;
|
||||
|
||||
/** The context key for the options. */
|
||||
public static final Context.Key<Options> optionsKey =
|
||||
new Context.Key<Options>();
|
||||
|
||||
private LinkedHashMap<String,String> values;
|
||||
|
||||
/** Get the Options instance for this context. */
|
||||
public static Options instance(Context context) {
|
||||
Options instance = context.get(optionsKey);
|
||||
if (instance == null)
|
||||
instance = new Options(context);
|
||||
return instance;
|
||||
}
|
||||
|
||||
protected Options(Context context) {
|
||||
// DEBUGGING -- Use LinkedHashMap for reproducability
|
||||
values = new LinkedHashMap<String,String>();
|
||||
context.put(optionsKey, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value for an undocumented option.
|
||||
*/
|
||||
public String get(String name) {
|
||||
return values.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value for an option.
|
||||
*/
|
||||
public String get(Option option) {
|
||||
return values.get(option.text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the boolean value for an option, patterned after Boolean.getBoolean,
|
||||
* essentially will return true, iff the value exists and is set to "true".
|
||||
*/
|
||||
public boolean getBoolean(String name) {
|
||||
return getBoolean(name, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the boolean with a default value if the option is not set.
|
||||
*/
|
||||
public boolean getBoolean(String name, boolean defaultValue) {
|
||||
String value = get(name);
|
||||
return (value == null) ? defaultValue : Boolean.parseBoolean(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the value for an undocumented option has been set.
|
||||
*/
|
||||
public boolean isSet(String name) {
|
||||
return (values.get(name) != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the value for an option has been set.
|
||||
*/
|
||||
public boolean isSet(Option option) {
|
||||
return (values.get(option.text) != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the value for a choice option has been set to a specific value.
|
||||
*/
|
||||
public boolean isSet(Option option, String value) {
|
||||
return (values.get(option.text + value) != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the value for an undocumented option has not been set.
|
||||
*/
|
||||
public boolean isUnset(String name) {
|
||||
return (values.get(name) == null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the value for an option has not been set.
|
||||
*/
|
||||
public boolean isUnset(Option option) {
|
||||
return (values.get(option.text) == null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the value for a choice option has not been set to a specific value.
|
||||
*/
|
||||
public boolean isUnset(Option option, String value) {
|
||||
return (values.get(option.text + value) == null);
|
||||
}
|
||||
|
||||
public void put(String name, String value) {
|
||||
values.put(name, value);
|
||||
}
|
||||
|
||||
public void put(Option option, String value) {
|
||||
values.put(option.text, value);
|
||||
}
|
||||
|
||||
public void putAll(Options options) {
|
||||
values.putAll(options.values);
|
||||
}
|
||||
|
||||
public void remove(String name) {
|
||||
values.remove(name);
|
||||
}
|
||||
|
||||
public Set<String> keySet() {
|
||||
return values.keySet();
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return values.size();
|
||||
}
|
||||
|
||||
// light-weight notification mechanism
|
||||
|
||||
private List<Runnable> listeners = List.nil();
|
||||
|
||||
public void addListener(Runnable listener) {
|
||||
listeners = listeners.prepend(listener);
|
||||
}
|
||||
|
||||
public void notifyListeners() {
|
||||
for (Runnable r: listeners)
|
||||
r.run();
|
||||
}
|
||||
|
||||
/** Check for a lint suboption. */
|
||||
public boolean lint(String s) {
|
||||
// return true if either the specific option is enabled, or
|
||||
// they are all enabled without the specific one being
|
||||
// disabled
|
||||
return
|
||||
isSet(XLINT_CUSTOM, s) ||
|
||||
(isSet(XLINT) || isSet(XLINT_CUSTOM, "all")) &&
|
||||
isUnset(XLINT_CUSTOM, "-" + s);
|
||||
}
|
||||
}
|
||||
67
jdkSrc/jdk8/com/sun/tools/javac/util/Pair.java
Normal file
67
jdkSrc/jdk8/com/sun/tools/javac/util/Pair.java
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/** A generic class for pairs.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class Pair<A, B> {
|
||||
|
||||
public final A fst;
|
||||
public final B snd;
|
||||
|
||||
public Pair(A fst, B snd) {
|
||||
this.fst = fst;
|
||||
this.snd = snd;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Pair[" + fst + "," + snd + "]";
|
||||
}
|
||||
|
||||
public boolean equals(Object other) {
|
||||
return
|
||||
other instanceof Pair<?,?> &&
|
||||
Objects.equals(fst, ((Pair<?,?>)other).fst) &&
|
||||
Objects.equals(snd, ((Pair<?,?>)other).snd);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
if (fst == null) return (snd == null) ? 0 : snd.hashCode() + 1;
|
||||
else if (snd == null) return fst.hashCode() + 2;
|
||||
else return fst.hashCode() * 17 + snd.hashCode();
|
||||
}
|
||||
|
||||
public static <A,B> Pair<A,B> of(A a, B b) {
|
||||
return new Pair<A,B>(a,b);
|
||||
}
|
||||
}
|
||||
282
jdkSrc/jdk8/com/sun/tools/javac/util/Position.java
Normal file
282
jdkSrc/jdk8/com/sun/tools/javac/util/Position.java
Normal file
@@ -0,0 +1,282 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import java.util.BitSet;
|
||||
import static com.sun.tools.javac.util.LayoutCharacters.*;
|
||||
|
||||
/** A class that defines source code positions as simple character
|
||||
* offsets from the beginning of the file. The first character
|
||||
* is at position 0.
|
||||
*
|
||||
* Support is also provided for (line,column) coordinates, but tab
|
||||
* expansion is optional and no Unicode excape translation is considered.
|
||||
* The first character is at location (1,1).
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class Position {
|
||||
public static final int NOPOS = -1;
|
||||
|
||||
public static final int FIRSTPOS = 0;
|
||||
public static final int FIRSTLINE = 1;
|
||||
public static final int FIRSTCOLUMN = 1;
|
||||
|
||||
public static final int LINESHIFT = 10;
|
||||
public static final int MAXCOLUMN = (1<<LINESHIFT) - 1;
|
||||
public static final int MAXLINE = (1<<(Integer.SIZE-LINESHIFT)) - 1;
|
||||
|
||||
public static final int MAXPOS = Integer.MAX_VALUE;
|
||||
|
||||
/**
|
||||
* This is class is not supposed to be instantiated.
|
||||
*/
|
||||
private Position() {}
|
||||
|
||||
/** A two-way map between line/column numbers and positions,
|
||||
* derived from a scan done at creation time. Tab expansion is
|
||||
* optionally supported via a character map. Text content
|
||||
* is not retained.
|
||||
*<p>
|
||||
* Notes: The first character position FIRSTPOS is at
|
||||
* (FIRSTLINE,FIRSTCOLUMN). No account is taken of Unicode escapes.
|
||||
*
|
||||
* @param src Source characters
|
||||
* @param max Number of characters to read
|
||||
* @param expandTabs If true, expand tabs when calculating columns
|
||||
*/
|
||||
public static LineMap makeLineMap(char[] src, int max, boolean expandTabs) {
|
||||
LineMapImpl lineMap = expandTabs ?
|
||||
new LineTabMapImpl(max) : new LineMapImpl();
|
||||
lineMap.build(src, max);
|
||||
return lineMap;
|
||||
}
|
||||
|
||||
/** Encode line and column numbers in an integer as:
|
||||
* {@code line-number << LINESHIFT + column-number }.
|
||||
* {@link Position#NOPOS} represents an undefined position.
|
||||
*
|
||||
* @param line number of line (first is 1)
|
||||
* @param col number of character on line (first is 1)
|
||||
* @return an encoded position or {@link Position#NOPOS}
|
||||
* if the line or column number is too big to
|
||||
* represent in the encoded format
|
||||
* @throws IllegalArgumentException if line or col is less than 1
|
||||
*/
|
||||
public static int encodePosition(int line, int col) {
|
||||
if (line < 1)
|
||||
throw new IllegalArgumentException("line must be greater than 0");
|
||||
if (col < 1)
|
||||
throw new IllegalArgumentException("column must be greater than 0");
|
||||
|
||||
if (line > MAXLINE || col > MAXCOLUMN) {
|
||||
return NOPOS;
|
||||
}
|
||||
return (line << LINESHIFT) + col;
|
||||
}
|
||||
|
||||
public static interface LineMap extends com.sun.source.tree.LineMap {
|
||||
/** Find the start position of a line.
|
||||
*
|
||||
* @param line number of line (first is 1)
|
||||
* @return position of first character in line
|
||||
* @throws ArrayIndexOutOfBoundsException
|
||||
* if {@code lineNumber < 1}
|
||||
* if {@code lineNumber > no. of lines}
|
||||
*/
|
||||
int getStartPosition(int line);
|
||||
|
||||
/** Find the position corresponding to a (line,column).
|
||||
*
|
||||
* @param line number of line (first is 1)
|
||||
* @param column number of character on line (first is 1)
|
||||
*
|
||||
* @return position of character
|
||||
* @throws ArrayIndexOutOfBoundsException
|
||||
* if {@code line < 1}
|
||||
* if {@code line > no. of lines}
|
||||
*/
|
||||
int getPosition(int line, int column);
|
||||
|
||||
/** Find the line containing a position; a line termination
|
||||
* character is on the line it terminates.
|
||||
*
|
||||
* @param pos character offset of the position
|
||||
* @return the line number on which pos occurs (first line is 1)
|
||||
*/
|
||||
int getLineNumber(int pos);
|
||||
|
||||
/** Find the column for a character position.
|
||||
* Note: this method does not handle tab expansion.
|
||||
* If tab expansion is needed, use a LineTabMap instead.
|
||||
*
|
||||
* @param pos character offset of the position
|
||||
* @return the column number at which pos occurs
|
||||
*/
|
||||
int getColumnNumber(int pos);
|
||||
}
|
||||
|
||||
static class LineMapImpl implements LineMap {
|
||||
protected int[] startPosition; // start position of each line
|
||||
|
||||
protected LineMapImpl() {}
|
||||
|
||||
protected void build(char[] src, int max) {
|
||||
int c = 0;
|
||||
int i = 0;
|
||||
int[] linebuf = new int[max];
|
||||
while (i < max) {
|
||||
linebuf[c++] = i;
|
||||
do {
|
||||
char ch = src[i];
|
||||
if (ch == '\r' || ch == '\n') {
|
||||
if (ch == '\r' && (i+1) < max && src[i+1] == '\n')
|
||||
i += 2;
|
||||
else
|
||||
++i;
|
||||
break;
|
||||
}
|
||||
else if (ch == '\t')
|
||||
setTabPosition(i);
|
||||
} while (++i < max);
|
||||
}
|
||||
this.startPosition = new int[c];
|
||||
System.arraycopy(linebuf, 0, startPosition, 0, c);
|
||||
}
|
||||
|
||||
public int getStartPosition(int line) {
|
||||
return startPosition[line - FIRSTLINE];
|
||||
}
|
||||
|
||||
public long getStartPosition(long line) {
|
||||
return getStartPosition(longToInt(line));
|
||||
}
|
||||
|
||||
public int getPosition(int line, int column) {
|
||||
return startPosition[line - FIRSTLINE] + column - FIRSTCOLUMN;
|
||||
}
|
||||
|
||||
public long getPosition(long line, long column) {
|
||||
return getPosition(longToInt(line), longToInt(column));
|
||||
}
|
||||
|
||||
// Cache of last line number lookup
|
||||
private int lastPosition = Position.FIRSTPOS;
|
||||
private int lastLine = Position.FIRSTLINE;
|
||||
|
||||
public int getLineNumber(int pos) {
|
||||
if (pos == lastPosition) {
|
||||
return lastLine;
|
||||
}
|
||||
lastPosition = pos;
|
||||
|
||||
int low = 0;
|
||||
int high = startPosition.length-1;
|
||||
while (low <= high) {
|
||||
int mid = (low + high) >> 1;
|
||||
int midVal = startPosition[mid];
|
||||
|
||||
if (midVal < pos)
|
||||
low = mid + 1;
|
||||
else if (midVal > pos)
|
||||
high = mid - 1;
|
||||
else {
|
||||
lastLine = mid + 1; // pos is at beginning of this line
|
||||
return lastLine;
|
||||
}
|
||||
}
|
||||
lastLine = low;
|
||||
return lastLine; // pos is on this line
|
||||
}
|
||||
|
||||
public long getLineNumber(long pos) {
|
||||
return getLineNumber(longToInt(pos));
|
||||
}
|
||||
|
||||
public int getColumnNumber(int pos) {
|
||||
return pos - startPosition[getLineNumber(pos) - FIRSTLINE] + FIRSTCOLUMN;
|
||||
}
|
||||
|
||||
public long getColumnNumber(long pos) {
|
||||
return getColumnNumber(longToInt(pos));
|
||||
}
|
||||
|
||||
private static int longToInt(long longValue) {
|
||||
int intValue = (int)longValue;
|
||||
if (intValue != longValue)
|
||||
throw new IndexOutOfBoundsException();
|
||||
return intValue;
|
||||
}
|
||||
|
||||
protected void setTabPosition(int offset) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* A LineMap that handles tab expansion correctly. The cost is
|
||||
* an additional bit per character in the source array.
|
||||
*/
|
||||
public static class LineTabMapImpl extends LineMapImpl {
|
||||
private BitSet tabMap; // bits set for tab positions.
|
||||
|
||||
public LineTabMapImpl(int max) {
|
||||
super();
|
||||
tabMap = new BitSet(max);
|
||||
}
|
||||
|
||||
protected void setTabPosition(int offset) {
|
||||
tabMap.set(offset);
|
||||
}
|
||||
|
||||
public int getColumnNumber(int pos) {
|
||||
int lineStart = startPosition[getLineNumber(pos) - FIRSTLINE];
|
||||
int column = 0;
|
||||
for (int bp = lineStart; bp < pos; bp++) {
|
||||
if (tabMap.get(bp))
|
||||
column = (column / TabInc * TabInc) + TabInc;
|
||||
else
|
||||
column++;
|
||||
}
|
||||
return column + FIRSTCOLUMN;
|
||||
}
|
||||
|
||||
public int getPosition(int line, int column) {
|
||||
int pos = startPosition[line - FIRSTLINE];
|
||||
column -= FIRSTCOLUMN;
|
||||
int col = 0;
|
||||
while (col < column) {
|
||||
pos++;
|
||||
if (tabMap.get(pos))
|
||||
col = (col / TabInc * TabInc) + TabInc;
|
||||
else
|
||||
col++;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
/**
|
||||
* Used to propagate exceptions through to the user.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own
|
||||
* risk. This code and its internal interfaces are subject to change
|
||||
* or deletion without notice.</b></p>
|
||||
*
|
||||
* @author Peter von der Ah\u00e9
|
||||
*/
|
||||
public class PropagatedException extends RuntimeException {
|
||||
|
||||
static final long serialVersionUID = -6065309339888775367L;
|
||||
|
||||
public PropagatedException(RuntimeException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RuntimeException getCause() {
|
||||
return (RuntimeException)super.getCause();
|
||||
}
|
||||
}
|
||||
151
jdkSrc/jdk8/com/sun/tools/javac/util/RawDiagnosticFormatter.java
Normal file
151
jdkSrc/jdk8/com/sun/tools/javac/util/RawDiagnosticFormatter.java
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Locale;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
import com.sun.tools.javac.api.DiagnosticFormatter.Configuration.*;
|
||||
import com.sun.tools.javac.api.Formattable;
|
||||
import com.sun.tools.javac.file.BaseFileObject;
|
||||
import com.sun.tools.javac.tree.JCTree.*;
|
||||
import com.sun.tools.javac.util.AbstractDiagnosticFormatter.SimpleConfiguration;
|
||||
|
||||
import static com.sun.tools.javac.api.DiagnosticFormatter.PositionKind.*;
|
||||
|
||||
/**
|
||||
* A raw formatter for diagnostic messages.
|
||||
* The raw formatter will format a diagnostic according to one of two format patterns, depending on whether
|
||||
* or not the source name and position are set. This formatter provides a standardized, localize-independent
|
||||
* implementation of a diagnostic formatter; as such, this formatter is best suited for testing purposes.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public final class RawDiagnosticFormatter extends AbstractDiagnosticFormatter {
|
||||
|
||||
/**
|
||||
* Create a formatter based on the supplied options.
|
||||
* @param options
|
||||
*/
|
||||
public RawDiagnosticFormatter(Options options) {
|
||||
super(null, new SimpleConfiguration(options,
|
||||
EnumSet.of(DiagnosticPart.SUMMARY,
|
||||
DiagnosticPart.DETAILS,
|
||||
DiagnosticPart.SUBDIAGNOSTICS)));
|
||||
}
|
||||
|
||||
//provide common default formats
|
||||
public String formatDiagnostic(JCDiagnostic d, Locale l) {
|
||||
try {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
if (d.getPosition() != Position.NOPOS) {
|
||||
buf.append(formatSource(d, false, null));
|
||||
buf.append(':');
|
||||
buf.append(formatPosition(d, LINE, null));
|
||||
buf.append(':');
|
||||
buf.append(formatPosition(d, COLUMN, null));
|
||||
buf.append(':');
|
||||
}
|
||||
else if (d.getSource() != null && d.getSource().getKind() == JavaFileObject.Kind.CLASS) {
|
||||
buf.append(formatSource(d, false, null));
|
||||
buf.append(":-:-:");
|
||||
}
|
||||
else
|
||||
buf.append('-');
|
||||
buf.append(' ');
|
||||
buf.append(formatMessage(d, null));
|
||||
if (displaySource(d)) {
|
||||
buf.append("\n");
|
||||
buf.append(formatSourceLine(d, 0));
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
catch (Exception e) {
|
||||
//e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String formatMessage(JCDiagnostic d, Locale l) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
Collection<String> args = formatArguments(d, l);
|
||||
buf.append(localize(null, d.getCode(), args.toArray()));
|
||||
if (d.isMultiline() && getConfiguration().getVisible().contains(DiagnosticPart.SUBDIAGNOSTICS)) {
|
||||
List<String> subDiags = formatSubdiagnostics(d, null);
|
||||
if (subDiags.nonEmpty()) {
|
||||
String sep = "";
|
||||
buf.append(",{");
|
||||
for (String sub : formatSubdiagnostics(d, null)) {
|
||||
buf.append(sep);
|
||||
buf.append("(");
|
||||
buf.append(sub);
|
||||
buf.append(")");
|
||||
sep = ",";
|
||||
}
|
||||
buf.append('}');
|
||||
}
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String formatArgument(JCDiagnostic diag, Object arg, Locale l) {
|
||||
String s;
|
||||
if (arg instanceof Formattable) {
|
||||
s = arg.toString();
|
||||
} else if (arg instanceof JCExpression) {
|
||||
JCExpression tree = (JCExpression)arg;
|
||||
s = "@" + tree.getStartPosition();
|
||||
} else if (arg instanceof BaseFileObject) {
|
||||
s = ((BaseFileObject) arg).getShortName();
|
||||
} else {
|
||||
s = super.formatArgument(diag, arg, null);
|
||||
}
|
||||
return (arg instanceof JCDiagnostic) ? "(" + s + ")" : s;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String localize(Locale l, String key, Object... args) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(key);
|
||||
String sep = ": ";
|
||||
for (Object o : args) {
|
||||
buf.append(sep);
|
||||
buf.append(o);
|
||||
sep = ", ";
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRaw() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,710 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sun.tools.javac.code.Kinds;
|
||||
import com.sun.tools.javac.code.Printer;
|
||||
import com.sun.tools.javac.code.Symbol;
|
||||
import com.sun.tools.javac.code.Symbol.*;
|
||||
import com.sun.tools.javac.code.Symtab;
|
||||
import com.sun.tools.javac.code.Type;
|
||||
import com.sun.tools.javac.code.Type.*;
|
||||
import com.sun.tools.javac.code.Types;
|
||||
|
||||
import static com.sun.tools.javac.code.TypeTag.*;
|
||||
import static com.sun.tools.javac.code.Flags.*;
|
||||
import static com.sun.tools.javac.util.LayoutCharacters.*;
|
||||
import static com.sun.tools.javac.util.RichDiagnosticFormatter.RichConfiguration.*;
|
||||
|
||||
/**
|
||||
* A rich diagnostic formatter is a formatter that provides better integration
|
||||
* with javac's type system. A diagostic is first preprocessed in order to keep
|
||||
* track of each types/symbols in it; after these informations are collected,
|
||||
* the diagnostic is rendered using a standard formatter, whose type/symbol printer
|
||||
* has been replaced by a more refined version provided by this rich formatter.
|
||||
* The rich formatter currently enables three different features: (i) simple class
|
||||
* names - that is class names are displayed used a non qualified name (thus
|
||||
* omitting package info) whenever possible - (ii) where clause list - a list of
|
||||
* additional subdiagnostics that provide specific info about type-variables,
|
||||
* captured types, intersection types that occur in the diagnostic that is to be
|
||||
* formatted and (iii) type-variable disambiguation - when the diagnostic refers
|
||||
* to two different type-variables with the same name, their representation is
|
||||
* disambiguated by appending an index to the type variable name.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class RichDiagnosticFormatter extends
|
||||
ForwardingDiagnosticFormatter<JCDiagnostic, AbstractDiagnosticFormatter> {
|
||||
|
||||
final Symtab syms;
|
||||
final Types types;
|
||||
final JCDiagnostic.Factory diags;
|
||||
final JavacMessages messages;
|
||||
|
||||
/* name simplifier used by this formatter */
|
||||
protected ClassNameSimplifier nameSimplifier;
|
||||
|
||||
/* type/symbol printer used by this formatter */
|
||||
private RichPrinter printer;
|
||||
|
||||
/* map for keeping track of a where clause associated to a given type */
|
||||
Map<WhereClauseKind, Map<Type, JCDiagnostic>> whereClauses;
|
||||
|
||||
/** Get the DiagnosticFormatter instance for this context. */
|
||||
public static RichDiagnosticFormatter instance(Context context) {
|
||||
RichDiagnosticFormatter instance = context.get(RichDiagnosticFormatter.class);
|
||||
if (instance == null)
|
||||
instance = new RichDiagnosticFormatter(context);
|
||||
return instance;
|
||||
}
|
||||
|
||||
protected RichDiagnosticFormatter(Context context) {
|
||||
super((AbstractDiagnosticFormatter)Log.instance(context).getDiagnosticFormatter());
|
||||
setRichPrinter(new RichPrinter());
|
||||
this.syms = Symtab.instance(context);
|
||||
this.diags = JCDiagnostic.Factory.instance(context);
|
||||
this.types = Types.instance(context);
|
||||
this.messages = JavacMessages.instance(context);
|
||||
whereClauses = new EnumMap<WhereClauseKind, Map<Type, JCDiagnostic>>(WhereClauseKind.class);
|
||||
configuration = new RichConfiguration(Options.instance(context), formatter);
|
||||
for (WhereClauseKind kind : WhereClauseKind.values())
|
||||
whereClauses.put(kind, new LinkedHashMap<Type, JCDiagnostic>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String format(JCDiagnostic diag, Locale l) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
nameSimplifier = new ClassNameSimplifier();
|
||||
for (WhereClauseKind kind : WhereClauseKind.values())
|
||||
whereClauses.get(kind).clear();
|
||||
preprocessDiagnostic(diag);
|
||||
sb.append(formatter.format(diag, l));
|
||||
if (getConfiguration().isEnabled(RichFormatterFeature.WHERE_CLAUSES)) {
|
||||
List<JCDiagnostic> clauses = getWhereClauses();
|
||||
String indent = formatter.isRaw() ? "" :
|
||||
formatter.indentString(DetailsInc);
|
||||
for (JCDiagnostic d : clauses) {
|
||||
String whereClause = formatter.format(d, l);
|
||||
if (whereClause.length() > 0) {
|
||||
sb.append('\n' + indent + whereClause);
|
||||
}
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String formatMessage(JCDiagnostic diag, Locale l) {
|
||||
nameSimplifier = new ClassNameSimplifier();
|
||||
preprocessDiagnostic(diag);
|
||||
return super.formatMessage(diag, l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the type/symbol printer used by this formatter.
|
||||
* @param printer the rich printer to be set
|
||||
*/
|
||||
protected void setRichPrinter(RichPrinter printer) {
|
||||
this.printer = printer;
|
||||
formatter.setPrinter(printer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type/symbol printer used by this formatter.
|
||||
* @return type/symbol rich printer
|
||||
*/
|
||||
protected RichPrinter getRichPrinter() {
|
||||
return printer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Preprocess a given diagnostic by looking both into its arguments and into
|
||||
* its subdiagnostics (if any). This preprocessing is responsible for
|
||||
* generating info corresponding to features like where clauses, name
|
||||
* simplification, etc.
|
||||
*
|
||||
* @param diag the diagnostic to be preprocessed
|
||||
*/
|
||||
protected void preprocessDiagnostic(JCDiagnostic diag) {
|
||||
for (Object o : diag.getArgs()) {
|
||||
if (o != null) {
|
||||
preprocessArgument(o);
|
||||
}
|
||||
}
|
||||
if (diag.isMultiline()) {
|
||||
for (JCDiagnostic d : diag.getSubdiagnostics())
|
||||
preprocessDiagnostic(d);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Preprocess a diagnostic argument. A type/symbol argument is
|
||||
* preprocessed by specialized type/symbol preprocessors.
|
||||
*
|
||||
* @param arg the argument to be translated
|
||||
*/
|
||||
protected void preprocessArgument(Object arg) {
|
||||
if (arg instanceof Type) {
|
||||
preprocessType((Type)arg);
|
||||
}
|
||||
else if (arg instanceof Symbol) {
|
||||
preprocessSymbol((Symbol)arg);
|
||||
}
|
||||
else if (arg instanceof JCDiagnostic) {
|
||||
preprocessDiagnostic((JCDiagnostic)arg);
|
||||
}
|
||||
else if (arg instanceof Iterable<?>) {
|
||||
for (Object o : (Iterable<?>)arg) {
|
||||
preprocessArgument(o);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a list of multiline diagnostics containing detailed info about
|
||||
* type-variables, captured types, and intersection types
|
||||
*
|
||||
* @return where clause list
|
||||
*/
|
||||
protected List<JCDiagnostic> getWhereClauses() {
|
||||
List<JCDiagnostic> clauses = List.nil();
|
||||
for (WhereClauseKind kind : WhereClauseKind.values()) {
|
||||
List<JCDiagnostic> lines = List.nil();
|
||||
for (Map.Entry<Type, JCDiagnostic> entry : whereClauses.get(kind).entrySet()) {
|
||||
lines = lines.prepend(entry.getValue());
|
||||
}
|
||||
if (!lines.isEmpty()) {
|
||||
String key = kind.key();
|
||||
if (lines.size() > 1)
|
||||
key += ".1";
|
||||
JCDiagnostic d = diags.fragment(key, whereClauses.get(kind).keySet());
|
||||
d = new JCDiagnostic.MultilineDiagnostic(d, lines.reverse());
|
||||
clauses = clauses.prepend(d);
|
||||
}
|
||||
}
|
||||
return clauses.reverse();
|
||||
}
|
||||
|
||||
private int indexOf(Type type, WhereClauseKind kind) {
|
||||
int index = 1;
|
||||
for (Type t : whereClauses.get(kind).keySet()) {
|
||||
if (t.tsym == type.tsym) {
|
||||
return index;
|
||||
}
|
||||
if (kind != WhereClauseKind.TYPEVAR ||
|
||||
t.toString().equals(type.toString())) {
|
||||
index++;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private boolean unique(TypeVar typevar) {
|
||||
int found = 0;
|
||||
for (Type t : whereClauses.get(WhereClauseKind.TYPEVAR).keySet()) {
|
||||
if (t.toString().equals(typevar.toString())) {
|
||||
found++;
|
||||
}
|
||||
}
|
||||
if (found < 1)
|
||||
throw new AssertionError("Missing type variable in where clause " + typevar);
|
||||
return found == 1;
|
||||
}
|
||||
//where
|
||||
/**
|
||||
* This enum defines all posssible kinds of where clauses that can be
|
||||
* attached by a rich diagnostic formatter to a given diagnostic
|
||||
*/
|
||||
enum WhereClauseKind {
|
||||
|
||||
/** where clause regarding a type variable */
|
||||
TYPEVAR("where.description.typevar"),
|
||||
/** where clause regarding a captured type */
|
||||
CAPTURED("where.description.captured"),
|
||||
/** where clause regarding an intersection type */
|
||||
INTERSECTION("where.description.intersection");
|
||||
|
||||
/** resource key for this where clause kind */
|
||||
private final String key;
|
||||
|
||||
WhereClauseKind(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
String key() {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="name simplifier">
|
||||
/**
|
||||
* A name simplifier keeps track of class names usages in order to determine
|
||||
* whether a class name can be compacted or not. Short names are not used
|
||||
* if a conflict is detected, e.g. when two classes with the same simple
|
||||
* name belong to different packages - in this case the formatter reverts
|
||||
* to fullnames as compact names might lead to a confusing diagnostic.
|
||||
*/
|
||||
protected class ClassNameSimplifier {
|
||||
|
||||
/* table for keeping track of all short name usages */
|
||||
Map<Name, List<Symbol>> nameClashes = new HashMap<Name, List<Symbol>>();
|
||||
|
||||
/**
|
||||
* Add a name usage to the simplifier's internal cache
|
||||
*/
|
||||
protected void addUsage(Symbol sym) {
|
||||
Name n = sym.getSimpleName();
|
||||
List<Symbol> conflicts = nameClashes.get(n);
|
||||
if (conflicts == null) {
|
||||
conflicts = List.nil();
|
||||
}
|
||||
if (!conflicts.contains(sym))
|
||||
nameClashes.put(n, conflicts.append(sym));
|
||||
}
|
||||
|
||||
public String simplify(Symbol s) {
|
||||
String name = s.getQualifiedName().toString();
|
||||
if (!s.type.isCompound() && !s.type.isPrimitive()) {
|
||||
List<Symbol> conflicts = nameClashes.get(s.getSimpleName());
|
||||
if (conflicts == null ||
|
||||
(conflicts.size() == 1 &&
|
||||
conflicts.contains(s))) {
|
||||
List<Name> l = List.nil();
|
||||
Symbol s2 = s;
|
||||
while (s2.type.hasTag(CLASS) &&
|
||||
s2.type.getEnclosingType().hasTag(CLASS) &&
|
||||
s2.owner.kind == Kinds.TYP) {
|
||||
l = l.prepend(s2.getSimpleName());
|
||||
s2 = s2.owner;
|
||||
}
|
||||
l = l.prepend(s2.getSimpleName());
|
||||
StringBuilder buf = new StringBuilder();
|
||||
String sep = "";
|
||||
for (Name n2 : l) {
|
||||
buf.append(sep);
|
||||
buf.append(n2);
|
||||
sep = ".";
|
||||
}
|
||||
name = buf.toString();
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
};
|
||||
// </editor-fold>
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="rich printer">
|
||||
/**
|
||||
* Enhanced type/symbol printer that provides support for features like simple names
|
||||
* and type variable disambiguation. This enriched printer exploits the info
|
||||
* discovered during type/symbol preprocessing. This printer is set on the delegate
|
||||
* formatter so that rich type/symbol info can be properly rendered.
|
||||
*/
|
||||
protected class RichPrinter extends Printer {
|
||||
|
||||
@Override
|
||||
public String localize(Locale locale, String key, Object... args) {
|
||||
return formatter.localize(locale, key, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String capturedVarId(CapturedType t, Locale locale) {
|
||||
return indexOf(t, WhereClauseKind.CAPTURED) + "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitType(Type t, Locale locale) {
|
||||
String s = super.visitType(t, locale);
|
||||
if (t == syms.botType)
|
||||
s = localize(locale, "compiler.misc.type.null");
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitCapturedType(CapturedType t, Locale locale) {
|
||||
if (getConfiguration().isEnabled(RichFormatterFeature.WHERE_CLAUSES)) {
|
||||
return localize(locale,
|
||||
"compiler.misc.captured.type",
|
||||
indexOf(t, WhereClauseKind.CAPTURED));
|
||||
}
|
||||
else
|
||||
return super.visitCapturedType(t, locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitClassType(ClassType t, Locale locale) {
|
||||
if (t.isCompound() &&
|
||||
getConfiguration().isEnabled(RichFormatterFeature.WHERE_CLAUSES)) {
|
||||
return localize(locale,
|
||||
"compiler.misc.intersection.type",
|
||||
indexOf(t, WhereClauseKind.INTERSECTION));
|
||||
}
|
||||
else
|
||||
return super.visitClassType(t, locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String className(ClassType t, boolean longform, Locale locale) {
|
||||
Symbol sym = t.tsym;
|
||||
if (sym.name.length() == 0 ||
|
||||
!getConfiguration().isEnabled(RichFormatterFeature.SIMPLE_NAMES)) {
|
||||
return super.className(t, longform, locale);
|
||||
}
|
||||
else if (longform)
|
||||
return nameSimplifier.simplify(sym).toString();
|
||||
else
|
||||
return sym.name.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitTypeVar(TypeVar t, Locale locale) {
|
||||
if (unique(t) ||
|
||||
!getConfiguration().isEnabled(RichFormatterFeature.UNIQUE_TYPEVAR_NAMES)) {
|
||||
return t.toString();
|
||||
}
|
||||
else {
|
||||
return localize(locale,
|
||||
"compiler.misc.type.var",
|
||||
t.toString(), indexOf(t, WhereClauseKind.TYPEVAR));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitClassSymbol(ClassSymbol s, Locale locale) {
|
||||
if (s.type.isCompound()) {
|
||||
return visit(s.type, locale);
|
||||
}
|
||||
String name = nameSimplifier.simplify(s);
|
||||
if (name.length() == 0 ||
|
||||
!getConfiguration().isEnabled(RichFormatterFeature.SIMPLE_NAMES)) {
|
||||
return super.visitClassSymbol(s, locale);
|
||||
}
|
||||
else {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitMethodSymbol(MethodSymbol s, Locale locale) {
|
||||
String ownerName = visit(s.owner, locale);
|
||||
if (s.isStaticOrInstanceInit()) {
|
||||
return ownerName;
|
||||
} else {
|
||||
String ms = (s.name == s.name.table.names.init)
|
||||
? ownerName
|
||||
: s.name.toString();
|
||||
if (s.type != null) {
|
||||
if (s.type.hasTag(FORALL)) {
|
||||
ms = "<" + visitTypes(s.type.getTypeArguments(), locale) + ">" + ms;
|
||||
}
|
||||
ms += "(" + printMethodArgs(
|
||||
s.type.getParameterTypes(),
|
||||
(s.flags() & VARARGS) != 0,
|
||||
locale) + ")";
|
||||
}
|
||||
return ms;
|
||||
}
|
||||
}
|
||||
};
|
||||
// </editor-fold>
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="type scanner">
|
||||
/**
|
||||
* Preprocess a given type looking for (i) additional info (where clauses) to be
|
||||
* added to the main diagnostic (ii) names to be compacted.
|
||||
*/
|
||||
protected void preprocessType(Type t) {
|
||||
typePreprocessor.visit(t);
|
||||
}
|
||||
//where
|
||||
protected Types.UnaryVisitor<Void> typePreprocessor =
|
||||
new Types.UnaryVisitor<Void>() {
|
||||
|
||||
public Void visit(List<Type> ts) {
|
||||
for (Type t : ts)
|
||||
visit(t);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitForAll(ForAll t, Void ignored) {
|
||||
visit(t.tvars);
|
||||
visit(t.qtype);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitMethodType(MethodType t, Void ignored) {
|
||||
visit(t.argtypes);
|
||||
visit(t.restype);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitErrorType(ErrorType t, Void ignored) {
|
||||
Type ot = t.getOriginalType();
|
||||
if (ot != null)
|
||||
visit(ot);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitArrayType(ArrayType t, Void ignored) {
|
||||
visit(t.elemtype);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitWildcardType(WildcardType t, Void ignored) {
|
||||
visit(t.type);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitType(Type t, Void ignored) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitCapturedType(CapturedType t, Void ignored) {
|
||||
if (indexOf(t, WhereClauseKind.CAPTURED) == -1) {
|
||||
String suffix = t.lower == syms.botType ? ".1" : "";
|
||||
JCDiagnostic d = diags.fragment("where.captured"+ suffix, t, t.bound, t.lower, t.wildcard);
|
||||
whereClauses.get(WhereClauseKind.CAPTURED).put(t, d);
|
||||
visit(t.wildcard);
|
||||
visit(t.lower);
|
||||
visit(t.bound);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitClassType(ClassType t, Void ignored) {
|
||||
if (t.isCompound()) {
|
||||
if (indexOf(t, WhereClauseKind.INTERSECTION) == -1) {
|
||||
Type supertype = types.supertype(t);
|
||||
List<Type> interfaces = types.interfaces(t);
|
||||
JCDiagnostic d = diags.fragment("where.intersection", t, interfaces.prepend(supertype));
|
||||
whereClauses.get(WhereClauseKind.INTERSECTION).put(t, d);
|
||||
visit(supertype);
|
||||
visit(interfaces);
|
||||
}
|
||||
} else if (t.tsym.name.isEmpty()) {
|
||||
//anon class
|
||||
ClassType norm = (ClassType) t.tsym.type;
|
||||
if (norm != null) {
|
||||
if (norm.interfaces_field != null && norm.interfaces_field.nonEmpty()) {
|
||||
visit(norm.interfaces_field.head);
|
||||
} else {
|
||||
visit(norm.supertype_field);
|
||||
}
|
||||
}
|
||||
}
|
||||
nameSimplifier.addUsage(t.tsym);
|
||||
visit(t.getTypeArguments());
|
||||
if (t.getEnclosingType() != Type.noType)
|
||||
visit(t.getEnclosingType());
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitTypeVar(TypeVar t, Void ignored) {
|
||||
if (indexOf(t, WhereClauseKind.TYPEVAR) == -1) {
|
||||
//access the bound type and skip error types
|
||||
Type bound = t.bound;
|
||||
while ((bound instanceof ErrorType))
|
||||
bound = ((ErrorType)bound).getOriginalType();
|
||||
//retrieve the bound list - if the type variable
|
||||
//has not been attributed the bound is not set
|
||||
List<Type> bounds = (bound != null) &&
|
||||
(bound.hasTag(CLASS) || bound.hasTag(TYPEVAR)) ?
|
||||
types.getBounds(t) :
|
||||
List.<Type>nil();
|
||||
|
||||
nameSimplifier.addUsage(t.tsym);
|
||||
|
||||
boolean boundErroneous = bounds.head == null ||
|
||||
bounds.head.hasTag(NONE) ||
|
||||
bounds.head.hasTag(ERROR);
|
||||
|
||||
if ((t.tsym.flags() & SYNTHETIC) == 0) {
|
||||
//this is a true typevar
|
||||
JCDiagnostic d = diags.fragment("where.typevar" +
|
||||
(boundErroneous ? ".1" : ""), t, bounds,
|
||||
Kinds.kindName(t.tsym.location()), t.tsym.location());
|
||||
whereClauses.get(WhereClauseKind.TYPEVAR).put(t, d);
|
||||
symbolPreprocessor.visit(t.tsym.location(), null);
|
||||
visit(bounds);
|
||||
} else {
|
||||
Assert.check(!boundErroneous);
|
||||
//this is a fresh (synthetic) tvar
|
||||
JCDiagnostic d = diags.fragment("where.fresh.typevar", t, bounds);
|
||||
whereClauses.get(WhereClauseKind.TYPEVAR).put(t, d);
|
||||
visit(bounds);
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
// </editor-fold>
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="symbol scanner">
|
||||
/**
|
||||
* Preprocess a given symbol looking for (i) additional info (where clauses) to be
|
||||
* added to the main diagnostic (ii) names to be compacted
|
||||
*/
|
||||
protected void preprocessSymbol(Symbol s) {
|
||||
symbolPreprocessor.visit(s, null);
|
||||
}
|
||||
//where
|
||||
protected Types.DefaultSymbolVisitor<Void, Void> symbolPreprocessor =
|
||||
new Types.DefaultSymbolVisitor<Void, Void>() {
|
||||
|
||||
@Override
|
||||
public Void visitClassSymbol(ClassSymbol s, Void ignored) {
|
||||
if (s.type.isCompound()) {
|
||||
typePreprocessor.visit(s.type);
|
||||
} else {
|
||||
nameSimplifier.addUsage(s);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitSymbol(Symbol s, Void ignored) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitMethodSymbol(MethodSymbol s, Void ignored) {
|
||||
visit(s.owner, null);
|
||||
if (s.type != null)
|
||||
typePreprocessor.visit(s.type);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
// </editor-fold>
|
||||
|
||||
@Override
|
||||
public RichConfiguration getConfiguration() {
|
||||
//the following cast is always safe - see init
|
||||
return (RichConfiguration)configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration object provided by the rich formatter.
|
||||
*/
|
||||
public static class RichConfiguration extends ForwardingDiagnosticFormatter.ForwardingConfiguration {
|
||||
|
||||
/** set of enabled rich formatter's features */
|
||||
protected java.util.EnumSet<RichFormatterFeature> features;
|
||||
|
||||
@SuppressWarnings("fallthrough")
|
||||
public RichConfiguration(Options options, AbstractDiagnosticFormatter formatter) {
|
||||
super(formatter.getConfiguration());
|
||||
features = formatter.isRaw() ? EnumSet.noneOf(RichFormatterFeature.class) :
|
||||
EnumSet.of(RichFormatterFeature.SIMPLE_NAMES,
|
||||
RichFormatterFeature.WHERE_CLAUSES,
|
||||
RichFormatterFeature.UNIQUE_TYPEVAR_NAMES);
|
||||
String diagOpts = options.get("diags");
|
||||
if (diagOpts != null) {
|
||||
for (String args: diagOpts.split(",")) {
|
||||
if (args.equals("-where")) {
|
||||
features.remove(RichFormatterFeature.WHERE_CLAUSES);
|
||||
}
|
||||
else if (args.equals("where")) {
|
||||
features.add(RichFormatterFeature.WHERE_CLAUSES);
|
||||
}
|
||||
if (args.equals("-simpleNames")) {
|
||||
features.remove(RichFormatterFeature.SIMPLE_NAMES);
|
||||
}
|
||||
else if (args.equals("simpleNames")) {
|
||||
features.add(RichFormatterFeature.SIMPLE_NAMES);
|
||||
}
|
||||
if (args.equals("-disambiguateTvars")) {
|
||||
features.remove(RichFormatterFeature.UNIQUE_TYPEVAR_NAMES);
|
||||
}
|
||||
else if (args.equals("disambiguateTvars")) {
|
||||
features.add(RichFormatterFeature.UNIQUE_TYPEVAR_NAMES);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all the features supported by the rich formatter.
|
||||
* @return list of supported features
|
||||
*/
|
||||
public RichFormatterFeature[] getAvailableFeatures() {
|
||||
return RichFormatterFeature.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable a specific feature on this rich formatter.
|
||||
* @param feature feature to be enabled
|
||||
*/
|
||||
public void enable(RichFormatterFeature feature) {
|
||||
features.add(feature);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable a specific feature on this rich formatter.
|
||||
* @param feature feature to be disabled
|
||||
*/
|
||||
public void disable(RichFormatterFeature feature) {
|
||||
features.remove(feature);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is a given feature enabled on this formatter?
|
||||
* @param feature feature to be tested
|
||||
*/
|
||||
public boolean isEnabled(RichFormatterFeature feature) {
|
||||
return features.contains(feature);
|
||||
}
|
||||
|
||||
/**
|
||||
* The advanced formatting features provided by the rich formatter
|
||||
*/
|
||||
public enum RichFormatterFeature {
|
||||
/** a list of additional info regarding a given type/symbol */
|
||||
WHERE_CLAUSES,
|
||||
/** full class names simplification (where possible) */
|
||||
SIMPLE_NAMES,
|
||||
/** type-variable names disambiguation */
|
||||
UNIQUE_TYPEVAR_NAMES;
|
||||
}
|
||||
}
|
||||
}
|
||||
437
jdkSrc/jdk8/com/sun/tools/javac/util/ServiceLoader.java
Normal file
437
jdkSrc/jdk8/com/sun/tools/javac/util/ServiceLoader.java
Normal file
@@ -0,0 +1,437 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Objects;
|
||||
import java.util.ServiceConfigurationError;
|
||||
|
||||
|
||||
/**
|
||||
* This is a temporary, modified copy of java.util.ServiceLoader, for use by
|
||||
* javac, to work around bug JDK-8004082.
|
||||
*
|
||||
* The bug describes problems in the interaction between ServiceLoader and
|
||||
* URLClassLoader, such that references to a jar file passed to URLClassLoader
|
||||
* may be retained after calling URLClassLoader.close(), preventing the jar
|
||||
* file from being deleted on Windows.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
|
||||
public final class ServiceLoader<S>
|
||||
implements Iterable<S>
|
||||
{
|
||||
|
||||
private static final String PREFIX = "META-INF/services/";
|
||||
|
||||
// The class or interface representing the service being loaded
|
||||
private Class<S> service;
|
||||
|
||||
// The class loader used to locate, load, and instantiate providers
|
||||
private ClassLoader loader;
|
||||
|
||||
// Cached providers, in instantiation order
|
||||
private LinkedHashMap<String,S> providers = new LinkedHashMap<>();
|
||||
|
||||
// The current lazy-lookup iterator
|
||||
private LazyIterator lookupIterator;
|
||||
|
||||
/**
|
||||
* Clear this loader's provider cache so that all providers will be
|
||||
* reloaded.
|
||||
*
|
||||
* <p> After invoking this method, subsequent invocations of the {@link
|
||||
* #iterator() iterator} method will lazily look up and instantiate
|
||||
* providers from scratch, just as is done by a newly-created loader.
|
||||
*
|
||||
* <p> This method is intended for use in situations in which new providers
|
||||
* can be installed into a running Java virtual machine.
|
||||
*/
|
||||
public void reload() {
|
||||
providers.clear();
|
||||
lookupIterator = new LazyIterator(service, loader);
|
||||
}
|
||||
|
||||
private ServiceLoader(Class<S> svc, ClassLoader cl) {
|
||||
service = Objects.requireNonNull(svc, "Service interface cannot be null");
|
||||
loader = (cl == null) ? ClassLoader.getSystemClassLoader() : cl;
|
||||
reload();
|
||||
}
|
||||
|
||||
private static void fail(Class<?> service, String msg, Throwable cause)
|
||||
throws ServiceConfigurationError
|
||||
{
|
||||
throw new ServiceConfigurationError(service.getName() + ": " + msg,
|
||||
cause);
|
||||
}
|
||||
|
||||
private static void fail(Class<?> service, String msg)
|
||||
throws ServiceConfigurationError
|
||||
{
|
||||
throw new ServiceConfigurationError(service.getName() + ": " + msg);
|
||||
}
|
||||
|
||||
private static void fail(Class<?> service, URL u, int line, String msg)
|
||||
throws ServiceConfigurationError
|
||||
{
|
||||
fail(service, u + ":" + line + ": " + msg);
|
||||
}
|
||||
|
||||
// Parse a single line from the given configuration file, adding the name
|
||||
// on the line to the names list.
|
||||
//
|
||||
private int parseLine(Class<?> service, URL u, BufferedReader r, int lc,
|
||||
List<String> names)
|
||||
throws IOException, ServiceConfigurationError
|
||||
{
|
||||
String ln = r.readLine();
|
||||
if (ln == null) {
|
||||
return -1;
|
||||
}
|
||||
int ci = ln.indexOf('#');
|
||||
if (ci >= 0) ln = ln.substring(0, ci);
|
||||
ln = ln.trim();
|
||||
int n = ln.length();
|
||||
if (n != 0) {
|
||||
if ((ln.indexOf(' ') >= 0) || (ln.indexOf('\t') >= 0))
|
||||
fail(service, u, lc, "Illegal configuration-file syntax");
|
||||
int cp = ln.codePointAt(0);
|
||||
if (!Character.isJavaIdentifierStart(cp))
|
||||
fail(service, u, lc, "Illegal provider-class name: " + ln);
|
||||
for (int i = Character.charCount(cp); i < n; i += Character.charCount(cp)) {
|
||||
cp = ln.codePointAt(i);
|
||||
if (!Character.isJavaIdentifierPart(cp) && (cp != '.'))
|
||||
fail(service, u, lc, "Illegal provider-class name: " + ln);
|
||||
}
|
||||
if (!providers.containsKey(ln) && !names.contains(ln))
|
||||
names.add(ln);
|
||||
}
|
||||
return lc + 1;
|
||||
}
|
||||
|
||||
// Parse the content of the given URL as a provider-configuration file.
|
||||
//
|
||||
// @param service
|
||||
// The service type for which providers are being sought;
|
||||
// used to construct error detail strings
|
||||
//
|
||||
// @param u
|
||||
// The URL naming the configuration file to be parsed
|
||||
//
|
||||
// @return A (possibly empty) iterator that will yield the provider-class
|
||||
// names in the given configuration file that are not yet members
|
||||
// of the returned set
|
||||
//
|
||||
// @throws ServiceConfigurationError
|
||||
// If an I/O error occurs while reading from the given URL, or
|
||||
// if a configuration-file format error is detected
|
||||
//
|
||||
private Iterator<String> parse(Class<?> service, URL u)
|
||||
throws ServiceConfigurationError
|
||||
{
|
||||
InputStream in = null;
|
||||
BufferedReader r = null;
|
||||
ArrayList<String> names = new ArrayList<>();
|
||||
try {
|
||||
// The problem is that by default, streams opened with
|
||||
// u.openInputStream use a cached reference to a JarFile, which
|
||||
// is separate from the reference used by URLClassLoader, and
|
||||
// which is not closed by URLClassLoader.close().
|
||||
// The workaround is to disable caching for this specific jar file,
|
||||
// so that the reference to the jar file can be closed when the
|
||||
// file has been read.
|
||||
// Original code:
|
||||
// in = u.openStream();
|
||||
// Workaround ...
|
||||
URLConnection uc = u.openConnection();
|
||||
uc.setUseCaches(false);
|
||||
in = uc.getInputStream();
|
||||
// ... end of workaround.
|
||||
r = new BufferedReader(new InputStreamReader(in, "utf-8"));
|
||||
int lc = 1;
|
||||
while ((lc = parseLine(service, u, r, lc, names)) >= 0);
|
||||
} catch (IOException x) {
|
||||
fail(service, "Error reading configuration file", x);
|
||||
} finally {
|
||||
try {
|
||||
if (r != null) r.close();
|
||||
if (in != null) in.close();
|
||||
} catch (IOException y) {
|
||||
fail(service, "Error closing configuration file", y);
|
||||
}
|
||||
}
|
||||
return names.iterator();
|
||||
}
|
||||
|
||||
// Private inner class implementing fully-lazy provider lookup
|
||||
//
|
||||
private class LazyIterator
|
||||
implements Iterator<S>
|
||||
{
|
||||
|
||||
Class<S> service;
|
||||
ClassLoader loader;
|
||||
Enumeration<URL> configs = null;
|
||||
Iterator<String> pending = null;
|
||||
String nextName = null;
|
||||
|
||||
private LazyIterator(Class<S> service, ClassLoader loader) {
|
||||
this.service = service;
|
||||
this.loader = loader;
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
if (nextName != null) {
|
||||
return true;
|
||||
}
|
||||
if (configs == null) {
|
||||
try {
|
||||
String fullName = PREFIX + service.getName();
|
||||
if (loader == null)
|
||||
configs = ClassLoader.getSystemResources(fullName);
|
||||
else
|
||||
configs = loader.getResources(fullName);
|
||||
} catch (IOException x) {
|
||||
fail(service, "Error locating configuration files", x);
|
||||
}
|
||||
}
|
||||
while ((pending == null) || !pending.hasNext()) {
|
||||
if (!configs.hasMoreElements()) {
|
||||
return false;
|
||||
}
|
||||
pending = parse(service, configs.nextElement());
|
||||
}
|
||||
nextName = pending.next();
|
||||
return true;
|
||||
}
|
||||
|
||||
public S next() {
|
||||
if (!hasNext()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
String cn = nextName;
|
||||
nextName = null;
|
||||
Class<?> c = null;
|
||||
try {
|
||||
c = Class.forName(cn, false, loader);
|
||||
} catch (ClassNotFoundException x) {
|
||||
fail(service,
|
||||
"Provider " + cn + " not found");
|
||||
}
|
||||
if (!service.isAssignableFrom(c)) {
|
||||
fail(service,
|
||||
"Provider " + cn + " not a subtype");
|
||||
}
|
||||
try {
|
||||
S p = service.cast(c.newInstance());
|
||||
providers.put(cn, p);
|
||||
return p;
|
||||
} catch (Throwable x) {
|
||||
fail(service,
|
||||
"Provider " + cn + " could not be instantiated: " + x,
|
||||
x);
|
||||
}
|
||||
throw new Error(); // This cannot happen
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazily loads the available providers of this loader's service.
|
||||
*
|
||||
* <p> The iterator returned by this method first yields all of the
|
||||
* elements of the provider cache, in instantiation order. It then lazily
|
||||
* loads and instantiates any remaining providers, adding each one to the
|
||||
* cache in turn.
|
||||
*
|
||||
* <p> To achieve laziness the actual work of parsing the available
|
||||
* provider-configuration files and instantiating providers must be done by
|
||||
* the iterator itself. Its {@link java.util.Iterator#hasNext hasNext} and
|
||||
* {@link java.util.Iterator#next next} methods can therefore throw a
|
||||
* {@link ServiceConfigurationError} if a provider-configuration file
|
||||
* violates the specified format, or if it names a provider class that
|
||||
* cannot be found and instantiated, or if the result of instantiating the
|
||||
* class is not assignable to the service type, or if any other kind of
|
||||
* exception or error is thrown as the next provider is located and
|
||||
* instantiated. To write robust code it is only necessary to catch {@link
|
||||
* ServiceConfigurationError} when using a service iterator.
|
||||
*
|
||||
* <p> If such an error is thrown then subsequent invocations of the
|
||||
* iterator will make a best effort to locate and instantiate the next
|
||||
* available provider, but in general such recovery cannot be guaranteed.
|
||||
*
|
||||
* <blockquote style="font-size: smaller; line-height: 1.2"><span
|
||||
* style="padding-right: 1em; font-weight: bold">Design Note</span>
|
||||
* Throwing an error in these cases may seem extreme. The rationale for
|
||||
* this behavior is that a malformed provider-configuration file, like a
|
||||
* malformed class file, indicates a serious problem with the way the Java
|
||||
* virtual machine is configured or is being used. As such it is
|
||||
* preferable to throw an error rather than try to recover or, even worse,
|
||||
* fail silently.</blockquote>
|
||||
*
|
||||
* <p> The iterator returned by this method does not support removal.
|
||||
* Invoking its {@link java.util.Iterator#remove() remove} method will
|
||||
* cause an {@link UnsupportedOperationException} to be thrown.
|
||||
*
|
||||
* @return An iterator that lazily loads providers for this loader's
|
||||
* service
|
||||
*/
|
||||
public Iterator<S> iterator() {
|
||||
return new Iterator<S>() {
|
||||
|
||||
Iterator<Map.Entry<String,S>> knownProviders
|
||||
= providers.entrySet().iterator();
|
||||
|
||||
public boolean hasNext() {
|
||||
if (knownProviders.hasNext())
|
||||
return true;
|
||||
return lookupIterator.hasNext();
|
||||
}
|
||||
|
||||
public S next() {
|
||||
if (knownProviders.hasNext())
|
||||
return knownProviders.next().getValue();
|
||||
return lookupIterator.next();
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new service loader for the given service type and class
|
||||
* loader.
|
||||
*
|
||||
* @param service
|
||||
* The interface or abstract class representing the service
|
||||
*
|
||||
* @param loader
|
||||
* The class loader to be used to load provider-configuration files
|
||||
* and provider classes, or <tt>null</tt> if the system class
|
||||
* loader (or, failing that, the bootstrap class loader) is to be
|
||||
* used
|
||||
*
|
||||
* @return A new service loader
|
||||
*/
|
||||
public static <S> ServiceLoader<S> load(Class<S> service,
|
||||
ClassLoader loader)
|
||||
{
|
||||
return new ServiceLoader<>(service, loader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new service loader for the given service type, using the
|
||||
* current thread's {@linkplain java.lang.Thread#getContextClassLoader
|
||||
* context class loader}.
|
||||
*
|
||||
* <p> An invocation of this convenience method of the form
|
||||
*
|
||||
* <blockquote><pre>
|
||||
* ServiceLoader.load(<i>service</i>)</pre></blockquote>
|
||||
*
|
||||
* is equivalent to
|
||||
*
|
||||
* <blockquote><pre>
|
||||
* ServiceLoader.load(<i>service</i>,
|
||||
* Thread.currentThread().getContextClassLoader())</pre></blockquote>
|
||||
*
|
||||
* @param service
|
||||
* The interface or abstract class representing the service
|
||||
*
|
||||
* @return A new service loader
|
||||
*/
|
||||
public static <S> ServiceLoader<S> load(Class<S> service) {
|
||||
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
return ServiceLoader.load(service, cl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new service loader for the given service type, using the
|
||||
* extension class loader.
|
||||
*
|
||||
* <p> This convenience method simply locates the extension class loader,
|
||||
* call it <tt><i>extClassLoader</i></tt>, and then returns
|
||||
*
|
||||
* <blockquote><pre>
|
||||
* ServiceLoader.load(<i>service</i>, <i>extClassLoader</i>)</pre></blockquote>
|
||||
*
|
||||
* <p> If the extension class loader cannot be found then the system class
|
||||
* loader is used; if there is no system class loader then the bootstrap
|
||||
* class loader is used.
|
||||
*
|
||||
* <p> This method is intended for use when only installed providers are
|
||||
* desired. The resulting service will only find and load providers that
|
||||
* have been installed into the current Java virtual machine; providers on
|
||||
* the application's class path will be ignored.
|
||||
*
|
||||
* @param service
|
||||
* The interface or abstract class representing the service
|
||||
*
|
||||
* @return A new service loader
|
||||
*/
|
||||
public static <S> ServiceLoader<S> loadInstalled(Class<S> service) {
|
||||
ClassLoader cl = ClassLoader.getSystemClassLoader();
|
||||
ClassLoader prev = null;
|
||||
while (cl != null) {
|
||||
prev = cl;
|
||||
cl = cl.getParent();
|
||||
}
|
||||
return ServiceLoader.load(service, prev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string describing this service.
|
||||
*
|
||||
* @return A descriptive string
|
||||
*/
|
||||
public String toString() {
|
||||
return "java.util.ServiceLoader[" + service.getName() + "]";
|
||||
}
|
||||
|
||||
}
|
||||
210
jdkSrc/jdk8/com/sun/tools/javac/util/SharedNameTable.java
Normal file
210
jdkSrc/jdk8/com/sun/tools/javac/util/SharedNameTable.java
Normal file
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import java.lang.ref.SoftReference;
|
||||
|
||||
/**
|
||||
* Implementation of Name.Table that stores all names in a single shared
|
||||
* byte array, expanding it as needed. This avoids the overhead incurred
|
||||
* by using an array of bytes for each name.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class SharedNameTable extends Name.Table {
|
||||
// maintain a freelist of recently used name tables for reuse.
|
||||
private static List<SoftReference<SharedNameTable>> freelist = List.nil();
|
||||
|
||||
static public synchronized SharedNameTable create(Names names) {
|
||||
while (freelist.nonEmpty()) {
|
||||
SharedNameTable t = freelist.head.get();
|
||||
freelist = freelist.tail;
|
||||
if (t != null) {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
return new SharedNameTable(names);
|
||||
}
|
||||
|
||||
static private synchronized void dispose(SharedNameTable t) {
|
||||
freelist = freelist.prepend(new SoftReference<SharedNameTable>(t));
|
||||
}
|
||||
|
||||
/** The hash table for names.
|
||||
*/
|
||||
private NameImpl[] hashes;
|
||||
|
||||
/** The shared byte array holding all encountered names.
|
||||
*/
|
||||
public byte[] bytes;
|
||||
|
||||
/** The mask to be used for hashing
|
||||
*/
|
||||
private int hashMask;
|
||||
|
||||
/** The number of filled bytes in `names'.
|
||||
*/
|
||||
private int nc = 0;
|
||||
|
||||
/** Allocator
|
||||
* @param names The main name table
|
||||
* @param hashSize the (constant) size to be used for the hash table
|
||||
* needs to be a power of two.
|
||||
* @param nameSize the initial size of the name table.
|
||||
*/
|
||||
public SharedNameTable(Names names, int hashSize, int nameSize) {
|
||||
super(names);
|
||||
hashMask = hashSize - 1;
|
||||
hashes = new NameImpl[hashSize];
|
||||
bytes = new byte[nameSize];
|
||||
|
||||
}
|
||||
|
||||
public SharedNameTable(Names names) {
|
||||
this(names, 0x8000, 0x20000);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Name fromChars(char[] cs, int start, int len) {
|
||||
int nc = this.nc;
|
||||
byte[] bytes = this.bytes = ArrayUtils.ensureCapacity(this.bytes, nc + len * 3);
|
||||
int nbytes = Convert.chars2utf(cs, start, bytes, nc, len) - nc;
|
||||
int h = hashValue(bytes, nc, nbytes) & hashMask;
|
||||
NameImpl n = hashes[h];
|
||||
while (n != null &&
|
||||
(n.getByteLength() != nbytes ||
|
||||
!equals(bytes, n.index, bytes, nc, nbytes))) {
|
||||
n = n.next;
|
||||
}
|
||||
if (n == null) {
|
||||
n = new NameImpl(this);
|
||||
n.index = nc;
|
||||
n.length = nbytes;
|
||||
n.next = hashes[h];
|
||||
hashes[h] = n;
|
||||
this.nc = nc + nbytes;
|
||||
if (nbytes == 0) {
|
||||
this.nc++;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Name fromUtf(byte[] cs, int start, int len) {
|
||||
int h = hashValue(cs, start, len) & hashMask;
|
||||
NameImpl n = hashes[h];
|
||||
byte[] names = this.bytes;
|
||||
while (n != null &&
|
||||
(n.getByteLength() != len || !equals(names, n.index, cs, start, len))) {
|
||||
n = n.next;
|
||||
}
|
||||
if (n == null) {
|
||||
int nc = this.nc;
|
||||
names = this.bytes = ArrayUtils.ensureCapacity(names, nc + len);
|
||||
System.arraycopy(cs, start, names, nc, len);
|
||||
n = new NameImpl(this);
|
||||
n.index = nc;
|
||||
n.length = len;
|
||||
n.next = hashes[h];
|
||||
hashes[h] = n;
|
||||
this.nc = nc + len;
|
||||
if (len == 0) {
|
||||
this.nc++;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
dispose(this);
|
||||
}
|
||||
|
||||
static class NameImpl extends Name {
|
||||
/** The next name occupying the same hash bucket.
|
||||
*/
|
||||
NameImpl next;
|
||||
|
||||
/** The index where the bytes of this name are stored in the global name
|
||||
* buffer `byte'.
|
||||
*/
|
||||
int index;
|
||||
|
||||
/** The number of bytes in this name.
|
||||
*/
|
||||
int length;
|
||||
|
||||
NameImpl(SharedNameTable table) {
|
||||
super(table);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getByteLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getByteAt(int i) {
|
||||
return getByteArray()[index + i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getByteArray() {
|
||||
return ((SharedNameTable) table).bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getByteOffset() {
|
||||
return index;
|
||||
}
|
||||
|
||||
/** Return the hash value of this name.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return index;
|
||||
}
|
||||
|
||||
/** Is this name equal to other?
|
||||
*/
|
||||
public boolean equals(Object other) {
|
||||
if (other instanceof Name)
|
||||
return
|
||||
table == ((Name)other).table && index == ((Name) other).getIndex();
|
||||
else return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
70
jdkSrc/jdk8/com/sun/tools/javac/util/StringUtils.java
Normal file
70
jdkSrc/jdk8/com/sun/tools/javac/util/StringUtils.java
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** A collection of utilities for String manipulation.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class StringUtils {
|
||||
|
||||
/**Converts the given String to lower case using the {@link Locale#US US Locale}. The result
|
||||
* is independent of the default Locale in the current JVM instance.
|
||||
*/
|
||||
public static String toLowerCase(String source) {
|
||||
return source.toLowerCase(Locale.US);
|
||||
}
|
||||
|
||||
/**Converts the given String to upper case using the {@link Locale#US US Locale}. The result
|
||||
* is independent of the default Locale in the current JVM instance.
|
||||
*/
|
||||
public static String toUpperCase(String source) {
|
||||
return source.toUpperCase(Locale.US);
|
||||
}
|
||||
|
||||
/**Case insensitive version of {@link String#indexOf(java.lang.String)}. Equivalent to
|
||||
* {@code text.indexOf(str)}, except the matching is case insensitive.
|
||||
*/
|
||||
public static int indexOfIgnoreCase(String text, String str) {
|
||||
return indexOfIgnoreCase(text, str, 0);
|
||||
}
|
||||
|
||||
/**Case insensitive version of {@link String#indexOf(java.lang.String, int)}. Equivalent to
|
||||
* {@code text.indexOf(str, startIndex)}, except the matching is case insensitive.
|
||||
*/
|
||||
public static int indexOfIgnoreCase(String text, String str, int startIndex) {
|
||||
Matcher m = Pattern.compile(Pattern.quote(str), Pattern.CASE_INSENSITIVE).matcher(text);
|
||||
return m.find(startIndex) ? m.start() : -1;
|
||||
}
|
||||
|
||||
}
|
||||
183
jdkSrc/jdk8/com/sun/tools/javac/util/UnsharedNameTable.java
Normal file
183
jdkSrc/jdk8/com/sun/tools/javac/util/UnsharedNameTable.java
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
/**
|
||||
* Implementation of Name.Table that stores names in individual arrays
|
||||
* using weak references. It is recommended for use when a single shared
|
||||
* byte array is unsuitable.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class UnsharedNameTable extends Name.Table {
|
||||
static public Name.Table create(Names names) {
|
||||
return new UnsharedNameTable(names);
|
||||
}
|
||||
|
||||
static class HashEntry extends WeakReference<NameImpl> {
|
||||
HashEntry next;
|
||||
HashEntry(NameImpl referent) {
|
||||
super(referent);
|
||||
}
|
||||
}
|
||||
|
||||
/** The hash table for names.
|
||||
*/
|
||||
private HashEntry[] hashes = null;
|
||||
|
||||
/** The mask to be used for hashing
|
||||
*/
|
||||
private int hashMask;
|
||||
|
||||
/** Index counter for names in this table.
|
||||
*/
|
||||
public int index;
|
||||
|
||||
/** Allocator
|
||||
* @param names The main name table
|
||||
* @param hashSize the (constant) size to be used for the hash table
|
||||
* needs to be a power of two.
|
||||
*/
|
||||
public UnsharedNameTable(Names names, int hashSize) {
|
||||
super(names);
|
||||
hashMask = hashSize - 1;
|
||||
hashes = new HashEntry[hashSize];
|
||||
}
|
||||
|
||||
public UnsharedNameTable(Names names) {
|
||||
this(names, 0x8000);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Name fromChars(char[] cs, int start, int len) {
|
||||
byte[] name = new byte[len * 3];
|
||||
int nbytes = Convert.chars2utf(cs, start, name, 0, len);
|
||||
return fromUtf(name, 0, nbytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Name fromUtf(byte[] cs, int start, int len) {
|
||||
int h = hashValue(cs, start, len) & hashMask;
|
||||
|
||||
HashEntry element = hashes[h];
|
||||
|
||||
NameImpl n = null;
|
||||
|
||||
HashEntry previousNonNullTableEntry = null;
|
||||
HashEntry firstTableEntry = element;
|
||||
|
||||
while (element != null) {
|
||||
if (element == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
n = element.get();
|
||||
|
||||
if (n == null) {
|
||||
if (firstTableEntry == element) {
|
||||
hashes[h] = firstTableEntry = element.next;
|
||||
}
|
||||
else {
|
||||
Assert.checkNonNull(previousNonNullTableEntry, "previousNonNullTableEntry cannot be null here.");
|
||||
previousNonNullTableEntry.next = element.next;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (n.getByteLength() == len && equals(n.bytes, 0, cs, start, len)) {
|
||||
return n;
|
||||
}
|
||||
previousNonNullTableEntry = element;
|
||||
}
|
||||
|
||||
element = element.next;
|
||||
}
|
||||
|
||||
byte[] bytes = new byte[len];
|
||||
System.arraycopy(cs, start, bytes, 0, len);
|
||||
n = new NameImpl(this, bytes, index++);
|
||||
|
||||
HashEntry newEntry = new HashEntry(n);
|
||||
|
||||
if (previousNonNullTableEntry == null) { // We are not the first name with that hashCode.
|
||||
hashes[h] = newEntry;
|
||||
}
|
||||
else {
|
||||
Assert.checkNull(previousNonNullTableEntry.next, "previousNonNullTableEntry.next must be null.");
|
||||
previousNonNullTableEntry.next = newEntry;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
hashes = null;
|
||||
}
|
||||
|
||||
static class NameImpl extends Name {
|
||||
NameImpl(UnsharedNameTable table, byte[] bytes, int index) {
|
||||
super(table);
|
||||
this.bytes = bytes;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
final byte[] bytes;
|
||||
final int index;
|
||||
|
||||
@Override
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getByteLength() {
|
||||
return bytes.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getByteAt(int i) {
|
||||
return bytes[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getByteArray() {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getByteOffset() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
86
jdkSrc/jdk8/com/sun/tools/javac/util/Warner.java
Normal file
86
jdkSrc/jdk8/com/sun/tools/javac/util/Warner.java
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import com.sun.tools.javac.code.Lint.LintCategory;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
|
||||
import java.util.EnumSet;
|
||||
|
||||
/**
|
||||
* An interface to support optional warnings, needed for support of
|
||||
* unchecked conversions and unchecked casts.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class Warner {
|
||||
|
||||
private DiagnosticPosition pos = null;
|
||||
protected boolean warned = false;
|
||||
private EnumSet<LintCategory> nonSilentLintSet = EnumSet.noneOf(LintCategory.class);
|
||||
private EnumSet<LintCategory> silentLintSet = EnumSet.noneOf(LintCategory.class);
|
||||
|
||||
public DiagnosticPosition pos() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
public void warn(LintCategory lint) {
|
||||
nonSilentLintSet.add(lint);
|
||||
}
|
||||
|
||||
public void silentWarn(LintCategory lint) {
|
||||
silentLintSet.add(lint);
|
||||
}
|
||||
|
||||
public Warner(DiagnosticPosition pos) {
|
||||
this.pos = pos;
|
||||
}
|
||||
|
||||
public boolean hasSilentLint(LintCategory lint) {
|
||||
return silentLintSet.contains(lint);
|
||||
}
|
||||
|
||||
public boolean hasNonSilentLint(LintCategory lint) {
|
||||
return nonSilentLintSet.contains(lint);
|
||||
}
|
||||
|
||||
public boolean hasLint(LintCategory lint) {
|
||||
return hasSilentLint(lint) ||
|
||||
hasNonSilentLint(lint);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
nonSilentLintSet.clear();
|
||||
silentLintSet.clear();
|
||||
this.warned = false;
|
||||
}
|
||||
|
||||
public Warner() {
|
||||
this(null);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user