[groovy] use Computable instead of NotNullLazyValue in GroovyMethodResult.

- NotNullCachedComputableWrapper: clean Computable after obtaining result value.
This commit is contained in:
Daniil Ovchinnikov
2015-12-10 18:48:58 +03:00
parent f53809455f
commit d7c399306f
3 changed files with 82 additions and 17 deletions
@@ -15,7 +15,7 @@
*/
package org.jetbrains.plugins.groovy.lang.psi.impl;
import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.openapi.util.NotNullComputable;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiSubstitutor;
@@ -25,22 +25,28 @@ import org.jetbrains.plugins.groovy.lang.psi.api.SpreadState;
public class GroovyMethodResult extends GroovyResolveResultImpl {
private final NotNullLazyValue<PsiSubstitutor> mySubstitutorComputer;
private final @NotNull NotNullComputable<PsiSubstitutor> mySubstitutorComputer;
public GroovyMethodResult(@NotNull PsiMethod method,
@Nullable PsiElement resolveContext,
@Nullable SpreadState spreadState,
@NotNull PsiSubstitutor substitutor,
@NotNull final PsiSubstitutor substitutor,
boolean isAccessible, boolean staticsOK) {
super(method, resolveContext, spreadState, substitutor, isAccessible, staticsOK, true, true);
mySubstitutorComputer = NotNullLazyValue.createConstantValue(substitutor);
mySubstitutorComputer = new NotNullComputable<PsiSubstitutor>() {
@NotNull
@Override
public PsiSubstitutor compute() {
return substitutor;
}
};
}
public GroovyMethodResult(@NotNull PsiMethod element,
@Nullable PsiElement resolveContext,
@Nullable SpreadState spreadState,
@NotNull PsiSubstitutor partialSubstitutor,
@NotNull NotNullLazyValue<PsiSubstitutor> substitutorComputer,
@NotNull NotNullComputable<PsiSubstitutor> substitutorComputer,
boolean isAccessible, boolean staticsOK, boolean isApplicable) {
super(element, resolveContext, spreadState, partialSubstitutor, isAccessible, staticsOK, false, isApplicable);
mySubstitutorComputer = substitutorComputer;
@@ -55,11 +61,11 @@ public class GroovyMethodResult extends GroovyResolveResultImpl {
@NotNull
@Override
public PsiSubstitutor getSubstitutor() {
return mySubstitutorComputer.getValue();
return mySubstitutorComputer.compute();
}
@NotNull
public PsiSubstitutor getSubstitutor(boolean infer) {
return infer ? mySubstitutorComputer.getValue() : super.getSubstitutor();
return infer ? mySubstitutorComputer.compute() : super.getSubstitutor();
}
}
}
@@ -16,7 +16,7 @@
package org.jetbrains.plugins.groovy.lang.resolve.processors;
import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.openapi.util.NotNullComputable;
import com.intellij.psi.*;
import com.intellij.psi.scope.JavaScopeProcessorEvent;
import com.intellij.psi.util.InheritanceUtil;
@@ -33,6 +33,7 @@ import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import org.jetbrains.plugins.groovy.lang.resolve.GrMethodComparator;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
import org.jetbrains.plugins.groovy.util.NotNullCachedComputableWrapper;
import java.util.Iterator;
import java.util.List;
@@ -108,14 +109,24 @@ public class MethodResolverProcessor extends ResolverProcessor<GroovyMethodResul
final PsiElement resolveContext = state.get(RESOLVE_CONTEXT);
final SpreadState spreadState = state.get(SpreadState.SPREAD_STATE);
final PsiSubstitutor partialSubstitutor = getSubstitutor(state);
final NotNullLazyValue<PsiSubstitutor> substitutorComputer
= myByShape ? NotNullLazyValue.createConstantValue(partialSubstitutor) : new NotNullLazyValue<PsiSubstitutor>() {
@NotNull
@Override
protected PsiSubstitutor compute() {
return mySubstitutorComputer.obtainSubstitutor(partialSubstitutor, method, resolveContext);
}
};
final NotNullComputable<PsiSubstitutor> substitutorComputer;
if (myByShape) {
substitutorComputer = new NotNullComputable<PsiSubstitutor>() {
@NotNull
@Override
public PsiSubstitutor compute() {
return partialSubstitutor;
}
};
} else {
substitutorComputer = new NotNullCachedComputableWrapper<PsiSubstitutor>(new NotNullComputable<PsiSubstitutor>() {
@NotNull
@Override
public PsiSubstitutor compute() {
return mySubstitutorComputer.obtainSubstitutor(partialSubstitutor, method, resolveContext);
}
});
}
boolean isAccessible = isAccessible(method);
boolean isStaticsOK = isStaticsOK(method, resolveContext, false);
@@ -0,0 +1,48 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.util;
import com.intellij.openapi.util.NotNullComputable;
import com.intellij.openapi.util.RecursionGuard;
import com.intellij.openapi.util.RecursionManager;
import org.jetbrains.annotations.NotNull;
public class NotNullCachedComputableWrapper<T> implements NotNullComputable<T> {
private static final RecursionGuard ourGuard = RecursionManager.createGuard(NotNullCachedComputableWrapper.class.getName());
private NotNullComputable<T> myComputable;
private T myValue;
public NotNullCachedComputableWrapper(@NotNull NotNullComputable<T> computable) {
myComputable = computable;
}
@NotNull
@Override
public T compute() {
T result = myValue;
if (result == null) {
final RecursionGuard.StackStamp stamp = ourGuard.markStack();
result = myComputable.compute();
if (stamp.mayCacheNow()) {
myValue = result;
myComputable = null; // allow gc to clean this up
}
}
return result;
}
}