Skip to content

Commit

Permalink
initial work on val support
Browse files Browse the repository at this point in the history
  • Loading branch information
Michail Plushnikov committed Feb 4, 2015
1 parent 4c9ab00 commit 91edee4
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 34 deletions.
Expand Up @@ -2,6 +2,7 @@


import com.intellij.codeInsight.daemon.impl.analysis.JavaGenericsUtil; import com.intellij.codeInsight.daemon.impl.analysis.JavaGenericsUtil;
import com.intellij.psi.PsiAnnotation; import com.intellij.psi.PsiAnnotation;
import com.intellij.psi.PsiArrayInitializerExpression;
import com.intellij.psi.PsiClass; import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiDiamondType; import com.intellij.psi.PsiDiamondType;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
Expand All @@ -14,7 +15,7 @@
import com.intellij.psi.PsiReferenceParameterList; import com.intellij.psi.PsiReferenceParameterList;
import com.intellij.psi.PsiType; import com.intellij.psi.PsiType;
import com.intellij.psi.PsiTypeElement; import com.intellij.psi.PsiTypeElement;
import com.intellij.psi.PsiVariable; import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.TypeConversionUtil; import com.intellij.psi.util.TypeConversionUtil;
import de.plushnikov.intellij.plugin.problem.LombokProblem; import de.plushnikov.intellij.plugin.problem.LombokProblem;
import lombok.val; import lombok.val;
Expand All @@ -23,12 +24,21 @@


import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet;
import java.util.Set;


public class ValProcessor extends AbstractProcessor { public class ValProcessor extends AbstractProcessor {


private static final String LOMBOK_VAL_FQN = "lombok.val"; private static final String LOMBOK_VAL_FQN = "lombok.val";
private static final String LOMBOK_VAL_SHORT_NAME = "val"; private static final String LOMBOK_VAL_SHORT_NAME = "val";


private final static ThreadLocal<Set<PsiExpression>> recursionBreaker = new ThreadLocal<Set<PsiExpression>>() {
@Override
protected Set<PsiExpression> initialValue() {
return new HashSet<PsiExpression>();
}
};

public ValProcessor() { public ValProcessor() {
super(val.class, PsiElement.class); super(val.class, PsiElement.class);
} }
Expand All @@ -48,40 +58,77 @@ public Collection<LombokProblem> verifyAnnotation(@NotNull PsiAnnotation psiAnno
@Nullable @Nullable
public PsiType inferType(PsiTypeElement typeElement) { public PsiType inferType(PsiTypeElement typeElement) {
final PsiElement parent = typeElement.getParent(); final PsiElement parent = typeElement.getParent();
if (parent instanceof PsiLocalVariable && ((PsiLocalVariable) parent).getInitializer() != null || if (!(parent instanceof PsiLocalVariable || parent instanceof PsiParameter)) {
parent instanceof PsiParameter && ((PsiParameter) parent).getDeclarationScope() instanceof PsiForeachStatement) { return null;
final String text = typeElement.getText(); }
if (LOMBOK_VAL_SHORT_NAME.equals(text) || LOMBOK_VAL_FQN.equals(text)) {
final PsiJavaCodeReferenceElement referenceElement = typeElement.getInnermostComponentReferenceElement(); final String typeElementText = typeElement.getText();
if (referenceElement != null) { if (!(LOMBOK_VAL_SHORT_NAME.equals(typeElementText) || LOMBOK_VAL_FQN.equals(typeElementText))) {
final PsiElement resolve = referenceElement.resolve(); return null;
if (resolve instanceof PsiClass) { }
if (parent instanceof PsiLocalVariable) {
final PsiExpression initializer = ((PsiLocalVariable) parent).getInitializer(); PsiType psiType;
final PsiType initializerType = initializer.getType(); if (parent instanceof PsiLocalVariable) {
if (initializer instanceof PsiNewExpression) { psiType = processLocalVariableInitializer(((PsiLocalVariable) parent).getInitializer());
final PsiJavaCodeReferenceElement reference = ((PsiNewExpression) initializer).getClassOrAnonymousClassReference(); } else {
if (reference != null) { psiType = processParameterDeclaration(((PsiParameter) parent).getDeclarationScope());
final PsiReferenceParameterList parameterList = reference.getParameterList(); }
if (parameterList != null) {
final PsiTypeElement[] elements = parameterList.getTypeParameterElements(); if (null == psiType) {
if (elements.length == 1 && elements[0].getType() instanceof PsiDiamondType) { psiType = PsiType.getJavaLangObject(typeElement.getManager(), GlobalSearchScope.projectScope(typeElement.getProject()));
return TypeConversionUtil.erasure(initializerType); }
} return psiType;
} }
}
//TODO ERROR: 'val' is not allowed in old-style for loops
public PsiType processLocalVariableInitializer(PsiExpression initializer) {
PsiType result = null;
if (initializer instanceof PsiArrayInitializerExpression) {
// TODO add ERROR : 'val' is not compatible with array initializer expressions. Use the full form (new int[] { ... } instead of just { ... })
// PsiArrayInitializerExpression psiArrayInitializerExpression = (PsiArrayInitializerExpression) initializer;
// final PsiExpression[] psiArrayInitializer = psiArrayInitializerExpression.getInitializers();
// if (psiArrayInitializer.length > 0) {
// final PsiType psiArrayElementType = psiArrayInitializer[0].getType();
// if (null != psiArrayElementType) {
// result = new PsiArrayType(psiArrayElementType);
// }
// }
} else if (null != initializer) {
if (!recursionBreaker.get().contains(initializer)) {

recursionBreaker.get().add(initializer);
try {
result = initializer.getType();
} finally {
recursionBreaker.get().remove(initializer);
}

if (initializer instanceof PsiNewExpression) {
final PsiJavaCodeReferenceElement reference = ((PsiNewExpression) initializer).getClassOrAnonymousClassReference();
if (reference != null) {
final PsiReferenceParameterList parameterList = reference.getParameterList();
if (parameterList != null) {
final PsiTypeElement[] elements = parameterList.getTypeParameterElements();
if (elements.length == 1 && elements[0].getType() instanceof PsiDiamondType) {
result = TypeConversionUtil.erasure(result);
} }
return initializerType;
}
final PsiForeachStatement foreachStatement = (PsiForeachStatement) ((PsiParameter) parent).getDeclarationScope();
final PsiExpression iteratedValue = foreachStatement.getIteratedValue();
if (iteratedValue != null) {
return JavaGenericsUtil.getCollectionItemType(iteratedValue);
} }
} }
} }
} }
} }
return null; return result;
}

public PsiType processParameterDeclaration(PsiElement parentDeclarationScope) {
PsiType result = null;
if (parentDeclarationScope instanceof PsiForeachStatement) {
final PsiForeachStatement foreachStatement = (PsiForeachStatement) parentDeclarationScope;
final PsiExpression iteratedValue = foreachStatement.getIteratedValue();
if (iteratedValue != null) {
result = JavaGenericsUtil.getCollectionItemType(iteratedValue);
}
}
return result;
} }
} }
Expand Up @@ -7,14 +7,18 @@
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiField; import com.intellij.psi.PsiField;
import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiType;
import com.intellij.psi.PsiTypeElement;
import com.intellij.psi.augment.PsiAugmentProvider; import com.intellij.psi.augment.PsiAugmentProvider;
import de.plushnikov.intellij.plugin.extension.LombokProcessorExtensionPoint; import de.plushnikov.intellij.plugin.extension.LombokProcessorExtensionPoint;
import de.plushnikov.intellij.plugin.extension.UserMapKeys; import de.plushnikov.intellij.plugin.extension.UserMapKeys;
import de.plushnikov.intellij.plugin.processor.Processor; import de.plushnikov.intellij.plugin.processor.Processor;
import de.plushnikov.intellij.plugin.processor.ValProcessor;
import de.plushnikov.intellij.plugin.settings.ProjectSettings; import de.plushnikov.intellij.plugin.settings.ProjectSettings;
import de.plushnikov.intellij.plugin.util.PsiAnnotationUtil; import de.plushnikov.intellij.plugin.util.PsiAnnotationUtil;
import de.plushnikov.intellij.plugin.util.PsiClassUtil; import de.plushnikov.intellij.plugin.util.PsiClassUtil;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;


import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.util.ArrayList; import java.util.ArrayList;
Expand Down Expand Up @@ -95,10 +99,10 @@ public <Psi extends PsiElement> List<Psi> getAugments(@NotNull PsiElement elemen
} }
} }


// @Nullable @Nullable
// protected PsiType inferType(PsiTypeElement typeElement) { protected PsiType inferType(PsiTypeElement typeElement) {
// return new ValProcessor().inferType(typeElement); return new ValProcessor().inferType(typeElement);
// } }


private void initRegisteredAnnotations() { private void initRegisteredAnnotations() {
if (null == registeredAnnotationNames) { if (null == registeredAnnotationNames) {
Expand Down

0 comments on commit 91edee4

Please sign in to comment.