package com.siberika.idea.pascal.lang.psi.impl; import com.intellij.lang.ASTNode; import com.intellij.openapi.util.ProperTextRange; import com.intellij.openapi.util.TextRange; import com.intellij.psi.LiteralTextEscaper; import com.intellij.psi.PsiLanguageInjectionHost; import com.intellij.psi.PsiType; import com.intellij.psi.impl.source.tree.LeafElement; import com.siberika.idea.pascal.lang.psi.PascalPsiElement; import org.apache.commons.lang.StringUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** * Author: George Bakhtadze * Date: 21/01/2016 */ public abstract class PascalStringImpl extends PascalPsiElementImpl implements PsiLanguageInjectionHost, PascalPsiElement { public PascalStringImpl(ASTNode node) { super(node); } @Override public boolean isValidHost() { return true; } @Override public PascalStringImpl updateText(@NotNull String text) { ASTNode valueNode = getNode().getFirstChildNode(); assert valueNode instanceof LeafElement; ((LeafElement)valueNode).replaceWithText(text); return this; } @Nullable public String getValue() { return getText().length() > 2 ? getText().substring(1, getText().length() - 1) : ""; } @Nullable public PsiType getType() { return null; } @NotNull @Override public LiteralTextEscaper<? extends PsiLanguageInjectionHost> createLiteralTextEscaper() { return new LiteralTextEscaper<PsiLanguageInjectionHost>(this) { private String lastDecoded; @Override public boolean decode(@NotNull TextRange rangeInsideHost, @NotNull StringBuilder outChars) { ProperTextRange.assertProperRange(rangeInsideHost); String value = myHost.getText().substring(rangeInsideHost.getStartOffset(), rangeInsideHost.getEndOffset()); lastDecoded = value.replace("''", "'"); outChars.append(lastDecoded); return false; } @Override public int getOffsetInHost(int offsetInDecoded, @NotNull TextRange rangeInsideHost) { ProperTextRange.assertProperRange(rangeInsideHost); int offset = rangeInsideHost.getStartOffset() + offsetInDecoded; int escapedCount = StringUtils.countMatches(lastDecoded.substring(0, offsetInDecoded), "'"); offset += escapedCount; if (offset < rangeInsideHost.getStartOffset()) offset = rangeInsideHost.getStartOffset(); if (offset > rangeInsideHost.getEndOffset()) offset = rangeInsideHost.getEndOffset(); return offset; } @Override public boolean isOneLine() { return true; } }; } }