private static boolean hasNotNullAnnotations( final Cache cache, final SymbolTable symbolTable, final int className, Project project) throws CacheCorruptedException { final NullableNotNullManager manager = NullableNotNullManager.getInstance(project); final List<String> notNulls = manager.getNotNulls(); for (MethodInfo methodId : cache.getMethods(className)) { for (AnnotationConstantValue annotation : methodId.getRuntimeInvisibleAnnotations()) { if (notNulls.contains(symbolTable.getSymbol(annotation.getAnnotationQName()))) { return true; } } final AnnotationConstantValue[][] paramAnnotations = methodId.getRuntimeInvisibleParameterAnnotations(); for (AnnotationConstantValue[] _singleParamAnnotations : paramAnnotations) { for (AnnotationConstantValue annotation : _singleParamAnnotations) { if (notNulls.contains(symbolTable.getSymbol(annotation.getAnnotationQName()))) { return true; } } } } return false; }
private void updateOutputItemsList( final String outputDir, final VirtualFile srcFile, VirtualFile sourceRoot, final String packagePrefix, final List<File> filesToRefresh, Map<String, Collection<TranslatingCompiler.OutputItem>> results, final GlobalSearchScope srcRootScope) throws CacheCorruptedException { CompositeDependencyCache dependencyCache = myCompileContext.getDependencyCache(); JavaDependencyCache child = dependencyCache.findChild(JavaDependencyCache.class); final Cache newCache = child.getNewClassesCache(); final Set<CompiledClass> paths = myFileNameToSourceMap.get(srcFile.getName()); if (paths == null || paths.isEmpty()) { return; } final String filePath = "/" + calcPackagePath(srcFile, sourceRoot, packagePrefix); for (final CompiledClass cc : paths) { myCompileContext.getProgressIndicator().checkCanceled(); if (LOG.isDebugEnabled()) { LOG.debug("Checking [pathToClass; relPathToSource] = " + cc); } boolean pathsEquals = FileUtil.pathsEqual(filePath, cc.relativePathToSource); if (!pathsEquals) { final String qName = child.resolve(cc.qName); if (qName != null) { pathsEquals = ApplicationManager.getApplication() .runReadAction( new Computable<Boolean>() { public Boolean compute() { final JavaPsiFacade facade = JavaPsiFacade.getInstance(myProject); PsiClass psiClass = facade.findClass(qName, srcRootScope); if (psiClass == null) { final int dollarIndex = qName.indexOf("$"); if (dollarIndex >= 0) { final String topLevelClassName = qName.substring(0, dollarIndex); psiClass = facade.findClass(topLevelClassName, srcRootScope); } } if (psiClass != null) { final VirtualFile vFile = psiClass.getContainingFile().getVirtualFile(); return vFile != null && vFile.equals(srcFile); } return false; } }); } } if (pathsEquals) { final String outputPath = cc.pathToClass.replace(File.separatorChar, '/'); final Pair<String, String> realLocation = moveToRealLocation(outputDir, outputPath, srcFile, filesToRefresh); if (realLocation != null) { Collection<TranslatingCompiler.OutputItem> outputs = results.get(realLocation.getFirst()); if (outputs == null) { outputs = new ArrayList<TranslatingCompiler.OutputItem>(); results.put(realLocation.getFirst(), outputs); } outputs.add(new OutputItemImpl(realLocation.getSecond(), srcFile)); if (PACKAGE_ANNOTATION_FILE_NAME.equals(srcFile.getName())) { myProcessedPackageInfos.add(srcFile); } if (CompilerManager.MAKE_ENABLED) { newCache.setPath(cc.qName, realLocation.getSecond()); } if (LOG.isDebugEnabled()) { LOG.debug( "Added output item: [outputDir; outputPath; sourceFile] = [" + realLocation.getFirst() + "; " + realLocation.getSecond() + "; " + srcFile.getPresentableUrl() + "]"); } } else { myCompileContext.addMessage( CompilerMessageCategory.ERROR, "Failed to copy from temporary location to output directory: " + outputPath + " (see idea.log for details)", null, -1, -1); if (LOG.isDebugEnabled()) { LOG.debug("Failed to move to real location: " + outputPath + "; from " + outputDir); } } } } }
private void processPath(FileObject fileObject, Project project) throws CacheCorruptedException { File file = fileObject.getFile(); final String path = file.getPath(); try { if (CompilerManager.MAKE_ENABLED) { byte[] fileContent = fileObject.getContent(); // the file is assumed to exist! final JavaDependencyCache dependencyCache = myCompileContext.getDependencyCache().findChild(JavaDependencyCache.class); final int newClassQName = dependencyCache.reparseClassFile(file, fileContent); final Cache newClassesCache = dependencyCache.getNewClassesCache(); final String sourceFileName = newClassesCache.getSourceFileName(newClassQName); final String qName = dependencyCache.resolve(newClassQName); String relativePathToSource = "/" + JavaMakeUtil.createRelativePathToSource(qName, sourceFileName); putName(sourceFileName, newClassQName, relativePathToSource, path); boolean haveToInstrument = myAddNotNullAssertions && hasNotNullAnnotations( newClassesCache, dependencyCache.getSymbolTable(), newClassQName, project); if (haveToInstrument) { try { ClassReader reader = new ClassReader(fileContent, 0, fileContent.length); ClassWriter writer = new PsiClassWriter(myProject, myIsJdk16); if (NotNullVerifyingInstrumenter.processClassFile(reader, writer)) { fileObject = new FileObject(file, writer.toByteArray()); } } catch (Exception ignored) { LOG.info(ignored); } } fileObject.save(); } else { final String _path = FileUtil.toSystemIndependentName(path); final int dollarIndex = _path.indexOf('$'); final int tailIndex = dollarIndex >= 0 ? dollarIndex : _path.length() - ".class".length(); final int slashIndex = _path.lastIndexOf('/'); final String sourceFileName = _path.substring(slashIndex + 1, tailIndex) + ".java"; String relativePathToSource = _path.substring(myOutputDir.length(), tailIndex) + ".java"; putName( sourceFileName, 0 /*doesn't matter here*/, relativePathToSource.startsWith("/") ? relativePathToSource : "/" + relativePathToSource, path); } } catch (ClsFormatException e) { final String m = e.getMessage(); String message = CompilerBundle.message( "error.bad.class.file.format", StringUtil.isEmpty(m) ? path : m + "\n" + path); myCompileContext.addMessage(CompilerMessageCategory.ERROR, message, null, -1, -1); LOG.info(e); } catch (IOException e) { myCompileContext.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1); LOG.info(e); } finally { myStatistics.incClassesCount(); updateStatistics(); } }