/** * Copyright: Fabio Zadrozny * License: EPL */ package org.python.pydev.shared_core.partitioner; import org.eclipse.core.runtime.Assert; import org.eclipse.jface.text.TypedPosition; import org.python.pydev.shared_core.string.FastStringBuffer; public class TypedPositionWithSubTokens extends TypedPosition { /** * Note: offsets should be relative to the offset in this position. */ private SubRuleToken subRuleToken; public TypedPositionWithSubTokens(int offset, int length, String type, SubRuleToken subRuleToken, boolean fixRelativeOffset) { super(offset, length, type); if (fixRelativeOffset) { this.setSubRuleToken(subRuleToken); } else { this.subRuleToken = subRuleToken; } } public TypedPositionWithSubTokens(int offset, int length, String type, SubRuleToken subRuleToken) { this(offset, length, type, subRuleToken, true); } public void clearSubRuleToken() { subRuleToken = null; } public void setSubRuleToken(SubRuleToken subRuleToken) { if (subRuleToken != null) { subRuleToken.makeRelativeToOffset(this.getOffset()); } this.subRuleToken = subRuleToken; } public SubRuleToken getSubRuleToken() { return subRuleToken; } public String toStringTest() { FastStringBuffer buf = new FastStringBuffer(); buf.append(getType() + ":" + getOffset() + ":" + getLength()).append(" [\n ") .append(subRuleToken != null ? subRuleToken.toStringBetter() : "null") .append("\n]"); return buf.toString(); } /** * Important: the object passed (and this object) may be mutated, thus, a copy should be passed * if the original ones should not be changed. */ public void mergeSubRuleToken(TypedPositionWithSubTokens withSub) { if (withSub == null || withSub.subRuleToken == null) { return; } if (subRuleToken == null) { subRuleToken = withSub.subRuleToken; return; } // We only implement for this situation. Assert.isTrue(withSub.offset >= this.offset); // Already make it relative to the offset in this position. withSub.subRuleToken.addOffset(withSub.offset); withSub.subRuleToken.makeRelativeToOffset(offset); // Both exist, let's see if the token/token data matches Object d0 = subRuleToken.token.getData(); Object d1 = withSub.subRuleToken.token.getData(); if (d0 == d1 || (d0 != null && d1 != null && d0.equals(d1))) { // Matches: just add the children and fix its len subRuleToken.addChildren(withSub.subRuleToken.getChildren()); } else { // The data doesn't match. Create a SubToken with null data with the proper size (or reuse the // current one if that's it's type already). SubRuleToken newSub; if (subRuleToken.token.getData() != null) { newSub = new SubRuleToken(new DummyToken(null), subRuleToken.offset, subRuleToken.len); newSub.addChild(subRuleToken); this.subRuleToken = newSub; } this.subRuleToken.addChild(withSub.subRuleToken); } int finalOffset = withSub.subRuleToken.offset + withSub.subRuleToken.len; int currentFinalOffset = subRuleToken.offset + subRuleToken.len; if (currentFinalOffset < finalOffset) { subRuleToken.len += finalOffset - currentFinalOffset; } } public TypedPositionWithSubTokens createCopy() { return new TypedPositionWithSubTokens(this.offset, this.length, this.getType(), this.subRuleToken != null ? this.subRuleToken.createCopy() : null, false); } }