From c6add71e836136fa40be424b6f0021ea04f3c8eb Mon Sep 17 00:00:00 2001 From: Daniil Ovchinnikov Date: Tue, 27 Sep 2016 17:19:40 +0300 Subject: [PATCH] [groovy] transformations: make signatures cache lazy --- .../intellij/util/containers/FactoryMap.java | 14 +++++++- .../TransformationContextImpl.java | 36 ++++++++++--------- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/platform/util/src/com/intellij/util/containers/FactoryMap.java b/platform/util/src/com/intellij/util/containers/FactoryMap.java index 07378c36bf30..9ce70a794962 100644 --- a/platform/util/src/com/intellij/util/containers/FactoryMap.java +++ b/platform/util/src/com/intellij/util/containers/FactoryMap.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -17,6 +17,7 @@ package com.intellij.util.containers; import com.intellij.openapi.util.RecursionGuard; import com.intellij.openapi.util.RecursionManager; +import com.intellij.util.Function; import com.intellij.util.ObjectUtils; import gnu.trove.THashMap; import org.jetbrains.annotations.NotNull; @@ -161,4 +162,15 @@ public abstract class FactoryMap implements Map { if (myMap == null) return Collections.emptySet(); return myMap.entrySet(); } + + @NotNull + public static FactoryMap createMap(@NotNull final Function computeValue) { + return new FactoryMap() { + @Nullable + @Override + protected V create(K key) { + return computeValue.fun(key); + } + }; + } } diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/transformations/TransformationContextImpl.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/transformations/TransformationContextImpl.java index 9263180d2eb2..726003266e4e 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/transformations/TransformationContextImpl.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/transformations/TransformationContextImpl.java @@ -20,12 +20,12 @@ import com.intellij.psi.impl.light.LightMethodBuilder; import com.intellij.psi.impl.light.LightPsiClassBuilder; import com.intellij.psi.util.MethodSignature; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.FactoryMap; import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightField; @@ -33,34 +33,36 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightMethodBuilder import org.jetbrains.plugins.groovy.lang.psi.util.GrClassImplUtil; import org.jetbrains.plugins.groovy.transformations.dsl.MemberBuilder; -import java.util.Collection; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; +import java.util.*; import static com.intellij.psi.util.MethodSignatureUtil.METHOD_PARAMETERS_ERASURE_EQUALITY; +import static com.intellij.util.containers.ContainerUtil.flatten; +import static com.intellij.util.containers.ContainerUtil.map; import static org.jetbrains.plugins.groovy.lang.psi.util.GrClassImplUtil.expandReflectedMethods; public class TransformationContextImpl implements TransformationContext { private final @NotNull GrTypeDefinition myCodeClass; - private final Set mySignatures = new THashSet<>(METHOD_PARAMETERS_ERASURE_EQUALITY); private final LinkedList myMethods = ContainerUtil.newLinkedList(); private final Collection myFields = ContainerUtil.newArrayList(); private final Collection myInnerClasses = ContainerUtil.newArrayList(); private final List myImplementsTypes = ContainerUtil.newArrayList(); private final List myExtendsTypes = ContainerUtil.newArrayList(); private final MemberBuilder myMemberBuilder = new MemberBuilder(this); + private final Map> mySignaturesCache = FactoryMap.createMap(name -> { + THashSet result = new THashSet<>(METHOD_PARAMETERS_ERASURE_EQUALITY); + for (PsiMethod existingMethod : myMethods) { + if (existingMethod.getName().equals(name)) { + result.add(existingMethod.getSignature(PsiSubstitutor.EMPTY)); + } + } + return result; + }); public TransformationContextImpl(@NotNull GrTypeDefinition codeClass) { myCodeClass = codeClass; ContainerUtil.addAll(myFields, codeClass.getCodeFields()); - for (GrMethod grMethod : codeClass.getCodeMethods()) { - for (PsiMethod method : expandReflectedMethods(grMethod)) { - mySignatures.add(method.getSignature(PsiSubstitutor.EMPTY)); - myMethods.add(method); - } - } + ContainerUtil.addAll(myMethods, flatten(map(codeClass.getCodeMethods(), m -> expandReflectedMethods(m)))); ContainerUtil.addAll(myInnerClasses, codeClass.getCodeInnerClasses()); ContainerUtil.addAll(myImplementsTypes, GrClassImplUtil.getReferenceListTypes(codeClass.getImplementsClause())); ContainerUtil.addAll(myExtendsTypes, GrClassImplUtil.getReferenceListTypes(codeClass.getExtendsClause())); @@ -97,7 +99,6 @@ public class TransformationContextImpl implements TransformationContext { } @Override - @SuppressWarnings("unused") @NotNull public List getExtendsTypes() { return myExtendsTypes; @@ -140,7 +141,8 @@ public class TransformationContextImpl implements TransformationContext { ((LightMethodBuilder)method).setContainingClass(myCodeClass); } MethodSignature signature = method.getSignature(PsiSubstitutor.EMPTY); - if (mySignatures.add(signature)) { + Set signatures = mySignaturesCache.get(method.getName()); + if (signatures.add(signature)) { if (prepend) { myMethods.addFirst(method); } @@ -173,10 +175,12 @@ public class TransformationContextImpl implements TransformationContext { @Override public void removeMethod(@NotNull PsiMethod method) { + Set signatures = mySignaturesCache.get(method.getName()); for (PsiMethod expanded : expandReflectedMethods(method)) { MethodSignature signature = expanded.getSignature(PsiSubstitutor.EMPTY); - mySignatures.remove(signature); - myMethods.removeIf(m -> METHOD_PARAMETERS_ERASURE_EQUALITY.equals(signature, m.getSignature(PsiSubstitutor.EMPTY))); + if (signatures.remove(signature)) { + myMethods.removeIf(m -> METHOD_PARAMETERS_ERASURE_EQUALITY.equals(signature, m.getSignature(PsiSubstitutor.EMPTY))); + } } }