Author: Xiao Fu Ge
Blog: https://bugstack.cn
Precipitate, share, grow, so that you and others can gain something! 😄
I. Introduction
gives you a chance, you are not good
Over the years I have been engaged in programming development, I seem to have discovered that most of the things I don't want to do in research and development have achieved others. like a troublesome deployment service. With Docker and simple CRUD does not want to develop. With low code and the method code is cumbersome to monitor, and there is a non-invasive full-link monitoring .
And these things you are doing originally, because you have no ideas, no innovation, no thinking, or inability, so you have always been moving bricks, laying bricks, and laying bricks, back and forth, back and forth. Keyboard typing is getting faster and faster, and the code is getting worse and worse. The salary is not up, and the hair is getting less and less.
For code farmers who want to take the technical route, don’t just stop at the logical development of business functions. Only when you have a common and condensed logical thinking, will you gradually think about how to make a repetitive thing into a universal service Or components, and the implementation of these things requires you not only to write code, but also to think and index some of the technologies you need, and to supplement this part of the skills in a self-learning way.
2. Demand Purpose
Do you want to write get、set
between objects? Annoying, annoying, especially in the DDD four-layer architecture, there are multiple anti-fouling treatments, one vo2dto for a while, a vo2do for a while, and a do2po for a while. Although there are many tool operations, you still have to write it. .
what to do? Don’t panic, this is an opportunity. Let’s make a plug-in to get it done so that it can automatically generate get、set
code for me. Under the processing of IDEA Plugin, select the anchor point that needs to generate the object code, copy and convert the object, and weave it automatically. Enter the code, 1s to get it!
3. Case development
1. Engineering structure
guide-idea-plugin-vo2dto
├── .gradle
└── src
├── main
│ └── java
│ └── cn.bugstack.guide.idea.plugin
│ ├── action
│ │ └── Vo2DtoGenerateAction.java
│ ├── application
│ │ └── IGenerateVo2Dto.java
│ ├── domain
│ │ ├── model
│ │ │ ├── GenerateContext.java
│ │ │ ├── GetObjConfigDO.java
│ │ │ └── SetObjConfigDO.java
│ │ └── service
│ │ ├── impl
│ │ │ └── GenerateVo2DtoImpl.java
│ │ └── AbstractGenerateVo2Dto.java
│ └── infrastructure
│ └── Utils.java
├── resources
│ └── META-INF
│ └── plugin.xml
├── build.gradle
└── gradle.properties
source code acquisition : #public number: bugstack wormhole stack reply:
idea
can download all IDEA plug-in development source code
In this IDEA plug-in project, it is mainly divided into 4 areas:
- action: Provides the menu bar form. In the plug-in, we configure this menu bar
Generate
, which is where you usually generate get, set, and constructor methods. - application: The application layer defines the interface, where a method interface for generating code and weaving into the anchor point is defined.
- domian: The domain layer specializes in code generation and weaving actions. This layer obtains the anchor point position of the code, copies the clipboard information, the application context, the analysis of the get and set in the class, and finally weaves the generated code Operations after reaching the anchor point.
- Infrastructure: Provides tool classes at the base layer for operations such as obtaining clipboard information and determining the position of anchor points.
2. Weaving code interface
cn.bugstack.guide.idea.plugin.application.IGenerateVo2Dto
public interface IGenerateVo2Dto {
void doGenerate(Project project, DataContext dataContext);
}
- Defining the interface is actually a very important step, because this step defines the generated standard, and all generation actions must be initiated from this interface. learning source code is the same, you have to find a core entry point, in order to better start learning
3. Define the template method
Because the operation of generating code and woven into the anchor point position is actually a set of process operations as a whole, because it is required in this process; obtaining context information (that is, engineering object), extracting the set method set for the class of the current anchor point position, Then Ctrl+C
clipboard to extract the get method set. The fourth step is to combine the set and get and weave the code into the anchor point. The overall process is as follows:
- Then after using the template method, it is very easy to split the pieces of code written in a class according to responsibilities.
- At the same time, because of the definition of the template, the entire set of standard processes is defined. It is easier to execute the code under the process specification, and then add the logical iteration function later.
4. Code weaving into anchors
Regarding the method we define in the template class before the code is weaved into the anchor point, the interface needs to be implemented for processing, and the key points include:
- Encapsulate the GenerateContext object context information through
CommonDataKeys.EDITOR.getData(dataContext)
andCommonDataKeys.PSI_ELEMENT.getData(dataContext)
, that is, some classes, anchor positions, and document editing objects. - Obtain the Class information corresponding to the cursor position through
psiClass.getMethods()
read the object method through 061ba96ad105bc, filter out the set method, and encapsulate it into the collection. - Get the clipboard information through
Toolkit.getDefaultToolkit().getSystemClipboard()
, that is, when you createx.set(y.get)
for the object at the anchor point, copy the Y y object and start extracting the get method, which is also encapsulated in the collection. - Then the final part is the assembly and weaving action of the code. Our code for this part is as follows;
cn.bugstack.guide.idea.plugin.domain.service.impl.GenerateVo2DtoImpl
@Override
protected void weavingSetGetCode(GenerateContext generateContext, SetObjConfigDO setObjConfigDO, GetObjConfigDO getObjConfigDO) {
Application application = ApplicationManager.getApplication();
// 获取空格位置长度
int distance = Utils.getWordStartOffset(generateContext.getEditorText(), generateContext.getOffset()) - generateContext.getStartOffset();
application.runWriteAction(() -> {
StringBuilder blankSpace = new StringBuilder();
for (int i = 0; i < distance; i++) {
blankSpace.append(" ");
}
int lineNumberCurrent = generateContext.getDocument().getLineNumber(generateContext.getOffset()) + 1;
List<String> setMtdList = setObjConfigDO.getParamList();
for (String param : setMtdList) {
int lineStartOffset = generateContext.getDocument().getLineStartOffset(lineNumberCurrent++);
new WriteCommandAction(generateContext.getProject()) {
@Override
protected void run(@NotNull Result result) throws Throwable {
generateContext.getDocument().insertString(lineStartOffset, blankSpace + setObjConfigDO.getClazzParamName() + "." + setObjConfigDO.getParamMtdMap().get(param) + "(" + (null == getObjConfigDO.getParamMtdMap().get(param) ? "" : getObjConfigDO.getClazzParam() + "." + getObjConfigDO.getParamMtdMap().get(param) + "()") + ");\n");
generateContext.getEditor().getCaretModel().moveToOffset(lineStartOffset + 2);
generateContext.getEditor().getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
}
}.execute();
}
});
}
- Weaving process operation code, the main method of collection is set to traverse, the corresponding
x.set(y.get)
bydocument.insertString
to a specific location and code. - In the end, all the generated code methods are woven, and the whole process of
x.set(y.get)
5. Configuration menu entry
plugin.xml
<actions>
<!-- Add your actions here -->
<action id="Vo2DtoGenerateAction" class="cn.bugstack.guide.idea.plugin.action.Vo2DtoGenerateAction"
text="Vo2Dto - 小傅哥" description="Vo2Dto generate util" icon="/icons/logo.png">
<add-to-group group-id="GenerateGroup" anchor="last"/>
<keyboard-shortcut keymap="$default" first-keystroke="ctrl shift K"/>
</action>
</actions>
- This time we
x.set(y.get)
, which allows us to operate more conveniently.
Four, test verification
Click Plugin
start the IDEA plug-in, and then there are two steps of ;
- Copy the object you need to be converted, because after copying, the clipboard information can be obtained by the plug-in, and the get method set can also be extracted.
- Define the mouse to the object that needs to be converted to the setting value, then right-click the mouse and select
Generate
->Vo2Dto-Xiao Fu Ge
1. Copy objects
2. Generate objects
3. Final effect
- In the end, you can see that all your objects have been converted, and the code has been automatically generated. Is it very fragrant?
- If you directly use the shortcut key
Ctrl + Shift + K
can also be automatically generated.
Five, extended interface
Get the currently edited file, PsiClass, PsiField, etc. can be obtained through PsiFile | PsiFile psiFile = e.getData(LangDataKeys.PSI_FILE); |
Get the current project object | Project project = e.getProject(); |
Get data context | DataContext dataContext = e.getDataContext(); |
After obtaining the data context, all information about the File can be obtained through the CommonDataKeys object | Editor editor = CommonDataKeys.EDITOR.getData(dataContext);<br />PsiFile psiFile = CommonDataKeys.PSI_FILE.getData(dataContext);<br />VirtualFile virtualFile = CommonDataKeys.VIRTUAL_FILE.getData(dataContext); |
There are Project domain, Moudule domain, File domain, etc. in GlobalSearchScope | PsiFile[] psiFiles = FilenameIndex.getFilesByName(project, name, GlobalSearchScope); |
Similar to the Find Usages operation in the IDE | Query<PsiReference> search = ReferencesSearch.search(PsiElement); |
Rename | RenameRefactoring newName = RefactoringFactory.getInstance(Project).createRename(PsiElement, "newName"); |
Search all subclasses of a class, there are many overloaded methods, and the specifics will not be listed one by one | Query<PsiClass> search = ClassInheritorsSearch.search(PsiClass); |
Query PsiClass according to the fully qualified name of the class, the following method is to query the Project domain | PsiClass psiClass = JavaPsiFacade.getInstance(project).findClass(classQualifiedName, GlobalSearchScope.projectScope(project)); |
Get the Package where the Java class is located | PsiPackage psiPackage = JavaPsiFacade.getInstance(Project).findPackage(classQualifiedName); |
Find methods that are overridden by a specific method | Query<PsiMethod> search = OverridingMethodsSearch.search(PsiMethod); |
Six, summary
- In this chapter, we have involved a lot of operations on the classes and methods of engineering objects. The practice of these contents is also very suitable for you to use in other scenarios, such as generating some automated API operations for the engineering interface.
x.set(y.get)
for the object, I was also thinking about how to substitute the conversion object into the code logic of the plug-in more reasonably. I might think of pop-up configuration or code scanning to the previous line, but this method is not after all Comfortable, considering the habit of actually coding by ourselves, in fact, when we do this step, copying is the first step. In order to have a better experience, we chose to use copying to deal with this connection problem.- The IDEA Plugin development of this series is designed and implemented in accordance with the idea of DDD engineering structure. Although the overall content does not seem complicated, it is hoped that the precipitation of these frameworks can pave the way for DDD to be implemented, so that more engineering developers can adapt to the DDD structure.
Seven, series recommendation
- program design: Based on IDEA plug-in development and bytecode instrumentation technology, automatic analysis of R&D delivery quality is realized
- , the middle stage that had just gone hot, turned around and dismantled it, and a large wave of companies couldn't put it down or pick it up!
- "IntelliJ IDEA Plug-in Development" Section 4: Expanding the steps of creating a project wizard, developing DDD scaffolding
- HashMap core knowledge, disturbance function, load factor, expansion linked list split, deep learning
- p3c plug-in, how do you check out the code of your shit mountain?
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。