/*
* Copyright 2003-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package jetbrains.mps.make;
import jetbrains.mps.project.MPSExtentions;
import jetbrains.mps.reloading.IClassPathItem;
import jetbrains.mps.util.NameUtil;
import org.eclipse.jdt.core.compiler.CategorizedProblem;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.mps.openapi.module.SModule;
import java.util.HashSet;
import java.util.Set;
/**
* Created by apyshkin on 5/26/16.
*/
public class CompilationErrorsHandler {
private final static int MAX_ERRORS = 100;
private final static String MODULES_CLASSPATH_STR = "Modules: %s;\nClasspath: %s\n"; // FIXME: transfer
private final static String FATAL_ERROR_MSG = "Fatal error during eclipse compilation: %s";
private final static String ERROR_FORMAT_STRING = "%s (line: %d)";
private final static String COMPILATION_PROBLEMS = "Compilation problems";
private final ModulesContainer myModulesContainer;
private final MessageSender mySender;
private final ClassesErrorsTracker myErrorTracker = new ClassesErrorsTracker();
private IClassPathItem myClassPath;
public CompilationErrorsHandler(@NotNull ModulesContainer modulesContainer, @NotNull MessageSender sender,
IClassPathItem classPath) {
myModulesContainer = modulesContainer;
myClassPath = classPath;
mySender = new MessageSender(sender, this);
}
/**
* parses compilation result for errors and prints them out
*
*/
public ClassesErrorsTracker handle(org.eclipse.jdt.internal.compiler.CompilationResult result) {
if (result.getErrors().length > 0) {
mySender.error(COMPILATION_PROBLEMS);
mySender.info(String.format(MODULES_CLASSPATH_STR, myModulesContainer.getModules(), myClassPath));
}
for (final CategorizedProblem problem : result.getErrors()) {
String fileName = new String(problem.getOriginatingFileName());
final String fqName = NameUtil.namespaceFromPath(fileName.substring(0, fileName.length() - MPSExtentions.DOT_JAVAFILE.length()));
myErrorTracker.add(fqName);
SModule containingModule = myModulesContainer.getModuleContainingClass(fqName);
assert containingModule != null;
JavaFile javaFile = myModulesContainer.getSources(containingModule).getJavaFile(fqName);
String messageString = String.valueOf(problem.getOriginatingFileName()) + " : " + problem.getMessage();
//final SNode nodeToShow = getNodeByLine(problem, fqName);
Object hintObject = new FileWithPosition(javaFile.getFile(), problem.getSourceStart());
String errMsg = String.format(ERROR_FORMAT_STRING, messageString, problem.getSourceLineNumber());
if (problem.isWarning()) {
mySender.warn(errMsg, hintObject);
} else if (myErrorTracker.errorsBelowLimit()) {
myErrorTracker.incErrCnt();
mySender.error(errMsg, hintObject);
}
}
return myErrorTracker;
}
public void handleFatal(@NotNull String msg) {
mySender.error(String.format(FATAL_ERROR_MSG, msg), null);
mySender.info(String.format(MODULES_CLASSPATH_STR, myModulesContainer.getModules(), myClassPath));
myErrorTracker.incErrCnt();
}
public int getErrorsCount() {
return myErrorTracker.getErrorsCount();
}
/**
* a set of classes fqNames which contain errors and an error counter
*/
public final static class ClassesErrorsTracker {
private final Set<String> myFqNamesWithErrors = new HashSet<String>();
private int myErrorsCount = 0;
public int getErrorsCount() {
return myErrorsCount;
}
public void add(@NotNull String classWithError) {
myFqNamesWithErrors.add(classWithError);
}
public boolean hasError(@NotNull String classFqName) {
return myFqNamesWithErrors.contains(classFqName);
}
public void incErrCnt() {
myErrorsCount++;
}
public boolean errorsBelowLimit() {
return myErrorsCount < MAX_ERRORS;
}
}
}