package com.hundsun.ares.studio.ui.editor.text;
import java.util.ArrayList;
import java.util.Stack;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.reconciler.DirtyRegion;
import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
import org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension;
import org.eclipse.swt.widgets.Display;
/**
* <p>CreatedDate: 2008-2-18</p>
* @author sundl
*/
public class ARESReconclingStrategy implements IReconcilingStrategy,
IReconcilingStrategyExtension {
private GeneralSourceEditor editor;
protected IDocument document;
/** holds the calculated positions */
protected final ArrayList fPositions = new ArrayList();
/** The offset of the next character to be read */
protected int fOffset;
/** The end offset of the range to be scanned */
protected int fRangeEnd;
/**
* next character position - used locally and only valid while
* {@link #calculatePositions()} is in progress.
*/
protected int cNextPos = 0;
/* (non-Javadoc)
* @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#reconcile(org.eclipse.jface.text.IRegion)
*/
public void reconcile(IRegion partition) {
initialReconcile();
}
/* (non-Javadoc)
* @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#reconcile(org.eclipse.jface.text.reconciler.DirtyRegion, org.eclipse.jface.text.IRegion)
*/
public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) {
initialReconcile();
}
/**
* @return the editor
*/
public GeneralSourceEditor getEditor() {
return editor;
}
/**
* @param editor the editor to set
*/
public void setEditor(GeneralSourceEditor editor) {
this.editor = editor;
}
/* (non-Javadoc)
* @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#setDocument(org.eclipse.jface.text.IDocument)
*/
public void setDocument(IDocument document) {
this.document = document;
// try {
//// int l2 = document.getLineInformation(2).getLength();
//// int l4 = document.getLineInformation(4).getLength();
// int l7 = document.getLineLength(7);
// int l10 = document.getLineLength(8);
// //fPositions.add(new Position(0, /*document.getLength()*/ i + j));
// fPositions.add(new Position(document.getLineOffset(2), document.getLineOffset(8) + l10 - document.getLineOffset(2)));
// //fPositions.add(new Position(document.getLineOffset(4), document.getLineOffset(7) + l7 - document.getLineOffset(4)));
// } catch (BadLocationException e) {
// e.printStackTrace();
// }
}
/* (non-Javadoc)
* @see org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension#initialReconcile()
*/
public void initialReconcile() {
fOffset = 0;
fRangeEnd = document.getLength();
calculatePositions();
}
/**
* uses {@link #fDocument}, {@link #fOffset} and {@link #fRangeEnd} to
* calculate {@link #fPositions}. About syntax errors: this method is not a
* validator, it is useful.
*/
protected void calculatePositions() {
fPositions.clear();
cNextPos = fOffset;
// try {
// // recursiveTokens(0);
// } catch (BadLocationException e) {
// e.printStackTrace();
// }
// Collections.sort(fPositions, new RangeTokenComparator());
long start = System.currentTimeMillis();
Stack<Integer> starts = new Stack<Integer>();
while(cNextPos < fRangeEnd) {
try {
char ch = document.getChar(cNextPos++);
if(ch == '{') {
starts.push(new Integer(cNextPos -1));
} else if(ch == '}') {
if(starts.empty()) {
} else {
int offset = starts.pop().intValue();
if(fPositions.size() != 0) {
Position lastPosition = (Position)fPositions.get(fPositions.size() - 1);
int preLine = document.getLineOfOffset(lastPosition.getOffset());
int startLine = document.getLineOfOffset(offset + 1);
if(preLine == startLine) continue;
int startOffset = document.getLineOffset(startLine);
int curLine = document.getLineOfOffset(cNextPos -1);
if(curLine == startLine) continue;
int curLineLength = document.getLineLength(curLine);
int curLineOffset = document.getLineOffset(curLine);
fPositions.add(new Position(startOffset, curLineOffset + curLineLength - startOffset));
} else {
int startLine = document.getLineOfOffset(offset + 1);
int startOffset = document.getLineOffset(startLine);
int curLine = document.getLineOfOffset(cNextPos -1);
if(curLine == startLine) continue;
int curLineLength = document.getLineLength(curLine);
int curLineOffset = document.getLineOffset(curLine);
fPositions.add(new Position(startOffset, curLineOffset + curLineLength - startOffset));
}
continue;
}
} else {
continue;
}
} catch (BadLocationException e) {
e.printStackTrace();
}
}
long end = System.currentTimeMillis();
Display.getDefault().asyncExec(new Runnable() {
public void run() {
editor.updateFoldingStructure(fPositions);
}
});
}
/* (non-Javadoc)
* @see org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension#setProgressMonitor(org.eclipse.core.runtime.IProgressMonitor)
*/
public void setProgressMonitor(IProgressMonitor monitor) {
}
}