Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
package com.github.lens.intellij.provider;
import com.github.lens.intellij.psi.LensLightPsiClassBuilder;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.psi.PsiAnnotation;
import com.intellij.psi.PsiAnnotationMemberValue;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiField;
import com.intellij.psi.PsiLiteralExpression;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.augment.PsiAugmentProvider;
import com.intellij.psi.impl.light.LightFieldBuilder;
import com.intellij.psi.impl.light.LightMethodBuilder;
import com.intellij.psi.impl.light.LightModifierList;
import dev.khbd.lens4j.core.annotations.GenLenses;
import java.util.List;
/**
* @author Sergei_Khadanovich
*/
public class LensPsiAugmentProvider extends PsiAugmentProvider {
@Override
protected <E extends PsiElement> List<E> getAugments(PsiElement element,
Class<E> type) {
System.out.println("Element :" + element + ", type :" + type);
if (!(element instanceof PsiClass && type == PsiClass.class)) {
return List.of();
}
PsiClass psiClass = (PsiClass) element;
if (!isClassAnnotated(psiClass)) {
return List.of();
}
PsiAnnotation genLensAnnotations = psiClass.getAnnotation(GenLenses.class.getName());
PsiAnnotationMemberValue factoryNameValue = genLensAnnotations.findAttributeValue("factoryName");
PsiLiteralExpression literalExpression = (PsiLiteralExpression) factoryNameValue;
String factoryName = (String) literalExpression.getValue();
return List.of((E) createLensFactory(psiClass, factoryName));
}
private boolean isClassAnnotated(PsiClass psiClass) {
return psiClass.getAnnotation(GenLenses.class.getName()) != null;
}
private PsiClass createLensFactory(PsiClass psiClass, String factoryName) {
String newFactoryName = "".equals(factoryName) ? psiClass.getName() + "Lenses" : factoryName;
LensLightPsiClassBuilder classBuilder = new LensLightPsiClassBuilder(psiClass, newFactoryName);
classBuilder.setScope(psiClass.getScope());
LightModifierList classModifiers = classBuilder.getModifierList();
// may be should have the same modifier list as original class
classModifiers.addModifier(PsiModifier.PUBLIC);
classModifiers.addModifier(PsiModifier.FINAL);
classBuilder.addMethod(createStubConstructor(classBuilder));
classBuilder.addField(createStubField(psiClass));
return classBuilder;
}
private PsiMethod createStubConstructor(PsiClass psiClass) {
LightMethodBuilder constructor = new LightMethodBuilder(psiClass, JavaLanguage.INSTANCE);
constructor.addModifiers(PsiModifier.PRIVATE);
constructor.setConstructor(true);
return constructor;
}
private PsiField createStubField(PsiClass psiClass) {
String fieldName = psiClass.getName().toUpperCase();
LightFieldBuilder builder = new LightFieldBuilder(fieldName, "java.lang.String", psiClass);
builder.setModifiers(PsiModifier.PUBLIC, PsiModifier.STATIC, PsiModifier.FINAL);
return builder;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment