public boolean isSuppressed(CategorizedProblem problem) { if (this.suppressWarningsCount == 0) return false; int irritant = ProblemReporter.getIrritant(problem.getID()); if (irritant == 0) return false; int start = problem.getSourceStart(); int end = problem.getSourceEnd(); nextSuppress: for (int iSuppress = 0, suppressCount = this.suppressWarningsCount; iSuppress < suppressCount; iSuppress++) { long position = this.suppressWarningScopePositions[iSuppress]; int startSuppress = (int) (position >>> 32); int endSuppress = (int) position; if (start < startSuppress) continue nextSuppress; if (end > endSuppress) continue nextSuppress; if (this.suppressWarningIrritants[iSuppress].isSet(irritant)) return true; } return false; }
public void finalizeProblems() { if (this.suppressWarningsCount == 0) return; int removed = 0; CategorizedProblem[] problems = this.compilationResult.problems; int problemCount = this.compilationResult.problemCount; IrritantSet[] foundIrritants = new IrritantSet[this.suppressWarningsCount]; CompilerOptions options = this.scope.compilerOptions(); boolean hasMandatoryErrors = false; nextProblem: for (int iProblem = 0, length = problemCount; iProblem < length; iProblem++) { CategorizedProblem problem = problems[iProblem]; int problemID = problem.getID(); int irritant = ProblemReporter.getIrritant(problemID); boolean isError = problem.isError(); if (isError) { if (irritant == 0) { // tolerate unused warning tokens when mandatory errors hasMandatoryErrors = true; continue; } if (!options.suppressOptionalErrors) { continue; } } int start = problem.getSourceStart(); int end = problem.getSourceEnd(); nextSuppress: for (int iSuppress = 0, suppressCount = this.suppressWarningsCount; iSuppress < suppressCount; iSuppress++) { long position = this.suppressWarningScopePositions[iSuppress]; int startSuppress = (int) (position >>> 32); int endSuppress = (int) position; if (start < startSuppress) continue nextSuppress; if (end > endSuppress) continue nextSuppress; if (!this.suppressWarningIrritants[iSuppress].isSet(irritant)) continue nextSuppress; // discard suppressed warning removed++; problems[iProblem] = null; this.compilationResult.removeProblem(problem); if (foundIrritants[iSuppress] == null) { foundIrritants[iSuppress] = new IrritantSet(irritant); } else { foundIrritants[iSuppress].set(irritant); } continue nextProblem; } } // compact remaining problems if (removed > 0) { for (int i = 0, index = 0; i < problemCount; i++) { CategorizedProblem problem; if ((problem = problems[i]) != null) { if (i > index) { problems[index++] = problem; } else { index++; } } } } // flag SuppressWarnings which had no effect (only if no (mandatory) error got detected within // unit if (!hasMandatoryErrors) { int severity = options.getSeverity(CompilerOptions.UnusedWarningToken); if (severity != ProblemSeverities.Ignore) { boolean unusedWarningTokenIsWarning = (severity & ProblemSeverities.Error) == 0; for (int iSuppress = 0, suppressCount = this.suppressWarningsCount; iSuppress < suppressCount; iSuppress++) { Annotation annotation = this.suppressWarningAnnotations[iSuppress]; if (annotation == null) continue; // implicit annotation IrritantSet irritants = this.suppressWarningIrritants[iSuppress]; if (unusedWarningTokenIsWarning && irritants.areAllSet()) continue; // @SuppressWarnings("all") also suppresses unused warning token if (irritants != foundIrritants[iSuppress]) { // mismatch, some warning tokens were unused MemberValuePair[] pairs = annotation.memberValuePairs(); pairLoop: for (int iPair = 0, pairCount = pairs.length; iPair < pairCount; iPair++) { MemberValuePair pair = pairs[iPair]; if (CharOperation.equals(pair.name, TypeConstants.VALUE)) { Expression value = pair.value; if (value instanceof ArrayInitializer) { ArrayInitializer initializer = (ArrayInitializer) value; Expression[] inits = initializer.expressions; if (inits != null) { for (int iToken = 0, tokenCount = inits.length; iToken < tokenCount; iToken++) { Constant cst = inits[iToken].constant; if (cst != Constant.NotAConstant && cst.typeID() == TypeIds.T_JavaLangString) { IrritantSet tokenIrritants = CompilerOptions.warningTokenToIrritants(cst.stringValue()); if (tokenIrritants != null && !tokenIrritants .areAllSet() // no complaint against @SuppressWarnings("all") && options.isAnyEnabled( tokenIrritants) // if irritant is effectively enabled && (foundIrritants[iSuppress] == null || !foundIrritants[iSuppress].isAnySet( tokenIrritants))) { // if irritant had no matching problem if (unusedWarningTokenIsWarning) { int start = value.sourceStart, end = value.sourceEnd; nextSuppress: for (int jSuppress = iSuppress - 1; jSuppress >= 0; jSuppress--) { long position = this.suppressWarningScopePositions[jSuppress]; int startSuppress = (int) (position >>> 32); int endSuppress = (int) position; if (start < startSuppress) continue nextSuppress; if (end > endSuppress) continue nextSuppress; if (this.suppressWarningIrritants[jSuppress].areAllSet()) break pairLoop; // suppress all? } } this.scope.problemReporter().unusedWarningToken(inits[iToken]); } } } } } else { Constant cst = value.constant; if (cst != Constant.NotAConstant && cst.typeID() == T_JavaLangString) { IrritantSet tokenIrritants = CompilerOptions.warningTokenToIrritants(cst.stringValue()); if (tokenIrritants != null && !tokenIrritants .areAllSet() // no complaint against @SuppressWarnings("all") && options.isAnyEnabled( tokenIrritants) // if irritant is effectively enabled && (foundIrritants[iSuppress] == null || !foundIrritants[iSuppress].isAnySet( tokenIrritants))) { // if irritant had no matching problem if (unusedWarningTokenIsWarning) { int start = value.sourceStart, end = value.sourceEnd; nextSuppress: for (int jSuppress = iSuppress - 1; jSuppress >= 0; jSuppress--) { long position = this.suppressWarningScopePositions[jSuppress]; int startSuppress = (int) (position >>> 32); int endSuppress = (int) position; if (start < startSuppress) continue nextSuppress; if (end > endSuppress) continue nextSuppress; if (this.suppressWarningIrritants[jSuppress].areAllSet()) break pairLoop; // suppress all? } } this.scope.problemReporter().unusedWarningToken(value); } } } break pairLoop; } } } } } } }
@Override public void onCompilationResult(CompilationResult cr) { Set<String> classesWithErrors = new HashSet<String>(); if (cr.getErrors() != null) { myTracer.push("handling errors", false); for (final CategorizedProblem cp : cr.getErrors()) { String fileName = new String(cp.getOriginatingFileName()); final String fqName = NameUtil.namespaceFromPath( fileName.substring(0, fileName.length() - MPSExtentions.DOT_JAVAFILE.length())); classesWithErrors.add(fqName); SModule containingModule = myContainingModules.get(fqName); assert containingModule != null; JavaFile javaFile = myModuleSources.get(containingModule).getJavaFile(fqName); String messageString = new String(cp.getOriginatingFileName()) + " : " + cp.getMessage(); // final SNode nodeToShow = getNodeByLine(cp, fqName); Object hintObject = new FileWithPosition(javaFile.getFile(), cp.getSourceStart()); String errMsg = messageString + " (line: " + cp.getSourceLineNumber() + ")"; if (cp.isWarning()) { myMessages.add(createMessage(MessageKind.WARNING, errMsg, hintObject)); } else { if (myOutputtedErrors == 0) { myMessages.add(createMessage(MessageKind.ERROR, "Compilation problems", null)); myMessages.add( createMessage( MessageKind.INFORMATION, "Modules: " + myModules.toString() + "\nClasspath: " + myClassPathItems + "\n", null)); } if (myOutputtedErrors < MAX_ERRORS) { myOutputtedErrors++; myMessages.add(createMessage(MessageKind.ERROR, errMsg, hintObject)); } } } myTracer.pop(); myErrorCount += cr.getErrors().length; } myTracer.push("storing files", false); for (ClassFile cf : cr.getClassFiles()) { String fqName = convertCompoundToFqName(cf.getCompoundName()); String containerClassName = fqName; if (containerClassName.contains("$")) { int index = containerClassName.indexOf('$'); containerClassName = containerClassName.substring(0, index); } if (myContainingModules.containsKey(containerClassName)) { SModule m = myContainingModules.get(containerClassName); myChangedModules.add(m); File classesGen = new File(getJavaFacet(m).getClassesGen().getPath()); String packageName = NameUtil.namespaceFromLongName(fqName); File outputDir = new File(classesGen + File.separator + NameUtil.pathFromNamespace(packageName)); if (!outputDir.exists()) { if (!outputDir.mkdirs()) { throw new RuntimeException("Can't create " + outputDir.getPath() + " directory"); } } String className = NameUtil.shortNameFromLongName(fqName); File output = new File(outputDir, className + ".class"); if (!classesWithErrors.contains(containerClassName)) { FileOutputStream os = null; try { os = new FileOutputStream(output); os.write(cf.getBytes()); } catch (IOException e) { String errMsg = "Can't write to " + output.getAbsolutePath(); myMessages.add(createMessage(MessageKind.ERROR, errMsg, null)); } finally { if (os != null) { try { os.close(); } catch (IOException e) { myHandler.handle(createMessage(MessageKind.ERROR, e.toString(), e)); } } } } else { if (output.exists() && !(output.delete())) { String errMsg = "Can't delete " + output.getPath(); myMessages.add(createMessage(MessageKind.ERROR, errMsg, null)); } } } else { String errMsg = "I don't know in which module's output path I should place class file for " + fqName; myMessages.add(createMessage(MessageKind.ERROR, errMsg, null)); } } myTracer.pop(); }