Skip to content
This repository has been archived by the owner on Nov 3, 2024. It is now read-only.

Commit

Permalink
Fix some of stackoverflow exceptions
Browse files Browse the repository at this point in the history
  • Loading branch information
Michail Plushnikov committed Nov 2, 2013
1 parent facd39f commit 9f15601
Show file tree
Hide file tree
Showing 15 changed files with 115 additions and 100 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.jetbrains.annotations.NotNull;

import java.util.Collection;
import java.util.concurrent.TimeUnit;

public class UserMapKeys {

Expand All @@ -18,7 +19,7 @@ public class UserMapKeys {
public static final Key<Boolean> READ_KEY = Key.create(LOMBOK_HAS_IMPLICIT_READ_PROPERTY);
public static final Key<Boolean> WRITE_KEY = Key.create(LOMBOK_HAS_IMPLICIT_WRITE_PROPERTY);

public static final Key<Boolean> HAS_LOMBOK_KEY = Key.create(LOMBOK_IS_PRESENT_PROPERTY);
public static final Key<LombokPresentData> HAS_LOMBOK_KEY = Key.create(LOMBOK_IS_PRESENT_PROPERTY);

public static void removeAllUsagesFrom(@NotNull UserDataHolder element) {
if (null != element.getUserData(READ_KEY)) {
Expand All @@ -44,27 +45,30 @@ public static void addWriteUsageFor(@NotNull UserDataHolder element) {
element.putUserData(WRITE_KEY, Boolean.TRUE);
}

public static void addLombokPresentFor(@NotNull UserDataHolder element) {
element.putUserData(HAS_LOMBOK_KEY, Boolean.TRUE);
public static void addReadUsageFor(@NotNull Collection<? extends UserDataHolder> elements) {
for (UserDataHolder element : elements) {
addReadUsageFor(element);
}
}

public static void addLombokNotPresentFor(@NotNull UserDataHolder element) {
element.putUserData(HAS_LOMBOK_KEY, Boolean.FALSE);
}
private static final long PRESENT_TIME = TimeUnit.SECONDS.toNanos(1);

private static class LombokPresentData {
private final boolean present;
private final long nanoTime;

public static boolean containLombok(@NotNull UserDataHolder element) {
Boolean userData = element.getUserData(HAS_LOMBOK_KEY);
return Boolean.TRUE.equals(userData);
private LombokPresentData(boolean present) {
this.present = present;
this.nanoTime = System.nanoTime();
}
}

public static boolean mayContainLombok(@NotNull UserDataHolder element) {
Boolean userData = element.getUserData(HAS_LOMBOK_KEY);
return null==userData||Boolean.TRUE.equals(userData);
public static void updateLombokPresent(@NotNull UserDataHolder element, boolean isPresent) {
element.putUserData(HAS_LOMBOK_KEY, new LombokPresentData(isPresent));
}

public static void addReadUsageFor(@NotNull Collection<? extends UserDataHolder> elements) {
for (UserDataHolder element : elements) {
addReadUsageFor(element);
}
public static boolean isLombokPossiblePresent(@NotNull UserDataHolder element) {
LombokPresentData userData = element.getUserData(HAS_LOMBOK_KEY);
return null == userData || (userData.nanoTime < System.nanoTime() - PRESENT_TIME) || userData.present;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ public abstract class AbstractProcessor implements Processor {
/**
* Kind of output elements this processor supports
*/
private final Class<?> supportedClass;
private final Class<? extends PsiElement> supportedClass;

/**
* Constructor for all Lombok-Processors
*
* @param supportedAnnotationClass annotation this processor supports
* @param supportedClass kind of output elements this processor supports
*/
protected AbstractProcessor(@NotNull Class<? extends Annotation> supportedAnnotationClass, @NotNull Class<?> supportedClass) {
protected AbstractProcessor(@NotNull Class<? extends Annotation> supportedAnnotationClass, @NotNull Class<? extends PsiElement> supportedClass) {
this.supportedAnnotationClass = supportedAnnotationClass;
this.supportedAnnotation = supportedAnnotationClass.getName();
this.supportedClass = supportedClass;
Expand All @@ -54,6 +54,12 @@ public final Class<? extends Annotation> getSupportedAnnotationClass() {
return supportedAnnotationClass;
}

@NotNull
@Override
public final Class<? extends PsiElement> getSupportedClass() {
return supportedClass;
}

public boolean acceptAnnotation(@NotNull PsiAnnotation psiAnnotation, @NotNull Class<? extends PsiElement> type) {
final String annotationName = StringUtil.notNullize(psiAnnotation.getQualifiedName()).trim();
return supportedAnnotation.equals(annotationName) && canProduce(type);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ public interface Processor {

Class<? extends Annotation> getSupportedAnnotationClass();

Class<? extends PsiElement> getSupportedClass();

Collection<LombokProblem> verifyAnnotation(@NotNull PsiAnnotation psiAnnotation);


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
*/
public abstract class AbstractClassProcessor extends AbstractProcessor implements ClassProcessor {

protected AbstractClassProcessor(@NotNull Class<? extends Annotation> supportedAnnotationClass, @NotNull Class<?> supportedClass) {
protected AbstractClassProcessor(@NotNull Class<? extends Annotation> supportedAnnotationClass, @NotNull Class<? extends PsiElement> supportedClass) {
super(supportedAnnotationClass, supportedClass);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public BuilderInnerClassProcessor() {
super(Builder.class, PsiClass.class);
}

protected BuilderInnerClassProcessor(@NotNull Class<? extends Annotation> supportedAnnotationClass, @NotNull Class supportedClass) {
protected BuilderInnerClassProcessor(@NotNull Class<? extends Annotation> supportedAnnotationClass, @NotNull Class<? extends PsiElement> supportedClass) {
super(supportedAnnotationClass, supportedClass);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,17 @@ protected void processIntern(@NotNull PsiClass psiClass, @NotNull PsiAnnotation
String innerClassName = BuilderUtil.createBuilderClassName(psiAnnotation, psiClass);
PsiClass innerClassByName = PsiClassUtil.getInnerClassByName(psiClass, innerClassName);
assert innerClassByName != null; // BuilderInnerClassProcessor should run first

final String builderMethodName = BuilderUtil.createBuilderMethodName(psiAnnotation);
if (!PsiMethodUtil.hasMethodByName(PsiClassUtil.collectClassMethodsIntern(psiClass), builderMethodName)) {
LombokLightMethodBuilder method = new LombokLightMethodBuilder(psiClass.getManager(), builderMethodName)
.withMethodReturnType(PsiClassUtil.getTypeWithGenerics(innerClassByName))
.withContainingClass(psiClass)
.withNavigationElement(psiAnnotation);
method.withModifier(PsiModifier.STATIC);
method.withModifier(PsiModifier.PUBLIC);
target.add(method);
if (null != innerClassByName) {
final String builderMethodName = BuilderUtil.createBuilderMethodName(psiAnnotation);
if (!PsiMethodUtil.hasMethodByName(PsiClassUtil.collectClassMethodsIntern(psiClass), builderMethodName)) {
LombokLightMethodBuilder method = new LombokLightMethodBuilder(psiClass.getManager(), builderMethodName)
.withMethodReturnType(PsiClassUtil.getTypeWithGenerics(innerClassByName))
.withContainingClass(psiClass)
.withNavigationElement(psiAnnotation);
method.withModifier(PsiModifier.STATIC);
method.withModifier(PsiModifier.PUBLIC);
target.add(method);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public SetterProcessor() {
this(Setter.class, PsiMethod.class);
}

protected SetterProcessor(@NotNull Class<? extends Annotation> supportedAnnotationClass, @NotNull Class<?> supportedClass) {
protected SetterProcessor(@NotNull Class<? extends Annotation> supportedAnnotationClass, @NotNull Class<? extends PsiElement> supportedClass) {
super(supportedAnnotationClass, supportedClass);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
*/
public abstract class AbstractFieldProcessor extends AbstractProcessor implements FieldProcessor {

protected AbstractFieldProcessor(@NotNull Class<? extends Annotation> supportedAnnotationClass, @NotNull Class<?> supportedClass) {
protected AbstractFieldProcessor(@NotNull Class<? extends Annotation> supportedAnnotationClass, @NotNull Class<? extends PsiElement> supportedClass) {
super(supportedAnnotationClass, supportedClass);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public GetterFieldProcessor() {
super(Getter.class, PsiMethod.class);
}

protected GetterFieldProcessor(@NotNull Class<? extends Annotation> supportedAnnotationClass, @NotNull Class<?> supportedClass) {
protected GetterFieldProcessor(@NotNull Class<? extends Annotation> supportedAnnotationClass, @NotNull Class<? extends PsiElement> supportedClass) {
super(supportedAnnotationClass, supportedClass);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public SetterFieldProcessor() {
this(Setter.class, PsiMethod.class);
}

protected SetterFieldProcessor(@NotNull Class<? extends Annotation> supportedAnnotationClass, @NotNull Class<?> supportedClass) {
protected SetterFieldProcessor(@NotNull Class<? extends Annotation> supportedAnnotationClass, @NotNull Class<? extends PsiElement> supportedClass) {
super(supportedAnnotationClass, supportedClass);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
*/
public abstract class AbstractMethodProcessor extends AbstractProcessor implements MethodProcessor {

protected AbstractMethodProcessor(@NotNull Class<? extends Annotation> supportedAnnotationClass, @NotNull Class<?> supportedClass) {
protected AbstractMethodProcessor(@NotNull Class<? extends Annotation> supportedAnnotationClass, @NotNull Class<? extends PsiElement> supportedClass) {
super(supportedAnnotationClass, supportedClass);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public BuilderMethodInnerClassProcessor() {
super(Builder.class, PsiClass.class);
}

protected BuilderMethodInnerClassProcessor(@NotNull Class<? extends Annotation> supportedAnnotationClass, @NotNull Class supportedClass) {
protected BuilderMethodInnerClassProcessor(@NotNull Class<? extends Annotation> supportedAnnotationClass, @NotNull Class<? extends PsiElement> supportedClass) {
super(supportedAnnotationClass, supportedClass);
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiField;
Expand All @@ -15,10 +16,13 @@
import de.plushnikov.intellij.plugin.util.PsiClassUtil;
import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

/**
* Provides support for lombok generated elements
Expand Down Expand Up @@ -51,42 +55,73 @@ public <Psi extends PsiElement> List<Psi> getAugments(@NotNull PsiElement elemen
return emptyResult;
}

final PsiClass psiClass = (PsiClass) element;
if (log.isDebugEnabled()) {
log.debug(String.format("Process class %s with LombokAugmentProvider for type %s", psiClass.getQualifiedName(), type.getName()));
boolean isLombokPresent = UserMapKeys.isLombokPossiblePresent(element);
if (!isLombokPresent) {
if (log.isDebugEnabled()) {
log.debug(String.format("Skipped call for type: %s class: %s", type, ((PsiClass) element).getQualifiedName()));
}
return Collections.emptyList();
}

final PsiFile containingFile = psiClass.getContainingFile();
if (UserMapKeys.mayContainLombok(containingFile)) {
if (!UserMapKeys.containLombok(containingFile)) {
if (containingFile.getText().contains("lombok.")) {
UserMapKeys.addLombokPresentFor(containingFile);
} else {
UserMapKeys.addLombokNotPresentFor(containingFile);
}
return process(type, project, (PsiClass) element);
}

private <Psi extends PsiElement> List<Psi> process(Class<Psi> type, Project project, PsiClass psiClass) {
boolean isLombokPossiblePresent = true;
try {
isLombokPossiblePresent = verifyLombokPresent(psiClass);
} catch (IOException ex) {
log.warn("Exception durcing check for Lombok", ex);
}
UserMapKeys.updateLombokPresent(psiClass, isLombokPossiblePresent);

if (isLombokPossiblePresent) {
if (log.isDebugEnabled()) {
log.debug(String.format("Process call for type: %s class: %s", type, psiClass.getQualifiedName()));
}

if (UserMapKeys.containLombok(containingFile)) {
cleanAttributeUsage(psiClass);
cleanAttributeUsage(psiClass);

final List<Psi> result = new ArrayList<Psi>();
for (Processor processor : LombokProcessorExtensionPoint.EP_NAME.getExtensions()) {
if (processor.canProduce(type) && processor.isEnabled(project)) {
result.addAll((Collection<Psi>) processor.process(psiClass));
}
}
return result;
}else{
if (log.isDebugEnabled()) {
log.debug(String.format("Skipped file %s", containingFile.getName()));
final List<Psi> result = new ArrayList<Psi>();
for (Processor processor : LombokProcessorExtensionPoint.EP_NAME.getExtensions()) {
if (processor.canProduce(type) && processor.isEnabled(project)) {
result.addAll((Collection<Psi>) processor.process(psiClass));
}
}
return result;
} else {
if (log.isDebugEnabled()) {
log.debug(String.format("Skipped file %s quickly", containingFile.getName()));
log.debug(String.format("Skipped call for type: %s class: %s", type, psiClass.getQualifiedName()));
}
}
return Collections.emptyList();
}

private boolean verifyLombokPresent(PsiClass psiClass) throws IOException {
boolean isLombokPossiblePresent = true;
final PsiFile containingFile = psiClass.getContainingFile();
if (null != containingFile) {
VirtualFile virtualFile = containingFile.getVirtualFile();
if (null != virtualFile) {
InputStream inputStream = null;
try {
inputStream = virtualFile.getInputStream();
Scanner scanner = new Scanner(inputStream);
while (scanner.hasNextLine()) {
final String lineFromFile = scanner.nextLine();
isLombokPossiblePresent = lineFromFile.contains("lombok.");
if (isLombokPossiblePresent) {
break;
}
}
} finally {
if (null != inputStream) {
inputStream.close();
}
}
}
}
return emptyResult;
return isLombokPossiblePresent;
}

protected void cleanAttributeUsage(PsiClass psiClass) {
Expand Down
9 changes: 6 additions & 3 deletions lombok-plugin/src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<name>Lombok Plugin</name>
<vendor url="http://code.google.com/p/lombok-intellij-plugin" email="[email protected]">Michail Plushnikov
</vendor>
<version>0.7.1</version>
<version>0.7.2</version>
<idea-version since-build="123.72"/>

<description><![CDATA[
Expand All @@ -28,8 +28,6 @@
</extensionPoints>

<extensions defaultExtensionNs="com.intellij">
<annotator language="JAVA" implementationClass="de.plushnikov.intellij.plugin.provider.LombokAnnotator"/>

<lang.psiAugmentProvider implementation="de.plushnikov.intellij.plugin.provider.LombokAugmentProvider"/>
<implicitUsageProvider implementation="de.plushnikov.intellij.plugin.provider.LombokImplicitUsageProvider"/>
<inspectionToolProvider implementation="de.plushnikov.intellij.plugin.provider.LombokInspectionProvider"/>
Expand Down Expand Up @@ -83,6 +81,11 @@

<change-notes><![CDATA[
<ul>
<li>0.7.2
<ol>
<li>Fix multiple stackoverflow exceptions</li>
</ol>
</li>
<li>0.7.1
<ol>
<li>Some performance optimizations</li>
Expand Down

0 comments on commit 9f15601

Please sign in to comment.