package org.eclipse.jdt.internal.core;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.jdt.core.*;
import org.eclipse.jdt.core.compiler.CategorizedProblem;
import org.eclipse.jdt.internal.compiler.*;
import org.eclipse.jdt.internal.compiler.Compiler;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
import org.eclipse.jdt.internal.compiler.env.IModule;
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
import org.eclipse.jdt.internal.compiler.env.ISourceType;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.parser.SourceTypeConverter;
import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
import org.eclipse.jdt.internal.core.util.CommentRecorderParser;
import org.eclipse.jdt.internal.core.util.Util;
@SuppressWarnings({ "rawtypes", "unchecked" })
public class CompilationUnitProblemFinder extends Compiler {
protected CompilationUnitProblemFinder(
INameEnvironment environment,
IErrorHandlingPolicy policy,
CompilerOptions compilerOptions,
ICompilerRequestor requestor,
IProblemFactory problemFactory) {
super(environment,
policy,
compilerOptions,
requestor,
problemFactory
);
}
@Override
public void accept(ISourceType[] sourceTypes, PackageBinding packageBinding, AccessRestriction accessRestriction) {
while (sourceTypes[0].getEnclosingType() != null) {
sourceTypes[0] = sourceTypes[0].getEnclosingType();
}
CompilationResult result =
new CompilationResult(sourceTypes[0].getFileName(), 1, 1, this.options.maxProblemsPerUnit);
final long savedComplianceLevel = this.options.complianceLevel;
final long savedSourceLevel = this.options.sourceLevel;
LookupEnvironment environment = packageBinding.environment;
if (environment == null)
environment = this.lookupEnvironment;
try {
IJavaProject project = ((SourceTypeElementInfo) sourceTypes[0]).getHandle().getJavaProject();
this.options.complianceLevel = CompilerOptions.versionToJdkLevel(project.getOption(JavaCore.COMPILER_COMPLIANCE, true));
this.options.sourceLevel = CompilerOptions.versionToJdkLevel(project.getOption(JavaCore.COMPILER_SOURCE, true));
CompilationUnitDeclaration unit =
SourceTypeConverter.buildCompilationUnit(
sourceTypes,
SourceTypeConverter.FIELD_AND_METHOD
| SourceTypeConverter.MEMBER_TYPE
| SourceTypeConverter.FIELD_INITIALIZATION,
environment.problemReporter,
result);
if (unit != null) {
environment.buildTypeBindings(unit, accessRestriction);
environment.completeTypeBindings(unit);
}
} finally {
this.options.complianceLevel = savedComplianceLevel;
this.options.sourceLevel = savedSourceLevel;
}
}
@Override
public void accept(IModule module, LookupEnvironment environment) {
IModuleDescription handle = null;
if (module instanceof ModuleDescriptionInfo) {
handle = ((ModuleDescriptionInfo) module).getHandle();
}
if (handle == null) {
super.accept(module, environment);
return;
}
CompilationResult result =
new CompilationResult(TypeConstants.MODULE_INFO_FILE_NAME, 1, 1, this.options.maxProblemsPerUnit);
final long savedComplianceLevel = this.options.complianceLevel;
final long savedSourceLevel = this.options.sourceLevel;
if (environment == null)
environment = this.lookupEnvironment;
try {
IJavaProject project = handle.getJavaProject();
this.options.complianceLevel = CompilerOptions.versionToJdkLevel(project.getOption(JavaCore.COMPILER_COMPLIANCE, true));
this.options.sourceLevel = CompilerOptions.versionToJdkLevel(project.getOption(JavaCore.COMPILER_SOURCE, true));
CompilationUnitDeclaration unit =
SourceTypeConverter.buildModularCompilationUnit(
module,
environment.problemReporter,
result);
if (unit != null) {
environment.buildTypeBindings(unit, null);
environment.completeTypeBindings(unit);
}
} finally {
this.options.complianceLevel = savedComplianceLevel;
this.options.sourceLevel = savedSourceLevel;
}
}
protected static CompilerOptions getCompilerOptions(Map settings, boolean creatingAST, boolean statementsRecovery) {
CompilerOptions compilerOptions = new CompilerOptions(settings);
compilerOptions.performMethodsFullRecovery = statementsRecovery;
compilerOptions.performStatementsRecovery = statementsRecovery;
compilerOptions.parseLiteralExpressionsAsConstants = !creatingAST;
if (creatingAST)
compilerOptions.storeAnnotations = true;
return compilerOptions;
}
protected static IErrorHandlingPolicy getHandlingPolicy() {
return DefaultErrorHandlingPolicies.proceedWithAllProblems();
}
protected static ICompilerRequestor getRequestor() {
return new ICompilerRequestor() {
@Override
public void acceptResult(CompilationResult compilationResult) {
}
};
}
private static boolean isTestSource(IJavaProject project, ICompilationUnit cu) {
try {
IClasspathEntry[] resolvedClasspath = project.getResolvedClasspath(true);
final IPath resourcePath = cu.getResource().getFullPath();
for (IClasspathEntry e : resolvedClasspath) {
if (e.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
if (e.isTest()) {
if (e.getPath().isPrefixOf(resourcePath)) {
return true;
}
}
}
}
} catch (JavaModelException e) {
Util.log(e, "Exception while determining if compilation unit \"" + cu.getElementName()
+ "\" is test source");
}
return false;
}
public static CompilationUnitDeclaration process(
CompilationUnit unitElement,
SourceElementParser parser,
WorkingCopyOwner workingCopyOwner,
HashMap problems,
boolean creatingAST,
int reconcileFlags,
IProgressMonitor monitor)
throws JavaModelException {
JavaProject project = (JavaProject) unitElement.getJavaProject();
CancelableNameEnvironment environment = null;
CancelableProblemFactory problemFactory = null;
CompilationUnitProblemFinder problemFinder = null;
CompilationUnitDeclaration unit = null;
try {
environment = new CancelableNameEnvironment(project, workingCopyOwner, monitor, !isTestSource(unitElement.getJavaProject(), unitElement));
problemFactory = new CancelableProblemFactory(monitor);
CompilerOptions compilerOptions = getCompilerOptions(project.getOptions(true), creatingAST, ((reconcileFlags & ICompilationUnit.ENABLE_STATEMENTS_RECOVERY) != 0));
boolean ignoreMethodBodies = (reconcileFlags & ICompilationUnit.IGNORE_METHOD_BODIES) != 0;
compilerOptions.ignoreMethodBodies = ignoreMethodBodies;
problemFinder = new CompilationUnitProblemFinder(
environment,
getHandlingPolicy(),
compilerOptions,
getRequestor(),
problemFactory);
boolean analyzeAndGenerateCode = true;
if (ignoreMethodBodies) {
analyzeAndGenerateCode = false;
}
try {
if (parser != null) {
problemFinder.parser = parser;
unit = parser.parseCompilationUnit(unitElement, true, monitor);
problemFinder.resolve(
unit,
unitElement,
true,
analyzeAndGenerateCode,
analyzeAndGenerateCode);
} else {
unit =
problemFinder.resolve(
unitElement,
true,
analyzeAndGenerateCode,
analyzeAndGenerateCode);
}
} catch (AbortCompilation e) {
problemFinder.handleInternalException(e, unit);
}
if (unit != null) {
CompilationResult unitResult = unit.compilationResult;
CategorizedProblem[] unitProblems = unitResult.getCUProblems();
int length = unitProblems == null ? 0 : unitProblems.length;
if (length > 0) {
CategorizedProblem[] categorizedProblems = new CategorizedProblem[length];
System.arraycopy(unitProblems, 0, categorizedProblems, 0, length);
problems.put(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, categorizedProblems);
}
unitProblems = unitResult.getTasks();
length = unitProblems == null ? 0 : unitProblems.length;
if (length > 0) {
CategorizedProblem[] categorizedProblems = new CategorizedProblem[length];
System.arraycopy(unitProblems, 0, categorizedProblems, 0, length);
problems.put(IJavaModelMarker.TASK_MARKER, categorizedProblems);
}
if (NameLookup.VERBOSE) {
System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInSourcePackage: " + environment.nameLookup.timeSpentInSeekTypesInSourcePackage + "ms");
System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInBinaryPackage: " + environment.nameLookup.timeSpentInSeekTypesInBinaryPackage + "ms");
}
}
} catch (OperationCanceledException e) {
throw e;
} catch(RuntimeException e) {
String lineDelimiter = unitElement.findRecommendedLineSeparator();
StringBuffer message = new StringBuffer("Exception occurred during problem detection:");
message.append(lineDelimiter);
message.append("----------------------------------- SOURCE BEGIN -------------------------------------");
message.append(lineDelimiter);
message.append(unitElement.getSource());
message.append(lineDelimiter);
message.append("----------------------------------- SOURCE END -------------------------------------");
Util.log(e, message.toString());
throw new JavaModelException(e, IJavaModelStatusConstants.COMPILER_FAILURE);
} finally {
if (environment != null)
environment.setMonitor(null);
if (problemFactory != null)
problemFactory.monitor = null;
if (problemFinder != null && !creatingAST)
problemFinder.lookupEnvironment.reset();
}
return unit;
}
public static CompilationUnitDeclaration process(
CompilationUnit unitElement,
WorkingCopyOwner workingCopyOwner,
HashMap problems,
boolean creatingAST,
int reconcileFlags,
IProgressMonitor monitor)
throws JavaModelException {
return process(unitElement, null, workingCopyOwner, problems, creatingAST, reconcileFlags, monitor);
}
@Override
public void initializeParser() {
this.parser = new CommentRecorderParser(this.problemReporter, this.options.parseLiteralExpressionsAsConstants);
}
}