blob: fbe0d3070009e912d302dc839e83c0be0b953ecd [file] [log] [blame]
/*
* Copyright 2000-2014 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.
*/
/*
* Created by IntelliJ IDEA.
* User: cdr
* Date: Aug 22, 2007
* Time: 9:09:57 PM
*/
package com.intellij.injected.editor;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.ex.RangeMarkerEx;
import com.intellij.openapi.util.Key;
import com.intellij.psi.PsiLanguageInjectionHost;
import org.jetbrains.annotations.NotNull;
public class RangeMarkerWindow implements RangeMarkerEx {
private final DocumentWindow myDocumentWindow;
private final RangeMarkerEx myHostMarker;
private final int myStartShift;
private final int myEndShift;
/**
* Creates new <code>RangeMarkerWindow</code> object with the given data.
*
* @param documentWindow target document window
* @param hostMarker backing host range marker
* @param startShift there is a possible situation that injected fragment uses non-empty
* {@link PsiLanguageInjectionHost.Shred#getPrefix() prefix} and
* {@link PsiLanguageInjectionHost.Shred#getSuffix() suffix}. It's also possible that target
* injected offsets are located at prefix/suffix space. We need to hold additional information
* in order to perform {@code 'host -> injected'} mapping then. This argument specifies difference
* between the start offset of the given host range marker at the injected text and target injected text
* start offset
* @param endShift similar to the 'startShift' argument but specifies difference between the target injected host end offset
* and end offset of the given host range marker at the injected text
*/
public RangeMarkerWindow(@NotNull DocumentWindow documentWindow, RangeMarkerEx hostMarker, int startShift, int endShift) {
myDocumentWindow = documentWindow;
myHostMarker = hostMarker;
myStartShift = startShift;
myEndShift = endShift;
}
@Override
@NotNull
public Document getDocument() {
return myDocumentWindow;
}
@Override
public int getStartOffset() {
int hostOffset = myHostMarker.getStartOffset();
return myDocumentWindow.hostToInjected(hostOffset) - myStartShift;
}
@Override
public int getEndOffset() {
int hostOffset = myHostMarker.getEndOffset();
return myDocumentWindow.hostToInjected(hostOffset) + myStartShift + myEndShift;
}
@Override
public boolean isValid() {
if (!myHostMarker.isValid() || !myDocumentWindow.isValid()) return false;
int startOffset = getStartOffset();
int endOffset = getEndOffset();
return startOffset <= endOffset && endOffset <= myDocumentWindow.getTextLength();
}
@Override
public boolean setValid(boolean value) {
return myHostMarker.setValid(value);
}
////////////////////////////delegates
@Override
public void setGreedyToLeft(final boolean greedy) {
myHostMarker.setGreedyToLeft(greedy);
}
@Override
public void setGreedyToRight(final boolean greedy) {
myHostMarker.setGreedyToRight(greedy);
}
@Override
public <T> T getUserData(@NotNull final Key<T> key) {
return myHostMarker.getUserData(key);
}
@Override
public <T> void putUserData(@NotNull final Key<T> key, final T value) {
myHostMarker.putUserData(key, value);
}
@Override
public void documentChanged(final DocumentEvent e) {
myHostMarker.documentChanged(e);
}
@Override
public long getId() {
return myHostMarker.getId();
}
public RangeMarkerEx getDelegate() {
return myHostMarker;
}
@Override
public boolean isGreedyToRight() {
return myHostMarker.isGreedyToRight();
}
@Override
public boolean isGreedyToLeft() {
return myHostMarker.isGreedyToLeft();
}
@Override
public int intervalStart() {
return getStartOffset();
}
@Override
public int intervalEnd() {
return getEndOffset();
}
@Override
public int setIntervalStart(int start) {
throw new IllegalStateException();
}
@Override
public int setIntervalEnd(int end) {
throw new IllegalStateException();
}
@Override
public void dispose() {
myHostMarker.dispose();
}
@Override
public String toString() {
return "RangeMarkerWindow" + (isGreedyToLeft() ? "[" : "(") + (isValid() ? "valid" : "invalid") + "," +
getStartOffset() + "," + getEndOffset() +
(isGreedyToRight() ? "]" : ")") + " " + getId();
}
}