blob: 055d598f2ae287c283d9fb178d35c809e4fd55b9 [file] [log] [blame]
package org.eclipse.photran.internal.ui.editor;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.rules.IPartitionTokenScanner;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.Token;
import org.eclipse.photran.internal.core.lang.linescanner.FortranLineScanner;
import org.eclipse.photran.internal.core.lang.linescanner.FortranLineType;
import org.eclipse.photran.internal.core.lang.linescanner.ILookaheadLineReader;
import org.eclipse.photran.internal.ui.FortranUIPlugin;
public class FortranStmtPartitionScanner implements IPartitionTokenScanner
{
static
{
FortranLineType[] lineTypes = FortranLineType.values();
String[] partitionTypes = new String[lineTypes.length];
Map<FortranLineType, IToken> tokenTypes = new HashMap<FortranLineType, IToken>();
for (FortranLineType lineType : lineTypes)
{
String partitionType = getPartitionType(lineType);
partitionTypes[lineType.ordinal()] = partitionType;
tokenTypes.put(lineType, new Token(partitionType));
}
PARTITION_TYPES = partitionTypes;
LINE_TOKENS = tokenTypes;
}
public static final String getPartitionType(FortranLineType lineType)
{
switch (lineType)
{
case STATEMENT:
return IDocument.DEFAULT_CONTENT_TYPE;
default:
return lineType.toString();
}
}
public static final String[] PARTITION_TYPES;
private static final Map<FortranLineType, IToken> LINE_TOKENS;
private final FortranEditor editor;
private IDocument document = null;
private int startOffset = 0;
private int endOffset = 0;
private int tokenOffset = 0;
private int tokenLength = 0;
public FortranStmtPartitionScanner()
{
this.editor = null;
}
public FortranStmtPartitionScanner(FortranEditor editor)
{
this.editor = editor;
}
@Override
public void setRange(IDocument document, int offset, int length)
{
this.document = document;
this.startOffset = offset;
this.endOffset = offset + length;
}
@Override
public void setPartialRange(IDocument document, int offset, int length, String contentType,
int partitionOffset)
{
this.document = document;
try
{
this.startOffset = document.getPartition(offset).getOffset();
}
catch (BadLocationException e)
{
FortranUIPlugin.log(e);
this.startOffset = offset;
}
this.endOffset = offset + length;
}
@Override
public IToken nextToken()
{
this.tokenOffset = startOffset;
this.tokenLength = 0;
if (document == null || endOffset <= startOffset || startOffset >= document.getLength()) { return Token.EOF; }
try
{
final FortranLineScanner lineScanner = new FortranLineScanner(isFixedForm(), isCPreprocessed());
lineScanner.scan(new DocumentLookaheadLineReader());
this.tokenLength = lineScanner.getLineLength();
this.startOffset += this.tokenLength;
//System.out.printf("Partition: offset %d length %d %s\n[[[%s]]]\n", tokenOffset, tokenLength, lineScanner.getLineType(), document.get(this.tokenOffset, this.tokenLength)); //$NON-NLS-1$
return LINE_TOKENS.get(lineScanner.getLineType());
}
catch (BadLocationException e)
{
FortranUIPlugin.log(e);
return Token.EOF;
}
}
private boolean isFixedForm()
{
return editor == null ? false : editor.isFixedForm();
}
private boolean isCPreprocessed()
{
return editor == null ? true : editor.isCPreprocessed();
}
@Override
public int getTokenOffset()
{
return tokenOffset;
}
@Override
public int getTokenLength()
{
return tokenLength;
}
private final class DocumentLookaheadLineReader implements ILookaheadLineReader<BadLocationException>
{
private int offset = startOffset;
public CharSequence readNextLine() throws BadLocationException
{
if (offset >= document.getLength()) return null;
int lineNumber = document.getLineOfOffset(offset);
IRegion line = document.getLineInformation(lineNumber);
String delimiter = document.getLineDelimiter(lineNumber);
if (delimiter == null) delimiter = ""; //$NON-NLS-1$
CharSequence result = new IDocumentCharSequence(document, line.getOffset(), line.getOffset() + line.getLength() + delimiter.length());
offset += result.length();
return result;
}
public CharSequence advanceAndRestart(int numChars)
{
offset = startOffset + numChars; // Pointless, actually, since this is never reused
return null; // Return value (passed back via FortranLineScanner#scan) not used above
}
public void close()
{
}
}
}