/*
* This file is part of the OpenJML project.
* Author: David R. Cok
*/
package org.jmlspecs.openjml;
import java.util.ArrayList;
import java.util.Collection;
import javax.tools.JavaFileObject;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.DiagnosticSource;
/** This class records all the Nowarn annoations in an OpenJML compile. Nowarn
* annotations are syntactic; they can appear anywhere in a line and affect
* the reporting of warnings and errors against that line.
*/
public class Nowarns {
/** The key to use to retrieve the instance of this class from the Context object. */
//@ non_null
public static final Context.Key<Nowarns> nowarnsKey =
new Context.Key<Nowarns>();
/** A method that returns the unique instance of this class for the given Context
* (creating it if it does not already exist).
*
* @param context the Context whose Nowarns instance is wanted
* @return the singleton instance (per Context) of this class
*/
//@ non_null
public static Nowarns instance(Context context) {
Nowarns instance = context.get(nowarnsKey);
if (instance == null) {
instance = new Nowarns(context);
context.put(nowarnsKey, instance);
}
return instance;
}
/** A class that holds the record of a particular Nowarn annotation
* in the code.
*/
public static class Item {
/** The source object */
/*@Nullable*/ DiagnosticSource source;
/** The 1-based line number of the location of the annotation. */
int line;
/** The label contained in the annotation. */
String label;
/** Constructs the record of a Nowarn annotation */
public Item(DiagnosticSource source, int line, String label) {
this.source = source;
this.line = line;
this.label = label;
}
}
/** The usual compilation context. */
protected Context context;
/** The collection of nowarn annotation items. */
protected Collection<Item> nowarns = new ArrayList<Item>();
/** Constructor for the (singleton) instance of the Nowarns object; users
* should not call this - use instance(context).
*/
protected Nowarns(Context context) {
this.context = context;
}
/** Add a new occurrence of an annotation to the record. */
public void addItem(DiagnosticSource file, int pos, String label) {
nowarns.add(new Item(file,file.getLineNumber(pos),label));
}
/** Check the set of annotations to see if a particular warning should be
* suppressed
* @return true if there is a recorded annotation with the given source, position and label
*/
// FIXME - this is an inefficient lookup, and in the following method
public boolean suppress(DiagnosticSource file, int pos, String label) {
int line = file.getLineNumber(pos);
for (Item i: nowarns) {
if (i.label != null && !label.equals(i.label)) {
// continue
} else if (i.source == null) {
return true; // FIXME - don't we check the line number? what use case is this?
} else {
if (file.equals(i.source) && line == i.line) return true;
}
}
return false;
}
/** Check the set of annotations to see if a particular warning should be
* suppressed
* @return true if there is a recorded annotation with the given source, position and label
*/
public boolean suppress(JavaFileObject file, int pos, String label) {
for (Item i: nowarns) {
if (i.label != null && !label.equals(i.label)) {
// continue
} else if (i.source == null) {
return true;
} else {
if (Utils.ifSourcesEqual(file, i.source.getFile()) && i.source.getLineNumber(pos) == i.line) return true;
}
}
return false;
}
}