如何在IntelliJ插件中将Java代码字符串写入文件
问题:IntelliJ插件中如何将字符串写入Java文件?
背景
- 正在开发一款基于Java源文件生成单元测试类的IntelliJ插件(目前仅支持Java)
- 无Kotlin开发经验,插件代码均来自GitHub
- 已完成目标目录的定位,但卡在将字符串内容写入目标目录下的Java文件这一步
当前代码
override fun actionPerformed(e: AnActionEvent) { // UtTestsDialogProcessor.createDialogAndGenerateTests(e.project, ) val file = e.getData(CommonDataKeys.PSI_FILE) ?: return val editor = e.getRequiredData(CommonDataKeys.EDITOR) val selectedElement = getSelectedElement(editor, file) ?: return val srcModule = ModuleUtilCore.findModuleForPsiElement(selectedElement) ?: return val srcClass = getContainingClass(selectedElement) val srcDir: PsiDirectory = selectedElement.containingFile.containingDirectory val srcPackage = JavaDirectoryService.getInstance().getPackage(srcDir) ?: return val propertiesComponent = PropertiesComponent.getInstance() var testModule: Module = suggestModuleForTestsReflective(file.project, srcModule) val testRootUrls = computeTestRoots( testModule ) // final HashSet<VirtualFile> testFolders = new HashSet<VirtualFile>(); //from v14 // checkForTestRoots(srcModule, testFolders); //from v14 if (testRootUrls == null || testRootUrls.isEmpty() && computeSuitableTestRootUrls(testModule!!).isEmpty()) { testModule = srcModule } val targetDirectory: PsiDirectory? = TargetDirectoryLocator.getOrCreateDirectory(file.project, srcPackage, testModule) val testClassContent = "public class UnitTest { @Test public void test() {…}}"; //NOW I'M STUCK HERE. HOW TO WRITE THIS CONTENT TO A FILE IN targetDirectory? }
补充说明
没有遇到错误,只是不知道如何将字符串写入Java文件,无需询问日志或调试细节。
解决方案
在IntelliJ插件开发中,必须使用PSI API操作文件(不能用普通Java IO),这样才能保证IDE的索引、撤销/重做等功能正常工作。以下是两种可行的实现方式:
方式一:直接创建PsiFile写入内容
targetDirectory ?: return // 确保目标目录不为空 val fileName = "UnitTest.java" val project = file.project // 检查是否已存在同名文件(可选,根据需求处理覆盖逻辑) if (targetDirectory.findFile(fileName) != null) { return // 存在则跳过,也可添加提示用户的逻辑 } // 获取Java元素工厂,创建文件并写入内容 val elementFactory = JavaPsiFacade.getInstance(project).elementFactory val psiFile = elementFactory.createFileFromText(fileName, JavaLanguage.INSTANCE, testClassContent) targetDirectory.add(psiFile)
方式二:通过PsiClass写入内容(适合后续需修改类结构的场景)
targetDirectory ?: return val fileName = "UnitTest.java" val project = file.project if (targetDirectory.findFile(fileName) != null) { return } val elementFactory = JavaPsiFacade.getInstance(project).elementFactory // 创建空类,再替换为目标内容 val psiClass = elementFactory.createClass("UnitTest") val newClass = elementFactory.createClassFromText(testClassContent, psiClass).firstChild psiClass.replace(newClass) // 将类添加到目标目录 targetDirectory.add(psiClass)
两种方式都能实现需求,可根据后续是否需要操作类结构来选择。
内容的提问来源于stack exchange,提问作者SoT
相关产品推荐
相关产品推荐

