[java] type element cache migrated to cached value (IDEA-147214, EA-74650)
authorRoman Shevchenko <roman.shevchenko@jetbrains.com>
Tue, 3 Nov 2015 09:57:05 +0000 (10:57 +0100)
committerRoman Shevchenko <roman.shevchenko@jetbrains.com>
Tue, 3 Nov 2015 09:57:40 +0000 (10:57 +0100)
java/java-psi-impl/src/com/intellij/psi/impl/source/PsiTypeElementImpl.java
java/java-tests/testSrc/com/intellij/codeInsight/daemon/PsiAugmentProviderTest.java

index 2adc60fbfac78189a5fa032f1ca2bae38847c900..fae8063dbe7ef2555508f14c5714aec16f1aacd2 100644 (file)
@@ -25,8 +25,7 @@ import com.intellij.psi.impl.source.tree.JavaElementType;
 import com.intellij.psi.impl.source.tree.TreeElement;
 import com.intellij.psi.scope.PsiScopeProcessor;
 import com.intellij.psi.tree.IElementType;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.util.*;
 import com.intellij.util.Function;
 import com.intellij.util.IncorrectOperationException;
 import com.intellij.util.SmartList;
@@ -38,8 +37,6 @@ import org.jetbrains.annotations.Nullable;
 import java.util.List;
 
 public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeElement {
-  private volatile PsiType myCachedType = null;
-
   @SuppressWarnings({"UnusedDeclaration"})
   public PsiTypeElementImpl() {
     this(JavaElementType.TYPE);
@@ -49,12 +46,6 @@ public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeEl
     super(type);
   }
 
-  @Override
-  public void clearCaches() {
-    super.clearCaches();
-    myCachedType = null;
-  }
-
   @Override
   public void accept(@NotNull PsiElementVisitor visitor) {
     if (visitor instanceof JavaElementVisitor) {
@@ -68,11 +59,13 @@ public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeEl
   @Override
   @NotNull
   public PsiType getType() {
-    PsiType cachedType = myCachedType;
-    if (cachedType != null) return cachedType;
-    cachedType = calculateType();
-    myCachedType = cachedType;
-    return cachedType;
+    return CachedValuesManager.getCachedValue(this, new CachedValueProvider<PsiType>() {
+      @Nullable
+      @Override
+      public Result<PsiType> compute() {
+        return Result.create(calculateType(), PsiModificationTracker.MODIFICATION_COUNT);
+      }
+    });
   }
 
   private PsiType calculateType() {
index dc197cec79305dd3eeedf917fdd4626420aad955..bea8d762338042590d3479dd85dc490a2ae4e123 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * 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.
@@ -17,111 +17,105 @@ package com.intellij.codeInsight.daemon;
 
 import com.intellij.JavaTestUtil;
 import com.intellij.codeInsight.daemon.impl.analysis.JavaGenericsUtil;
-import com.intellij.idea.Bombed;
-import com.intellij.openapi.command.WriteCommandAction;
-import com.intellij.openapi.editor.Document;
 import com.intellij.psi.*;
 import com.intellij.psi.augment.PsiAugmentProvider;
+import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.psi.util.TypeConversionUtil;
 import com.intellij.testFramework.PlatformTestUtil;
 import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-import java.util.Calendar;
 import java.util.Collections;
 import java.util.List;
 
 public class PsiAugmentProviderTest extends LightCodeInsightFixtureTestCase {
-
-  private static final String LOMBOK_VAL_FQN = "lombok.val";
-  private static final String LOMBOK_VAL_SHORT_NAME = "val";
+  @Override
+  protected String getTestDataPath() {
+    return JavaTestUtil.getJavaTestDataPath() + "/codeInsight/daemonCodeAnalyzer/augment";
+  }
 
   @Override
   public void setUp() throws Exception {
     super.setUp();
-    PlatformTestUtil.registerExtension(PsiAugmentProvider.EP_NAME, new PsiAugmentProvider() {
-      @NotNull
-      @Override
-      public <Psi extends PsiElement> List<Psi> getAugments(@NotNull PsiElement element, @NotNull Class<Psi> type) {
-        return Collections.<Psi>emptyList();
-      }
+    PlatformTestUtil.registerExtension(PsiAugmentProvider.EP_NAME, new TestAugmentProvider(), myTestRootDisposable);
+    myFixture.addClass("package lombok;\npublic @interface val { }");
+  }
+
+  public void testLombokVal() {
+    myFixture.testHighlighting(false, false, false, getTestName(false) + ".java");
+  }
+
+  public void testLombokEditing() {
+    PsiFile file = myFixture.configureByText("a.java", "import lombok.val;\nclass Foo { {val o = <caret>;} }");
+    PsiLocalVariable var = PsiTreeUtil.getParentOfType(file.findElementAt(myFixture.getCaretOffset()), PsiLocalVariable.class);
+    assertNotNull(var);
+
+    PsiType type1 = var.getType();
+    assertNotNull(type1);
+    assertEquals("lombok.val", type1.getCanonicalText(false));
+
+    myFixture.type('1');
+    PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
+    assertTrue(var.isValid());
+
+    PsiType type2 = var.getType();
+    assertNotNull(type2);
+    assertEquals(PsiType.INT.getCanonicalText(false), type2.getCanonicalText(false));
+  }
 
-      @Nullable
-      @Override
-      protected PsiType inferType(PsiTypeElement typeElement) {
-        final PsiElement parent = typeElement.getParent();
-        if (parent instanceof PsiLocalVariable && ((PsiLocalVariable)parent).getInitializer() != null ||
-            parent instanceof PsiParameter && ((PsiParameter)parent).getDeclarationScope() instanceof PsiForeachStatement) {
-          final String text = typeElement.getText();
-          if (LOMBOK_VAL_SHORT_NAME.equals(text) || LOMBOK_VAL_FQN.equals(text)) {
-            final PsiJavaCodeReferenceElement referenceElement = typeElement.getInnermostComponentReferenceElement();
-            if (referenceElement != null) {
-              final PsiElement resolve = referenceElement.resolve();
-              if (resolve instanceof PsiClass) {
-                if (parent instanceof PsiLocalVariable) {
-                  final PsiExpression initializer = ((PsiVariable)parent).getInitializer();
-                  assertNotNull(initializer);
-                  final PsiType initializerType = initializer.getType();
-                  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) {
-                          return TypeConversionUtil.erasure(initializerType);
-                        }
+  private static class TestAugmentProvider extends PsiAugmentProvider {
+    private static final String LOMBOK_VAL_FQN = "lombok.val";
+    private static final String LOMBOK_VAL_SHORT_NAME = "val";
+
+    @NotNull
+    @Override
+    public <Psi extends PsiElement> List<Psi> getAugments(@NotNull PsiElement element, @NotNull Class<Psi> type) {
+      return Collections.emptyList();
+    }
+
+    @Nullable
+    @Override
+    protected PsiType inferType(PsiTypeElement typeElement) {
+      PsiElement parent = typeElement.getParent();
+      if (parent instanceof PsiLocalVariable && ((PsiLocalVariable)parent).getInitializer() != null ||
+          parent instanceof PsiParameter && ((PsiParameter)parent).getDeclarationScope() instanceof PsiForeachStatement) {
+        String text = typeElement.getText();
+        if (LOMBOK_VAL_SHORT_NAME.equals(text) || LOMBOK_VAL_FQN.equals(text)) {
+          PsiJavaCodeReferenceElement referenceElement = typeElement.getInnermostComponentReferenceElement();
+          if (referenceElement != null) {
+            PsiElement resolve = referenceElement.resolve();
+            if (resolve instanceof PsiClass) {
+              if (parent instanceof PsiLocalVariable) {
+                PsiExpression initializer = ((PsiVariable)parent).getInitializer();
+                assertNotNull(initializer);
+                PsiType initializerType = initializer.getType();
+                if (initializer instanceof PsiNewExpression) {
+                  PsiJavaCodeReferenceElement reference = ((PsiNewExpression)initializer).getClassOrAnonymousClassReference();
+                  if (reference != null) {
+                    PsiReferenceParameterList parameterList = reference.getParameterList();
+                    if (parameterList != null) {
+                      PsiTypeElement[] elements = parameterList.getTypeParameterElements();
+                      if (elements.length == 1 && elements[0].getType() instanceof PsiDiamondType) {
+                        return TypeConversionUtil.erasure(initializerType);
                       }
                     }
                   }
-                  return initializerType;
-                }
-                final PsiForeachStatement foreachStatement = (PsiForeachStatement)((PsiParameter)parent).getDeclarationScope();
-                assertNotNull(foreachStatement);
-                final PsiExpression iteratedValue = foreachStatement.getIteratedValue();
-                if (iteratedValue != null) {
-                  return JavaGenericsUtil.getCollectionItemType(iteratedValue);
                 }
+                return initializerType;
+              }
+
+              PsiForeachStatement foreachStatement = (PsiForeachStatement)((PsiParameter)parent).getDeclarationScope();
+              PsiExpression iteratedValue = foreachStatement.getIteratedValue();
+              if (iteratedValue != null) {
+                return JavaGenericsUtil.getCollectionItemType(iteratedValue);
               }
             }
           }
         }
-        return null;
       }
-    }, myTestRootDisposable);
-    myFixture.addClass("package lombok; public @interface val{}");
-  }
 
-  public void testLombokVal() {
-    myFixture.testHighlighting(false, false, false, getTestName(false) + ".java");
+      return null;
+    }
   }
-
-  @Bombed(day = 10, month = Calendar.NOVEMBER, year = 2015, user = "Roman Shevchenko")
-  public void testLombokEditing() throws Exception {
-    final PsiFile file = myFixture.configureByText("a.java", "import lombok.val; class Foo {{val o = ;}}");
-    final PsiElement elementAt = file.findElementAt(35);
-    assertNotNull(elementAt);
-    final PsiElement parent = elementAt.getParent();
-    assertInstanceOf(parent, PsiLocalVariable.class);
-    final PsiLocalVariable var = (PsiLocalVariable)parent;
-    var.getType(); //cache
-    final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(getProject());
-    final Document document = documentManager.getDocument(file);
-    assertNotNull(document);
-    WriteCommandAction.runWriteCommandAction(getProject(), () -> {
-      document.insertString(39, "1");
-      documentManager.commitAllDocuments();
-    });
-    assertTrue(var.isValid());
-    final PsiType type = var.getType();
-    assertNotNull(type);
-    assertTrue(type.equalsToText(CommonClassNames.JAVA_LANG_STRING));
-  }
-
-  @Override
-  protected String getTestDataPath() {
-    return JavaTestUtil.getJavaTestDataPath() + "/codeInsight/daemonCodeAnalyzer/augment";
-  }
-
-}
+}
\ No newline at end of file