reformat of many injected fragments: do not recreate range markers for each (exception "too many RMs" otherwise)

This commit is contained in:
Alexey Kudravtsev
2012-10-10 16:08:10 +04:00
parent c7e7c0ffd2
commit 5726d507ed
12 changed files with 54 additions and 35 deletions
@@ -97,7 +97,7 @@ class AnchorElementInfo extends SelfElementInfo {
}
@Override
public void fastenBelt(int offset, RangeMarker cachedRangeMarker) {
public void fastenBelt(int offset, RangeMarker[] cachedRangeMarker) {
if (stubId != -1) {
PsiElement element = restoreElement();
if (element != null) {
@@ -65,7 +65,7 @@ public class ImplicitVariableElementInfoFactory implements SmartPointerElementIn
}
@Override
public void fastenBelt(int offset, RangeMarker cachedRangeMarker) {
public void fastenBelt(int offset, RangeMarker[] cachedRangeMarker) {
}
@Override
@@ -42,7 +42,7 @@ public class ClsElementInfo implements SmartPointerElementInfo {
// before change
@Override
public void fastenBelt(int offset, RangeMarker cachedRangeMarker) {
public void fastenBelt(int offset, RangeMarker[] cachedRangeMarker) {
}
// after change
@@ -58,7 +58,7 @@ class FileElementInfo implements SmartPointerElementInfo {
}
@Override
public void fastenBelt(int offset, RangeMarker cachedRangeMarker) {
public void fastenBelt(int offset, RangeMarker[] cachedRangeMarker) {
}
@Override
@@ -47,7 +47,7 @@ class HardElementInfo implements SmartPointerElementInfo {
}
@Override
public void fastenBelt(int offset, RangeMarker cachedRangeMarker) {
public void fastenBelt(int offset, RangeMarker[] cachedRangeMarker) {
}
@Override
@@ -88,7 +88,7 @@ public class SelfElementInfo implements SmartPointerElementInfo {
setRange(anchor);
}
protected void setRange(TextRange range) {
protected void setRange(@NotNull Segment range) {
mySyncStartOffset = range.getStartOffset();
mySyncEndOffset = range.getEndOffset();
}
@@ -104,7 +104,7 @@ public class SelfElementInfo implements SmartPointerElementInfo {
// before change
@Override
public void fastenBelt(int offset, @Nullable RangeMarker cachedRangeMarker) {
public void fastenBelt(int offset, @Nullable RangeMarker[] cachedRangeMarkers) {
if (!mySyncMarkerIsValid) return;
RangeMarker marker = getMarker();
int actualEndOffset = marker == null || !marker.isValid() ? getSyncEndOffset() : marker.getEndOffset();
@@ -120,11 +120,15 @@ public class SelfElementInfo implements SmartPointerElementInfo {
int start = Math.min(getSyncStartOffset(), document.getTextLength());
int end = Math.min(Math.max(getSyncEndOffset(), start), document.getTextLength());
// use supplied cached markers if available
if (cachedRangeMarker != null &&
cachedRangeMarker.isValid() &&
cachedRangeMarker.getStartOffset() == start &&
cachedRangeMarker.getEndOffset() == end) {
marker = cachedRangeMarker;
if (cachedRangeMarkers != null) {
for (RangeMarker cachedRangeMarker : cachedRangeMarkers) {
if (cachedRangeMarker.isValid() &&
cachedRangeMarker.getStartOffset() == start &&
cachedRangeMarker.getEndOffset() == end) {
marker = cachedRangeMarker;
break;
}
}
}
else {
marker = document.createRangeMarker(start, end, true);
@@ -147,8 +151,7 @@ public class SelfElementInfo implements SmartPointerElementInfo {
RangeMarker marker = getMarker();
if (marker != null) {
if (marker.isValid()) {
mySyncStartOffset = marker.getStartOffset();
mySyncEndOffset = marker.getEndOffset();
setRange(marker);
assert mySyncEndOffset <= marker.getDocument().getTextLength() : "mySyncEndOffset: "+mySyncEndOffset+"; docLength: "+marker.getDocument().getTextLength()+"; marker: "+marker +"; "+marker.getClass();
}
else {
@@ -30,7 +30,7 @@ interface SmartPointerElementInfo {
Document getDocumentToSynchronize();
void documentAndPsiInSync();
void fastenBelt(int offset, RangeMarker cachedRangeMarker);
void fastenBelt(int offset, RangeMarker[] cachedRangeMarkers);
void unfastenBelt(int offset);
@@ -21,7 +21,7 @@ import com.intellij.psi.SmartPsiElementPointer;
import org.jetbrains.annotations.Nullable;
public interface SmartPointerEx<E extends PsiElement> extends SmartPsiElementPointer<E> {
void fastenBelt(int offset, @Nullable RangeMarker cachedRangeMarker);
void fastenBelt(int offset, @Nullable RangeMarker[] cachedRangeMarkers);
void documentAndPsiInSync();
void unfastenBelt(int offset);
@@ -18,7 +18,6 @@ package com.intellij.psi.impl.smartPointers;
import com.intellij.injected.editor.DocumentWindow;
import com.intellij.lang.Language;
import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
@@ -29,11 +28,13 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.ProperTextRange;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.tree.injected.InjectedFileViewProvider;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.reference.SoftReference;
import com.intellij.util.containers.UnsafeWeakList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import java.lang.ref.Reference;
import java.util.List;
@@ -51,7 +52,7 @@ public class SmartPointerManagerImpl extends SmartPointerManager {
myProject = project;
}
public void fastenBelts(@NotNull PsiFile file, int offset, @Nullable RangeMarker cachedRangeMarker) {
public void fastenBelts(@NotNull PsiFile file, int offset, @Nullable RangeMarker[] cachedRangeMarkers) {
synchronized (file) {
if (areBeltsFastened(file)) return;
@@ -68,30 +69,23 @@ public class SmartPointerManagerImpl extends SmartPointerManager {
for (int i = 0; i < pointers.size(); i++) {
SmartPointerEx pointer = pointers.get(i);
if (pointer != null) {
pointer.fastenBelt(offset, cachedRangeMarker);
pointer.fastenBelt(offset, cachedRangeMarkers);
}
}
for (DocumentWindow injectedDoc : InjectedLanguageUtil.getCachedInjectedDocuments(file)) {
PsiFile injectedFile = psiDocumentManager.getPsiFile(injectedDoc);
if (injectedFile == null) continue;
RangeMarker cachedMarker = getCachedRangeMarkerToInjectedFragment(injectedFile);
fastenBelts(injectedFile, 0, cachedMarker);
RangeMarker[] cachedMarkers = getCachedRangeMarkerToInjectedFragment(injectedFile);
fastenBelts(injectedFile, 0, cachedMarkers);
}
}
}
private static RangeMarker getCachedRangeMarkerToInjectedFragment(@NotNull PsiFile injectedFile) {
PsiElement hostContext = InjectedLanguageManager.getInstance(injectedFile.getProject()).getInjectionHost(injectedFile);
RangeMarker cachedMarker = null;
if (hostContext != null) {
SmartPsiElementPointer<PsiElement> cachedPointer = getCachedPointer(hostContext);
SmartPointerElementInfo info = cachedPointer == null ? null : ((SmartPsiElementPointerImpl)cachedPointer).getElementInfo();
if (info instanceof SelfElementInfo) {
cachedMarker = ((SelfElementInfo)info).getMarker();
}
}
return cachedMarker;
@NotNull
private static RangeMarker[] getCachedRangeMarkerToInjectedFragment(@NotNull PsiFile injectedFile) {
InjectedFileViewProvider provider = (InjectedFileViewProvider)injectedFile.getViewProvider();
return provider.getCachedMarkers();
}
public void unfastenBelts(@NotNull PsiFile file, int offset) {
@@ -221,6 +215,12 @@ public class SmartPointerManagerImpl extends SmartPointerManager {
return containingFile.getUserData(SMART_POINTERS_IN_PSI_FILE_KEY);
}
@TestOnly
public int getPointersNumber(@NotNull PsiFile containingFile) {
List<SmartPointerEx> pointers = getPointers(containingFile);
return pointers == null ? 0 : pointers.size();
}
private static boolean areBeltsFastened(@NotNull PsiFile file) {
return file.getUserData(BELTS_ARE_FASTEN_KEY) == Boolean.TRUE;
}
@@ -201,8 +201,8 @@ class SmartPsiElementPointerImpl<E extends PsiElement> implements SmartPointerEx
}
@Override
public void fastenBelt(int offset, @Nullable RangeMarker cachedRangeMarker) {
myElementInfo.fastenBelt(offset, cachedRangeMarker);
public void fastenBelt(int offset, @Nullable RangeMarker[] cachedRangeMarkers) {
myElementInfo.fastenBelt(offset, cachedRangeMarkers);
}
@NotNull
@@ -21,6 +21,7 @@ import com.intellij.injected.editor.DocumentWindowImpl;
import com.intellij.injected.editor.VirtualFileWindow;
import com.intellij.lang.Language;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Ref;
@@ -30,6 +31,8 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.FreeThreadedFileViewProvider;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.util.List;
@@ -189,6 +192,7 @@ public class InjectedFileViewProvider extends SingleRootFileViewProvider impleme
}
}
@NonNls
@Override
public String toString() {
return "Injected file '"+getVirtualFile().getName()+"' " + (isValid() ? "" : " invalid") + (isPhysical() ? "" : " nonphysical");
@@ -197,4 +201,16 @@ public class InjectedFileViewProvider extends SingleRootFileViewProvider impleme
public void setPatchingLeaves(boolean patchingLeaves) {
myPatchingLeaves = patchingLeaves;
}
@NotNull
public RangeMarker[] getCachedMarkers() {
List<RangeMarker> markers = new SmartList<RangeMarker>();
for (PsiLanguageInjectionHost.Shred shred : myDocumentWindow.getShreds()) {
RangeMarker marker = (RangeMarker)shred.getHostRangeMarker();
if (marker != null) {
markers.add(marker);
}
}
return markers.toArray(new RangeMarker[markers.size()]);
}
}
@@ -61,7 +61,7 @@ class ShredImpl implements PsiLanguageInjectionHost.Shred {
@Nullable("returns null when the host document marker is invalid")
public Segment getHostRangeMarker() {
RangeMarker marker = relevantRangeInHost;
return marker == null || !marker.isValid() ? null : marker;
return marker.isValid() ? marker : null;
}
@Override