idea插件开发_psitype 集合类型

最后的话

最近很多小伙伴找我要Linux学习资料,于是我翻箱倒柜,整理了一些优质资源,涵盖视频、电子书、PPT等共享给大家!

资料预览

给大家整理的视频资料:

给大家整理的电子书资料:

如果本文对你有帮助,欢迎点赞、收藏、转发给朋友,让我有持续创作的动力!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以点击这里获取!

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

PSI

Program Structure Interface,是IntelliJ平台中负责解析文件并创建句法和语义代码模型的层,为平台的许多功能提供支持。
VFS (Virtual File System) 虚拟文件系统是IntelliJ平台的一个组件,它封装了与以虚拟文件表示的文件进行操作的大部分功能。它主要具有以下几个目的:

  1. 提供一个通用的API,无论文件实际位于何处(磁盘上、存档中、HTTP服务器上等),都可以对文件进行操作。
  2. 跟踪文件的修改,并在检测到更改时提供文件内容的旧版本和新版本。
  3. 提供将附加持久数据与VFS中的文件关联的可能性。

常用API:

  • com.intellij.psi.PsiFileFactory:文件相关操作,e.g.创建文件等。
  • com.intellij.psi.PsiElementFactory: 元素相关操作,e.g.创建java方法、注解、字段、构造方法等。
  • com.intellij.psi.PsiManager: 项目访问PSI服务的主要入口点,e.g.查找文件、查找文件夹等。
  • com.intellij.psi.PsiClass:在java类查找元素,e.g.查找方法、字段、注解。
  • com.intellij.psi.JavaPsiFacade: java元素查找等操作,e.g.查找类等。
PsiFileFactory psiFileFactory = PsiFileFactory.getInstance(project);
PsiElementFactory psiElementFactory = PsiElementFactory.getInstance(project);
PsiManager psiManager = PsiManager.getInstance(project);
ProjectRootManager projectRootManager = ProjectRootManager.getInstance(project);
JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(project);
// 查找项目中的文件
ProjectFileIndex projectFileIndex = ProjectFileIndex.getInstance(project);
// 管理VirtualFile
VirtualFileManager virtualFileManager = VirtualFileManager.getInstance();

IntelliJ平台中与代码相关的数据结构都由一个读写锁(RW lock)进行管理,必须在一个读或者写的Action中才能访问这些模型:PSI、VFS、Project root model.

WriteCommandAction.runWriteCommandAction(project, () -> {
	// 写操作
});

类型转换
  • 转VirtualFile
// 文件路径(String)转VirtualFile
VirtualFileManager virtualFileManager = VirtualFileManager.getInstance();
VirtualFile virtualFile = virtualFileManager.findFileByNioPath(Path.of(path));
// File转VirtualFile
File file= new File("./demo.java");
VritualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file);
virtualFile.refresh(false, true);
// PsiFile转VirtualFile
VirtualFile virtualFile = psiFile.getVirtualFile();
// URL转VirtualFile
VirtualFileManager.getInstance().findFileByUrl("url");
VirtualFileManager.getInstance().refreshAndFindFileByUrl("url");

  • 转PsiDirectory / PsiFile / PsiClass
// VirtualFile转PsiDirector
PsiDirectory psiDirectory = PsiManager.getInstance(project).findDirectory(virtualFile);
// VirtualFile转PsiFile
PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile);
// PsiClass转PsiFile
PsiJavaFile psiJavaFile =  (PsiJavaFile) psiClass.getContainingFile();
// PsiType转PsiClass
PsiClass psiClass = ((PsiClassType)psiType).resolve()

查找类操作
  • 查找Module / SourceRoot
// 获取所有Module
Module[] modules = ModuleManager.getInstance(project).getModules();
// 查找某个psiFile所属的Module
Module module = ModuleUtil.findModuleForFile(psiFile);
// 查找所有的源文件夹
VirtualFile[] virtualFiles = ProjectRootManager.getInstance(project).getContentSourceRoots();
// 查找某个文件所在的源文件夹
VirtualFile sourceDirectory =  ProjectRootManager.getInstance(project).getFileIndex().getSourceRootForFile(virtualFile);

  • 查找PsiFile / PsiClass / VirtualFile
// 根据类的QualifiedName查找PsiClass
PsiClass = JavaPsiFacade.getInstance(project).findClass(sourceClassStr, GlobalSearchScope.allScope(project))
// 根据类的SimpleName查找PsiClass
PsiClass[] classes = PsiShortNamesCache.getInstance(project).getClassesByName(StringUtils.capitalize(selectedText), GlobalSearchScope.allScope(project));
// 根据fileName查找VirtualFile
Collection<VirtualFile> vFiles = FilenameIndex.getVirtualFilesByName(fileName, GlobalSearchScope.projectScope(project));

PsiJavaFile / PsiClass 操作
  • 从PsiJavaFile中获取PsiClass
// 从PsiJavaFile中获取Public属性的Class
PsiClass psiClass = Arrays.stream(psiJavaFile.getClasses())
        .filter(x -> x.getModifierList() != null && x.getModifierList().hasModifierProperty(PsiModifier.PUBLIC))
        .findFirst().orElse(null);

  • 获取方法签名
// 获取所有的Method
PsiMethod[] methods = psiClass.getMethods()
// 获取方法签名
String methodSignature = Optional.ofNullable(psiMethod.getReturnType()).map(x -> x.getPresentableText() + " ").orElse("")
		+ psiMethod.getName() + "(" +
		Arrays.stream(psiMethod.getParameterList().getParameters())
				.map(x -> x.getType().getPresentableText())
				.collect(Collectors.joining(",")) + ")";

  • 新建JavaFile (需要在WriteAction中进行写操作)
// 在指定PsiDirectory目录下,新建一个java类。content换行符如果是\r\n需要转换成\n
PsiFileFactory psiFileFactory = PsiFileFactory.getInstance(psiDirectory.getProject());
PsiJavaFile psiJavaFile = (PsiJavaFile) psiFileFactory.createFileFromText(fileName, JavaFileType.INSTANCE, content);
psiDirectory.add(psiJavaFile);

PsiType操作
  • 获取类名
// 获取PsiType的全类名,包含泛型,如: Result<List<TestDTO>>
String qualifiedName = psiType.getCanonicalText();
// 获取类名简称,可能返回void
String simpleName = psiType.getPresentableText();
// 获取PsiType对应的PsiClass
PsiClass psiClass = ((PsiClassType)psiType).resolve();


  • 获取泛型
// 获取PsiType的泛型集合
List<PsiType> getGenericType(PsiType psiType) {
	if (psiType instanceof PsiClassReferenceType) {
		PsiClassReferenceType psiClassReferenceType = (PsiClassReferenceType)psiType;
		return Arrays.stream(psiClassReferenceType.getParameters())
				.filter(Objects::nonNull).collect(Collectors.toList());
	}
	return Collections.emptyList();
}
// 递归获取PsiType的所有PsiClass
List<PsiClass> getPsiClassWithGenericType(PsiType psiType) {
	if (psiType instanceof PsiClassType) {
		List<PsiClass> psiClasses = new ArrayList<>();
		psiClasses.add(((PsiClassType)psiType).resolve());
		List<PsiType> genericTypes = getGenericType(psiType);
		if (!genericTypes.isEmpty()) {
			for (PsiType genericType : genericTypes) {
				psiClasses.addAll(getPsiClassWithGenericType(genericType));
			}
		}
		return psiClasses;
	}
	return Collections.emptyList();
}

PsiElement操作(导包、加方法等)
  • 创建PsiElement
PsiElementFactory psiElementFactory = PsiElementFactory.getInstance(project);
// 创建PsiStatement
psiElementFactory.createStatementFromText(statementStr, psiMethod)
// 创建PsiImportStatement
psiElementFactory.createImportStatement(psiClass)
// 创建PsiMethod, context传PsiElement类型,可以是PsiMehtod, PsiJavaFile, PsiStatement...
psiElementFactory.createMethodFromText(methodStr, context)
// 创建PsiType并获取PsiClass
PsiType psiType = psiElementFactory.createTypeFromText(qualifiedName, null);
PsiClass psiClass = ((PsiClassType)psiType)psiType.resolve();
// 创建PsiField
PsiField psiField = psiElementFactory.createFieldFromText("@Resource private Test test;", psiClass);

  • 导入包
// 获取PsiElementFactory 
JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(project);
PsiElementFactory psiElementFactory = javaPsiFacade.getElementFactory();
// 导入指定PsiClass (import xxx;)
Set<String> importSet = Optional.ofNullable(psiImportList).map(PsiImportList::getImportStatements)
        .stream().flatMap(Arrays::stream)
        .map(PsiImportStatement::getQualifiedName).collect(Collectors.toSet());
if (!importSet.contains(sourceClass.getQualifiedName())) {
    WriteCommandAction.runWriteCommandAction(project, () -> {
        psiImportList.add(psiElementFactory.createImportStatement(psiClass));
    });
}

  • 添加方法
PsiMethod psiMethod = psiElementFactory.createMethodFromText(methodText, psiJavaFile);
WriteCommandAction.runWriteCommandAction(project, () -> {


### 最后的话

最近很多小伙伴找我要Linux学习资料,于是我翻箱倒柜,整理了一些优质资源,涵盖视频、电子书、PPT等共享给大家!

### 资料预览

给大家整理的视频资料:

![](https://img-blog.csdnimg.cn/img_convert/c4b297c6f4184af85cb748236df7be4b.png)

给大家整理的电子书资料:

  

![](https://img-blog.csdnimg.cn/img_convert/c83f61e6b1bb2c68b729a561b3230448.png)



**如果本文对你有帮助,欢迎点赞、收藏、转发给朋友,让我有持续创作的动力!**

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以点击这里获取!](https://bbs.csdn.net/topics/618635766)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

img-Q0hVcCDw-1715731313447)]



**如果本文对你有帮助,欢迎点赞、收藏、转发给朋友,让我有持续创作的动力!**

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以点击这里获取!](https://bbs.csdn.net/topics/618635766)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 26
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值