@Nullable("null means we were unable to calculate") LogicalPosition hostToInjectedInVirtualSpace(@NotNull LogicalPosition hPos) { // beware the virtual space int hLineStartOffset = hPos.line >= myDelegate.getLineCount() ? myDelegate.getTextLength() : myDelegate.getLineStartOffset(hPos.line); int iLineStartOffset = hostToInjected(hLineStartOffset); int iLine = getLineNumber(iLineStartOffset); synchronized (myLock) { for (int i = myShreds.size() - 1; i >= 0; i--) { PsiLanguageInjectionHost.Shred shred = myShreds.get(i); if (!shred.isValid()) continue; Segment hostRangeMarker = shred.getHostRangeMarker(); if (hostRangeMarker == null) continue; int hShredEndOffset = hostRangeMarker.getEndOffset(); int hShredStartOffset = hostRangeMarker.getStartOffset(); int hShredStartLine = myDelegate.getLineNumber(hShredStartOffset); int hShredEndLine = myDelegate.getLineNumber(hShredEndOffset); if (hShredStartLine <= hPos.line && hPos.line <= hShredEndLine) { int hColumnOfShredEnd = hShredEndOffset - hLineStartOffset; int iColumnOfShredEnd = hostToInjected(hShredEndOffset) - iLineStartOffset; int iColumn = iColumnOfShredEnd + hPos.column - hColumnOfShredEnd; return new LogicalPosition(iLine, iColumn); } } } return null; }
@NotNull public LogicalPosition hostToInjected(@NotNull LogicalPosition hPos) { assert isValid(); DocumentEx hostDocument = myDelegate.getDocument(); int hLineEndOffset = hPos.line >= hostDocument.getLineCount() ? hostDocument.getTextLength() : hostDocument.getLineEndOffset(hPos.line); LogicalPosition hLineEndPos = myDelegate.offsetToLogicalPosition(hLineEndOffset); if (hLineEndPos.column < hPos.column) { // in virtual space LogicalPosition iPos = myDocumentWindow.hostToInjectedInVirtualSpace(hPos); if (iPos != null) { return iPos; } } int hOffset = myDelegate.logicalPositionToOffset(hPos); int iOffset = myDocumentWindow.hostToInjected(hOffset); return offsetToLogicalPosition(iOffset); }