private ReplaceRegion getReplaceRegion(String nameToUse, String packageLocalName, JvmDeclaredType type, TypeUsage usage, RewritableImportSection importSection) { // if the resource contains two types with the same simple name, we don't add any import // but we can still use the package local name within the same package. // Except for inner types if (equal(usage.getContextPackageName(), type.getPackageName()) && type.getDeclaringType() == null) { if (type.eContainer() != null) { String declarationLocalName = getLocalName(type, usage.getContext()); nameToUse = declarationLocalName; } else if (importSection.getImportedTypes(packageLocalName) == null) { nameToUse = packageLocalName; } } String textToUse = getConcreteSyntax(nameToUse, type, usage); return new ReplaceRegion(usage.getTextRegion(), textToUse); }
private boolean isRangePartOfExceedingLookAhead(CompositeNode node, ReplaceRegion replaceRegion) { TreeIterator<AbstractNode> iterator = node.basicIterator(); int lookAhead = node.getLookAhead(); if (lookAhead == 0) { return false; } while(iterator.hasNext()) { AbstractNode child = iterator.next(); if (child instanceof CompositeNode) { if (child.getTotalOffset() < replaceRegion.getEndOffset()) lookAhead = Math.max(((CompositeNode) child).getLookAhead(), lookAhead); } else if (!((ILeafNode) child).isHidden()) { lookAhead--; if (lookAhead == 0) { if (child.getTotalOffset() >= replaceRegion.getEndOffset()) return false; } } } return lookAhead > 0; }
public void update(int offset, int replacedTextLength, String newText) { if (!isLoaded()) { throw new IllegalStateException("You can't update an unloaded resource."); } try { isUpdating = true; IParseResult oldParseResult = parseResult; ReplaceRegion replaceRegion = new ReplaceRegion(new TextRegion(offset, replacedTextLength), newText); IParseResult newParseResult; ParserRule oldEntryPoint = NodeModelUtils.getEntryParserRule(oldParseResult.getRootNode()); if (entryPoint == null || entryPoint == oldEntryPoint) { newParseResult = parser.reparse(oldParseResult, replaceRegion); } else { StringBuilder builder = new StringBuilder(oldParseResult.getRootNode().getText()); replaceRegion.applyTo(builder); newParseResult = parser.parse(entryPoint, new StringReader(builder.toString())); } updateInternalState(oldParseResult, newParseResult); } finally { isUpdating = false; } }
@Override public String processFile(String completeData, String data, int offset, int len, String change) throws Exception { IParseResult initialParseResult = parser.parse(new StringReader(data)); String newData = applyDelta(data, offset, len, change); ReplaceRegion replaceRegion = new ReplaceRegion(offset, len, change); try { IParseResult reparsed = parser.reparse(initialParseResult, replaceRegion); IParseResult parsedFromScratch = parser.parse(new StringReader(newData)); assertEqual(data, newData, parsedFromScratch, reparsed); return newData; } catch(Throwable e) { ComparisonFailure throwMe = new ComparisonFailure(e.getMessage(), newData, replaceRegion + DELIM + data); throwMe.initCause(e); throw throwMe; } }
protected void replaceAndReparse(String model, int offset, int length, String change, String expectedReparseRegion) throws Exception { IParseResult parseResult = getParseResult(model); PartialParsingPointers parsingPointers = getPartialParser().calculatePartialParsingPointers(parseResult, offset, length); String reparseRegion = getPartialParser().insertChangeIntoReplaceRegion(parsingPointers .getDefaultReplaceRootNode(), new ReplaceRegion(offset, length, change)); assertEquals(expectedReparseRegion, reparseRegion); final Wrapper<Boolean> unloaded = Wrapper.wrap(Boolean.FALSE); getPartialParser().setUnloader(new IReferableElementsUnloader() { @Override public void unloadRoot(EObject root) { unloaded.set(Boolean.TRUE); } }); IParseResult partiallyReparse = reparse(parseResult, offset, length, change); assertTrue("unloaded", unloaded.get()); assertFalse(partiallyReparse.getRootNode().getText(), partiallyReparse.hasSyntaxErrors()); String expectedReparseModel = model.substring(0, offset) + change + model.substring(offset + length); assertEquals(expectedReparseModel, partiallyReparse.getRootNode().getText()); }
protected void replaceAndReparse(String model, int offset, int length, String change, String expectedReparseRegion) throws Exception { IParseResult parseResult = getParseResultAndExpect(model, UNKNOWN_EXPECTATION); PartialParsingPointers parsingPointers = getPartialParser().calculatePartialParsingPointers(parseResult, offset, length); String reparseRegion = getPartialParser().insertChangeIntoReplaceRegion(parsingPointers .getDefaultReplaceRootNode(), new ReplaceRegion(offset, length, change)); assertEquals(expectedReparseRegion, reparseRegion); final Wrapper<Boolean> unloaded = Wrapper.wrap(Boolean.FALSE); getPartialParser().setUnloader(new IReferableElementsUnloader() { @Override public void unloadRoot(EObject root) { unloaded.set(Boolean.TRUE); } }); IParseResult partiallyReparse = reparse(parseResult, offset, length, change); assertTrue("unloaded", unloaded.get()); String expectedReparseModel = model.substring(0, offset) + change + model.substring(offset + length); assertEquals(expectedReparseModel, partiallyReparse.getRootNode().getText()); compareWithFullParse(model, offset, length, change); }
private boolean isRangePartOfExceedingLookAhead(final CompositeNode node, final ReplaceRegion replaceRegion) { TreeIterator<AbstractNode> iterator = node.basicIterator(); int lookAhead = node.getLookAhead(); if (lookAhead == 0) { return false; } while (iterator.hasNext()) { AbstractNode child = iterator.next(); if (child instanceof CompositeNode) { if (child.getTotalOffset() < replaceRegion.getEndOffset()) { lookAhead = Math.max(((CompositeNode) child).getLookAhead(), lookAhead); } } else if (!((ILeafNode) child).isHidden()) { lookAhead--; if (lookAhead == 0) { if (child.getTotalOffset() >= replaceRegion.getEndOffset()) { return false; } } } } return lookAhead > 0; }
protected List<TextEdit> getObjectEdits() { final Collection<EObject> modifiedObjects = getModifiedObjects(); Collection<EObject> topLevelObjects = EcoreUtil.filterDescendants(modifiedObjects); Iterable<EObject> containedModifiedObjects = Iterables.filter(topLevelObjects, new Predicate<EObject>() { public boolean apply(EObject input) { return input.eResource() == resource; } }); List<TextEdit> edits = Lists.newArrayListWithExpectedSize(Iterables.size(containedModifiedObjects)); for (EObject modifiedObject : containedModifiedObjects) { ReplaceRegion replaceRegion = serializer.serializeReplacement(modifiedObject, getSaveOptions()); TextEdit edit = new ReplaceEdit(replaceRegion.getOffset(), replaceRegion.getLength(), replaceRegion.getText()); edits.add(edit); } return edits; }
public List<ReplaceRegion> rewrite() { removeObsoleteStaticImports(); final List<ReplaceRegion> replaceRegions = newArrayList(); if (isSort) { List<XImportDeclaration> allImportDeclarations = newArrayList(); allImportDeclarations.addAll(originalImportDeclarations); allImportDeclarations.addAll(addedImportDeclarations); allImportDeclarations.removeAll(removedImportDeclarations); String newImportSection = serializeImports(allImportDeclarations); importRegion = regionUtil.addLeadingWhitespace(importRegion, resource); importRegion = regionUtil.addTrailingWhitespace(importRegion, resource); return singletonList(new ReplaceRegion(importRegion, newImportSection)); } else { for (XImportDeclaration removedImportDeclaration : removedImportDeclarations) { ICompositeNode node = NodeModelUtils.findActualNodeFor(removedImportDeclaration); if (node != null) { ITextRegion textRegion = node.getTextRegion(); textRegion = regionUtil.addTrailingSingleWhitespace(textRegion, lineSeparator, resource); replaceRegions.add(new ReplaceRegion(textRegion, "")); } } addSectionToAppend(new IAcceptor<ReplaceRegion>() { @Override public void accept(ReplaceRegion t) { replaceRegions.add(t); } }); } return replaceRegions; }
protected void addSectionToAppend(IAcceptor<ReplaceRegion> acceptor) { StringBuilder importDeclarationsToAppend = getImportDeclarationsToAppend(); if (importDeclarationsToAppend.length() == 0) return; importRegion = regionUtil.addLeadingWhitespace(importRegion, resource); importRegion = regionUtil.addTrailingSingleWhitespace(importRegion, lineSeparator, resource); int insertOffset = importRegion.getOffset() + importRegion.getLength(); if (insertOffset != 0 && originalImportDeclarations.isEmpty()) importDeclarationsToAppend.insert(0, lineSeparator); importDeclarationsToAppend.append(lineSeparator); int insertLength = -importRegion.getLength(); insertLength += regionUtil.addTrailingWhitespace(importRegion, resource).getLength(); ReplaceRegion appendDeclarations = new ReplaceRegion(new TextRegion(insertOffset, insertLength), importDeclarationsToAppend.toString()); acceptor.accept(appendDeclarations); }
public List<ReplaceRegion> getOrganizedImportChanges(XtextResource resource) { TypeUsageCollector typeUsageCollector = typeUsageCollectorProvider.get(); TypeUsages typeUsages = typeUsageCollector.collectTypeUsages(resource); if (unresolvedTypeResolver != null) unresolvedTypeResolver.resolve(typeUsages, resource); Map<String, JvmDeclaredType> name2type = conflictResolver.resolveConflicts(typeUsages, nonOverridableTypesProvider, resource); List<ReplaceRegion> changes = getOrganizedImportChanges(resource, name2type, typeUsages); removeNullEdits(resource, changes); return changes; }
protected void removeNullEdits(XtextResource resource, List<ReplaceRegion> changes) { Iterator<ReplaceRegion> iterator = changes.iterator(); String document = resource.getParseResult().getRootNode().getText(); while(iterator.hasNext()) { ReplaceRegion region = iterator.next(); if (region.getText().equals(document.substring(region.getOffset(), region.getEndOffset()))) { iterator.remove(); } } }
private List<ReplaceRegion> getReplacedUsageSites(Map<String, JvmDeclaredType> resolvedConflicts, TypeUsages typeUsages, RewritableImportSection newImportSection) { List<ReplaceRegion> result = newArrayList(); for (Map.Entry<String, JvmDeclaredType> textToType : resolvedConflicts.entrySet()) { getReplacedUsagesOf(textToType, typeUsages, newImportSection, result); } return result; }
private void getReplacedUsagesOf(Map.Entry<String, JvmDeclaredType> nameToType, TypeUsages typeUsages, RewritableImportSection importSection, List<ReplaceRegion> result) { String nameToUse = nameToType.getKey(); JvmDeclaredType type = nameToType.getValue(); String packageLocalName = getPackageLocalName(type); for (TypeUsage typeUsage : typeUsages.getUsages(type)) { ReplaceRegion replaceRegion = getReplaceRegion(nameToUse, packageLocalName, type, typeUsage, importSection); if (replaceRegion != null) { result.add(replaceRegion); } } }
public void addJavaDocImports(final EObject it, final ITreeAppendable appendable, final List<INode> documentationNodes) { for (final INode node : documentationNodes) { List<ReplaceRegion> _computeTypeRefRegions = this.javaDocTypeReferenceProvider.computeTypeRefRegions(node); for (final ReplaceRegion region : _computeTypeRefRegions) { { final String text = region.getText(); if (((text != null) && (text.length() > 0))) { final QualifiedName fqn = this.qualifiedNameConverter.toQualifiedName(text); final EObject context = NodeModelUtils.findActualSemanticObjectFor(node); if (((fqn.getSegmentCount() == 1) && (context != null))) { final IScope scope = this.scopeProvider.getScope(context, TypesPackage.Literals.JVM_PARAMETERIZED_TYPE_REFERENCE__TYPE); final IEObjectDescription candidate = scope.getSingleElement(fqn); if ((candidate != null)) { EObject _xifexpression = null; boolean _eIsProxy = candidate.getEObjectOrProxy().eIsProxy(); if (_eIsProxy) { _xifexpression = EcoreUtil.resolve(candidate.getEObjectOrProxy(), context); } else { _xifexpression = candidate.getEObjectOrProxy(); } final JvmType jvmType = ((JvmType) _xifexpression); if (((jvmType instanceof JvmDeclaredType) && (!jvmType.eIsProxy()))) { final JvmDeclaredType referencedType = ((JvmDeclaredType) jvmType); final JvmDeclaredType contextDeclarator = EcoreUtil2.<JvmDeclaredType>getContainerOfType(it, JvmDeclaredType.class); String _packageName = referencedType.getPackageName(); String _packageName_1 = contextDeclarator.getPackageName(); boolean _notEquals = (!Objects.equal(_packageName, _packageName_1)); if (_notEquals) { final ImportManager importManager = this.getImportManager(appendable); importManager.addImportFor(jvmType); } } } } } } } } }
private void addJavaDocReferences(final INode documentationNode, final ITextRegion selectedRegion, final ImportsAcceptor acceptor) { List<ReplaceRegion> _computeTypeRefRegions = this.javaDocTypeReferenceProvider.computeTypeRefRegions(documentationNode); for (final ReplaceRegion docTypeReference : _computeTypeRefRegions) { { int _offset = docTypeReference.getOffset(); int _length = docTypeReference.getLength(); final TextRegion referenceRange = new TextRegion(_offset, _length); boolean _contains = selectedRegion.contains(referenceRange); if (_contains) { String docTypeText = docTypeReference.getText(); final EObject element = NodeModelUtils.findActualSemanticObjectFor(documentationNode); IScope scope = this.scopeProvider.getScope(element, TypesPackage.Literals.JVM_PARAMETERIZED_TYPE_REFERENCE__TYPE); IEObjectDescription singleElement = scope.getSingleElement(QualifiedName.create(docTypeText)); JvmType referencedType = null; if ((singleElement != null)) { EObject _eObjectOrProxy = singleElement.getEObjectOrProxy(); referencedType = ((JvmType) _eObjectOrProxy); } if (((referencedType instanceof JvmDeclaredType) && (!referencedType.eIsProxy()))) { JvmDeclaredType casted = ((JvmDeclaredType) referencedType); boolean _equals = casted.getQualifiedName().equals(docTypeText); boolean _not = (!_equals); if (_not) { acceptor.acceptTypeImport(casted); } } } } } }
protected boolean addImportDeclaration(final ContentAssistEntry entry, final ITextRegion importSectionRegion, final ITypeDescriptor typeDesc, final String qualifiedName, final ContentAssistContext context) { boolean _xblockexpression = false; { int _offset = importSectionRegion.getOffset(); int _length = importSectionRegion.getLength(); final int insertionOffset = (_offset + _length); final String declaration = ("\nimport " + qualifiedName); ArrayList<ReplaceRegion> _textReplacements = entry.getTextReplacements(); ReplaceRegion _replaceRegion = new ReplaceRegion(insertionOffset, 0, declaration); _xblockexpression = _textReplacements.add(_replaceRegion); } return _xblockexpression; }
@Override public final IParseResult reparse(IParseResult previousResult, ReplaceRegion replaceRegion) { if (!isReparseSupported()) { final StringBuilder builder = new StringBuilder(previousResult.getRootNode().getText()); replaceRegion.applyTo(builder); return doParse(builder); } return doReparse(previousResult, replaceRegion); }
private boolean isNullEdit(INode oldRootNode, ReplaceRegion replaceRegion) { if (replaceRegion.getLength() == replaceRegion.getText().length()) { String replacedText = oldRootNode.getText().substring(replaceRegion.getOffset(), replaceRegion.getEndOffset()); if (replaceRegion.getText().equals(replacedText)) { return true; } } return false; }
protected IParseResult fullyReparse(IParser parser, IParseResult previousParseResult, ReplaceRegion replaceRegion) { unloadSemanticObject(previousParseResult.getRootASTElement()); ICompositeNode node = previousParseResult.getRootNode(); ParserRule parserRule = NodeModelUtils.getEntryParserRule(node); String reparseRegion = insertChangeIntoReplaceRegion(previousParseResult.getRootNode(), replaceRegion); return parser.parse(parserRule, new StringReader(reparseRegion)); }
public ReplaceRegion getTokenReplaceRegion(String changedText, ReplaceRegion replaceRegion) { int lengthDelta = replaceRegion.getText().length() - replaceRegion.getLength(); ITextRegion tokenRegion = getTokenRegion(changedText, new TextRegion(replaceRegion.getOffset(), replaceRegion .getText().length())); if (tokenRegion.getOffset() == replaceRegion.getOffset() && tokenRegion.getLength() == replaceRegion.getText().length()) return replaceRegion; else return new ReplaceRegion(tokenRegion.getOffset(), tokenRegion.getLength() - lengthDelta, changedText.substring(tokenRegion.getOffset(), tokenRegion.getOffset() + tokenRegion.getLength())); }
@Override public List<ReplaceRegion> computeTypeRefRegions(INode node) { List<ReplaceRegion> regions = Lists.newArrayList(); Iterable<ILeafNode> leafNodes = node.getLeafNodes(); computeRegions(regions, leafNodes, LINK_TAG_WITH_SUFFIX, new String[]{"#", " ", "}"}); computeRegions(regions, leafNodes, SEE_TAG_WITH_SUFFIX, new String[]{"#" , " ", "\r", "\n"}); return regions; }
@Override public List<ReplaceRegion> computeParameterTypeRefRegions(INode node) { List<ReplaceRegion> regions = Lists.newArrayList(); Iterable<ILeafNode> leafNodes = node.getLeafNodes(); computeRegions(regions, leafNodes, "@param ", new String[]{" ", "-", "\r", "\n"}); return regions; }
@Override public ReplaceRegion serializeReplacement(EObject obj, SaveOptions options) { TokenStringBuffer tokenStringBuffer = new TokenStringBuffer(); try { TreeConstructionReport report = serialize(obj, tokenStringBuffer, options); return new ReplaceRegion(report.getPreviousLocation(), tokenStringBuffer.toString()); } catch (IOException e) { throw new RuntimeException(e); } }
@Override public ReplaceRegion serializeReplacement(EObject obj, SaveOptions options) { ICompositeNode node = NodeModelUtils.findActualNodeFor(obj); if (node == null) { throw new IllegalStateException("Cannot replace an obj that has no associated node"); } String text = serialize(obj, options); return new ReplaceRegion(node.getTotalOffset(), node.getTotalLength(), text); }
@Test public void testInsertSlashInFirstNode() throws Exception { IParseResult parseResult = resource.getParser().reparse(this.parseResult, new ReplaceRegion(model.indexOf('3'), 0, "/")); assertFalse(parseResult.hasSyntaxErrors()); assertEquals(0, parseResult.getRootNode().getTotalOffset()); assertSame(resource.getParseResult().getRootNode(), parseResult.getRootNode()); String newModel = "a.b.c.d: 12/3;\n" + "e.f.g.h: 456;"; EmfAssert.assertEObjectsEqual(getModel(newModel), resource.getParseResult().getRootASTElement()); }
@Test public void testInsertSlashInSecondNode() throws Exception { IParseResult parseResult = resource.getParser().reparse(this.parseResult, new ReplaceRegion(model.indexOf('6'), 0, "/")); assertFalse(parseResult.hasSyntaxErrors()); assertEquals(0, parseResult.getRootNode().getTotalOffset()); assertSame(resource.getParseResult().getRootNode(), parseResult.getRootNode()); String newModel = "a.b.c.d: 123;\n" + "e.f.g.h: 45/6;"; EmfAssert.assertEObjectsEqual(getModel(newModel), resource.getParseResult().getRootASTElement()); }
private void checkReplaceRegion(Element element, String expectedText, String completeModel) { Serializer serializer = get(Serializer.class); ReplaceRegion replacement = serializer.serializeReplacement(element, SaveOptions.defaultOptions()); assertEquals(expectedText, replacement.getText()); assertEquals(completeModel.indexOf(expectedText), replacement.getOffset()); assertEquals(expectedText.length(), replacement.getLength()); }
private boolean isNullEdit(final INode oldRootNode, final ReplaceRegion replaceRegion) { if (replaceRegion.getLength() == replaceRegion.getText().length()) { String replacedText = oldRootNode.getText().substring(replaceRegion.getOffset(), replaceRegion.getEndOffset()); if (replaceRegion.getText().equals(replacedText)) { return true; } } return false; }
@Override public IParseResult reparse(IParser parser, IParseResult previousParseResult, ReplaceRegion changedRegion) { if (isBrokenPreviousState(previousParseResult, changedRegion.getOffset())) { return fullyReparse(parser, previousParseResult, changedRegion); } ICompositeNode oldRootNode = previousParseResult.getRootNode(); Iterator<ILeafNode> leafNodes = oldRootNode.getLeafNodes().iterator(); ILeafNode leftNode = getLeftNode(leafNodes, changedRegion.getOffset()); if (leftNode == null) { return fullyReparse(parser, previousParseResult, changedRegion); } ILeafNode rightNode = getRightNode(leafNodes, changedRegion.getEndOffset()); if (rightNode == null) { return fullyReparse(parser, previousParseResult, changedRegion); } while(leafNodes.hasNext()) { if (leafNodes.next().getSyntaxErrorMessage() != null) { return fullyReparse(parser, previousParseResult, changedRegion); } } String originalText = oldRootNode.getText().substring(leftNode.getTotalOffset()); StringBuilder newTextBuilder = new StringBuilder(originalText); changedRegion.shiftBy(-leftNode.getTotalOffset()).applyTo(newTextBuilder); String newText = newTextBuilder.toString(); if (originalText.equals(newText)) { // nothing to do return previousParseResult; } int originalLength = rightNode.getTotalEndOffset() - leftNode.getTotalOffset(); int expectedLength = originalLength - changedRegion.getLength() + changedRegion.getText().length(); if (!isSameTokenSequence(originalText.substring(0, originalLength), newText, expectedLength)) { // different token sequence, cannot perform a partial parse run return fullyReparse(parser, previousParseResult, changedRegion); } PartialParsingPointers parsingPointers = calculatePartialParsingPointers(oldRootNode, leftNode, rightNode); ICompositeNode replaceMe = getReplacedNode(parsingPointers); if (replaceMe == null || replaceMe == oldRootNode || replaceMe.getOffset() == 0 && replaceMe.getEndOffset() == oldRootNode.getLength()) { return fullyReparse(parser, previousParseResult, changedRegion); } String reparseRegion = insertChangeIntoReplaceRegion(replaceMe, changedRegion); EObject oldSemanticElement = getOldSemanticElement(replaceMe, parsingPointers); if (oldSemanticElement == null) return fullyReparse(parser, previousParseResult, changedRegion); if (oldSemanticElement == replaceMe.getParent().getSemanticElement()) { throw new IllegalStateException("oldParent == oldElement"); } IParseResult newParseResult = doParseRegion(parser, parsingPointers, replaceMe, reparseRegion); if (newParseResult == null) { throw new IllegalStateException("Could not perform a partial parse operation"); } replaceOldSemanticElement(oldSemanticElement, previousParseResult, newParseResult); nodeModelBuilder.replaceAndTransferLookAhead(replaceMe, newParseResult.getRootNode()); ((ParseResult) newParseResult).setRootNode(oldRootNode); StringBuilder builder = new StringBuilder(oldRootNode.getText()); changedRegion.applyTo(builder); nodeModelBuilder.setCompleteContent(oldRootNode, builder.toString()); return newParseResult; }
protected IParseResult fullyReparse(IParser parser, IParseResult previousParseResult, ReplaceRegion replaceRegion) { unloadSemanticObject(previousParseResult.getRootASTElement()); String reparseRegion = insertChangeIntoReplaceRegion(previousParseResult.getRootNode(), replaceRegion); return parser.parse(new StringReader(reparseRegion)); }
protected String insertChangeIntoReplaceRegion(ICompositeNode rootNode, ReplaceRegion region) { final StringBuilder builder = new StringBuilder(rootNode.getText()); region.shiftBy(0-rootNode.getTotalOffset()).applyTo(builder); return builder.toString(); }
protected IParseResult doReparse(IParseResult previousParseResult, ReplaceRegion replaceRegion) { throw new UnsupportedOperationException(); }
@Override public IParseResult reparse(IParseResult previousParseResult, ReplaceRegion replaceRegion) { return null; }
@Override protected IParseResult doReparse(IParseResult previousParseResult, ReplaceRegion replaceRegion) { return partialParser.reparse(this, previousParseResult, replaceRegion); }
public String insertChangeIntoReplaceRegion(ICompositeNode rootNode, ReplaceRegion region) { final StringBuilder builder = new StringBuilder(rootNode.getText()); region.shiftBy(0-rootNode.getTotalOffset()).applyTo(builder); return builder.toString(); }
/** * Computes regions between a given string to search and different ends searched by their precedence * * @param regions - List to put new regions in * @param leafNodes - nodes to search in * @param toSearch - String to search * @param ends - ends in decreasing precedence * @since 2.6 */ protected void computeRegions(List<ReplaceRegion> regions, Iterable<ILeafNode> leafNodes, String toSearch, String... ends) { for (ILeafNode leafNode : leafNodes) { String text = leafNode.getText(); int offset = leafNode.getOffset(); int position = text.indexOf(toSearch); int textLength = text.length(); while (position != -1) { int beginIndex = position + toSearch.length(); // Skip leading whitespaces if(Character.isWhitespace(text.charAt(beginIndex))){ while(beginIndex < textLength && Character.isWhitespace(text.charAt(beginIndex))){ beginIndex ++; } } int endIndex = -1; for (int i = ends.length -1; i >= 0; i--) { String end = ends[i]; int endCandidate = text.indexOf(end, beginIndex); if (endCandidate != -1) { if (endIndex == -1) { endIndex = endCandidate; } else { if (endIndex > endCandidate) { endIndex = endCandidate; } } } } if (endIndex == -1) { break; } else { String simpleName = text.substring(beginIndex, endIndex).replaceAll(" ", ""); if(simpleName.length() > 0 && simpleName.matches("[0-9a-zA-Z\\.\\$_]*")){ ReplaceRegion region = new ReplaceRegion(offset + beginIndex, simpleName.length(), simpleName); regions.add(region); } } position = text.indexOf(toSearch, endIndex); } } }
protected String applyDelta(String data, int offset, int len, String change) { StringBuilder builder = new StringBuilder(data); new ReplaceRegion(offset, len, change).applyTo(builder); String result = builder.toString(); return result; }
protected IParseResult reparse(IParseResult parseResult, int offset, int length, String text) { return getPartialParser().reparse(getParser(), parseResult, new ReplaceRegion(offset, length, text)); }
@Pure public ArrayList<ReplaceRegion> getTextReplacements() { return this.textReplacements; }