use of org.revapi.java.spi.Check in project revapi by revapi.
the class JavaApiAnalyzer method getJSONSchema.
@Nullable
@Override
public Reader getJSONSchema() {
Map<String, Reader> checkSchemas = new HashMap<>(4);
for (Check c : checks) {
if (c.getExtensionId() != null) {
checkSchemas.put(c.getExtensionId(), c.getJSONSchema());
}
}
Reader rdr = new InputStreamReader(getClass().getResourceAsStream("/META-INF/config-schema.json"), Charset.forName("UTF-8"));
if (checkSchemas.isEmpty()) {
return rdr;
} else {
try {
ModelNode baseSchema = ModelNode.fromJSONString(consume(rdr));
ModelNode checksNode = baseSchema.get("properties", "checks");
checksNode.get("type").set("object");
for (Map.Entry<String, Reader> entry : checkSchemas.entrySet()) {
String checkId = entry.getKey();
Reader checkSchemaReader = entry.getValue();
ModelNode checkSchema = ModelNode.fromJSONString(consume(checkSchemaReader));
checksNode.get("properties").get(checkId).set(checkSchema);
}
return new StringReader(baseSchema.toJSONString(false));
} catch (IOException e) {
throw new IllegalStateException("Could not read the schema for the revapi extension...", e);
}
}
}
use of org.revapi.java.spi.Check in project revapi by revapi.
the class JavaApiAnalyzer method initialize.
@Override
public void initialize(@Nonnull AnalysisContext analysisContext) {
this.analysisContext = analysisContext;
this.configuration = AnalysisConfiguration.fromModel(analysisContext.getConfiguration());
for (Check c : checks) {
if (c.getExtensionId() != null) {
ModelNode checkConfig = analysisContext.getConfiguration().get("checks", c.getExtensionId());
AnalysisContext checkCtx = analysisContext.copyWithConfiguration(checkConfig);
c.initialize(checkCtx);
}
}
}
use of org.revapi.java.spi.Check in project revapi by revapi.
the class JavaElementDifferenceAnalyzer method doRestrictedCheck.
private <T extends JavaModelElement> void doRestrictedCheck(T oldElement, T newElement, CheckType interest, Collection<Check> possibleChecks) {
lastAnnotationResults = null;
if (!(isCheckedElsewhere(oldElement, oldEnvironment) && isCheckedElsewhere(newElement, newEnvironment))) {
checkTypeStack.push(interest);
checksStack.push(possibleChecks);
for (Check c : possibleChecks) {
Stats.of(c.getClass().getName()).start();
switch(interest) {
case FIELD:
c.visitField((FieldElement) oldElement, (FieldElement) newElement);
break;
case METHOD:
c.visitMethod((MethodElement) oldElement, (MethodElement) newElement);
break;
case METHOD_PARAMETER:
c.visitMethodParameter((MethodParameterElement) oldElement, (MethodParameterElement) newElement);
break;
}
Stats.of(c.getClass().getName()).end(oldElement, newElement);
}
} else {
// "ignore what's on the stack because no checks actually happened".
checkTypeStack.push(CheckType.NONE);
checksStack.push(emptyList());
}
}
use of org.revapi.java.spi.Check in project revapi by revapi.
the class JavaElementDifferenceAnalyzer method endAnalysis.
@Override
public Report endAnalysis(@Nullable Element oldElement, @Nullable Element newElement) {
if (oldElement == nonExistenceOldRoot && newElement == nonExistenceNewRoot) {
nonExistenceMode = false;
nonExistenceOldRoot = null;
nonExistenceNewRoot = null;
}
if (conforms(oldElement, newElement, AnnotationElement.class)) {
// the annotations are always reported at the parent element
return new Report(Collections.emptyList(), oldElement, newElement);
}
List<Difference> differences = new ArrayList<>();
CheckType lastInterest = checkTypeStack.pop();
if (lastInterest.isConcrete()) {
for (Check c : checksStack.pop()) {
List<Difference> p = c.visitEnd();
if (p != null) {
differences.addAll(p);
}
}
}
if (lastAnnotationResults != null && !lastAnnotationResults.isEmpty()) {
differences.addAll(lastAnnotationResults);
lastAnnotationResults.clear();
}
if (!differences.isEmpty()) {
LOG.trace("Detected following problems: {}", differences);
}
Timing.LOG.trace("Ended analysis of {} and {}.", oldElement, newElement);
ListIterator<Difference> it = differences.listIterator();
while (it.hasNext()) {
Difference d = it.next();
if (analysisConfiguration.reportUseForAllDifferences() || analysisConfiguration.getUseReportingCodes().contains(d.code)) {
StringBuilder oldUseChain = null;
StringBuilder newUseChain = null;
if (oldElement != null) {
oldUseChain = new StringBuilder();
appendUses(oldEnvironment, oldElement, oldUseChain);
}
if (newElement != null) {
newUseChain = new StringBuilder();
appendUses(newEnvironment, newElement, newUseChain);
}
Map<String, String> atts = new HashMap<>(d.attachments);
if (oldUseChain != null) {
atts.put("exampleUseChainInOldApi", oldUseChain.toString());
}
if (newUseChain != null) {
atts.put("exampleUseChainInNewApi", newUseChain.toString());
}
d = Difference.builder().addAttachments(atts).addClassifications(d.classification).withCode(d.code).withName(d.name).withDescription(d.description).build();
}
it.set(d);
}
return new Report(differences, oldElement, newElement);
}
use of org.revapi.java.spi.Check in project revapi by revapi.
the class JavaElementDifferenceAnalyzer method beginAnalysis.
@Override
public void beginAnalysis(@Nullable Element oldElement, @Nullable Element newElement) {
Timing.LOG.trace("Beginning analysis of {} and {}.", oldElement, newElement);
Check.Type elementsType = getCheckType(oldElement, newElement);
Collection<Check> possibleChecks = nonExistenceMode ? descendingChecksByTypes.getOrDefault(elementsType, emptySet()) : checksByInterest.get(elementsType);
if (conforms(oldElement, newElement, TypeElement.class)) {
checkTypeStack.push(CheckType.CLASS);
checksStack.push(possibleChecks);
lastAnnotationResults = null;
for (Check c : possibleChecks) {
Stats.of(c.getClass().getName()).start();
c.visitClass(oldElement == null ? null : (TypeElement) oldElement, newElement == null ? null : (TypeElement) newElement);
Stats.of(c.getClass().getName()).end(oldElement, newElement);
}
} else if (conforms(oldElement, newElement, AnnotationElement.class)) {
// treat them a bit differently
if (lastAnnotationResults == null) {
lastAnnotationResults = new ArrayList<>(4);
}
// Annotations are handled differently and this would lead to the stack corruption and missed problems!!!
for (Check c : possibleChecks) {
Stats.of(c.getClass().getName()).start();
List<Difference> cps = c.visitAnnotation(oldElement == null ? null : (AnnotationElement) oldElement, newElement == null ? null : (AnnotationElement) newElement);
if (cps != null) {
lastAnnotationResults.addAll(cps);
}
Stats.of(c.getClass().getName()).end(oldElement, newElement);
}
} else if (conforms(oldElement, newElement, FieldElement.class)) {
doRestrictedCheck((FieldElement) oldElement, (FieldElement) newElement, CheckType.FIELD, possibleChecks);
} else if (conforms(oldElement, newElement, MethodElement.class)) {
doRestrictedCheck((MethodElement) oldElement, (MethodElement) newElement, CheckType.METHOD, possibleChecks);
} else if (conforms(oldElement, newElement, MethodParameterElement.class)) {
doRestrictedCheck((MethodParameterElement) oldElement, (MethodParameterElement) newElement, CheckType.METHOD_PARAMETER, possibleChecks);
}
if (!nonExistenceMode && (oldElement == null || newElement == null)) {
nonExistenceMode = true;
nonExistenceOldRoot = oldElement;
nonExistenceNewRoot = newElement;
}
}
Aggregations