package net.sf.eclipsefp.haskell.ui.internal.editors.haskell.text; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.ListIterator; import java.util.Map; import net.sf.eclipsefp.haskell.buildwrapper.BWFacade; import net.sf.eclipsefp.haskell.buildwrapper.BuildWrapperPlugin; import net.sf.eclipsefp.haskell.buildwrapper.types.Location; import net.sf.eclipsefp.haskell.buildwrapper.types.TokenDef; import net.sf.eclipsefp.haskell.core.codeassist.ITokenTypes; import net.sf.eclipsefp.haskell.ui.HaskellUIPlugin; import net.sf.eclipsefp.haskell.ui.internal.preferences.editor.IEditorPreferenceNames; import org.eclipse.core.resources.IFile; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.Region; import org.eclipse.jface.text.rules.IPartitionTokenScanner; import org.eclipse.jface.text.rules.IToken; import org.eclipse.jface.text.rules.Token; /** * Uses Scion tokenTypesArbitrary function to get tokens for a haskell source * * @author Alejandro Serrano * @deprecated i don't see the use of that, use ScionTokenScanner instead */ @Deprecated public class PartitionedScionTokenScanner implements IPartitionTokenScanner, IEditorPreferenceNames { private final ScannerManager man; //private final ScionInstance instance; private final IFile file; private IDocument doc; private String contents; private TokenDef currentTokenDef; private List<TokenDef> lTokenDefs; private ListIterator<TokenDef> tokenDefs; private IToken currentToken; private int currentOffset; private int currentLength; private int offset; private int length; private final Map<String, IToken> tokenByTypes; private final String[] initialElements; private final String[] endElements; private final String[] initialComments; private final String[] endComments; public PartitionedScionTokenScanner( final ScannerManager man, final IFile file ) { this( man, file, new String[] { "{" }, new String[] { "}" }, new String[ 0 ], new String[ 0 ] ); } public PartitionedScionTokenScanner( final ScannerManager man,final IFile file, final String[] initialElements, final String[] endElements, final String[] initialComments, final String[] endComments ) { this.man = man; //this.instance = instance; this.file = file; this.initialElements = initialElements; this.endElements = endElements; this.initialComments = initialComments; this.endComments = endComments; this.tokenByTypes = new HashMap<String, IToken>() { // Eclipse insists on a serial version identifier, not that this hash map // will ever // get serialized... private static final long serialVersionUID = 3579246300065591883L; { put( ITokenTypes.LITERAL_STRING, man.createToken( EDITOR_STRING_COLOR, EDITOR_STRING_BOLD ) ); put( ITokenTypes.LITERAL_CHAR, man.createToken( EDITOR_CHAR_COLOR, EDITOR_CHAR_BOLD ) ); put( ITokenTypes.DOCUMENTATION_ANNOTATION, man.createToken( EDITOR_DOC_COLOR, EDITOR_DOC_BOLD ) ); put( ITokenTypes.COMMENT, man.createToken( EDITOR_COMMENT_COLOR, EDITOR_COMMENT_BOLD ) ); put( ITokenTypes.LITERATE_COMMENT, man.createToken( EDITOR_LITERATE_COMMENT_COLOR, EDITOR_LITERATE_COMMENT_BOLD ) ); put( ITokenTypes.PRAGMA, man.createToken( EDITOR_PRAGMA_COLOR, EDITOR_PRAGMA_BOLD ) ); put( ITokenTypes.KEYWORD, man.createToken( EDITOR_KEYWORD_COLOR, EDITOR_KEYWORD_BOLD ) ); put( ITokenTypes.GHC_EXTENSION_KEYWORD, man.createToken( EDITOR_KEYWORD_COLOR, EDITOR_KEYWORD_BOLD ) ); put( ITokenTypes.LITERAL_INTEGER, man.createToken( EDITOR_NUMBER_COLOR, EDITOR_NUMBER_BOLD ) ); put( ITokenTypes.LITERAL_RATIONAL, man.createToken( EDITOR_NUMBER_COLOR, EDITOR_NUMBER_BOLD ) ); put( ITokenTypes.LITERAL_WORD, man.createToken( EDITOR_NUMBER_COLOR, EDITOR_NUMBER_BOLD ) ); put( ITokenTypes.LITERAL_FLOAT, man.createToken( EDITOR_NUMBER_COLOR, EDITOR_NUMBER_BOLD ) ); put( ITokenTypes.IDENTIFIER_CONSTRUCTOR, man.createToken( EDITOR_CON_COLOR, EDITOR_CON_BOLD ) ); put( ITokenTypes.IDENTIFIER_VARIABLE, man.createToken( EDITOR_VAR_COLOR, EDITOR_VAR_BOLD ) ); put( ITokenTypes.SYMBOL_VARIABLE, man.createToken( EDITOR_VARSYM_COLOR, EDITOR_VARSYM_BOLD ) ); put( ITokenTypes.SYMBOL_RESERVED, man.createToken( EDITOR_SYMBOL_COLOR, EDITOR_SYMBOL_BOLD ) ); put( ITokenTypes.SYMBOL_SPECIAL, man.createToken( EDITOR_SYMBOL_COLOR, EDITOR_SYMBOL_BOLD ) ); put( ITokenTypes.PREPROCESSOR_TEXT, man.createToken( EDITOR_CPP_COLOR, EDITOR_CPP_BOLD ) ); put( ITokenTypes.TEMPLATE_HASKELL, man.createToken( EDITOR_TH_COLOR, EDITOR_TH_BOLD ) ); } }; } @Override public int getTokenLength() { if( currentTokenDef != null ) { return currentLength; } return 0; } @Override public int getTokenOffset() { if( currentTokenDef != null ) { return currentOffset; } return 0; } @Override public IToken nextToken() { do { if( tokenDefs != null && tokenDefs.hasNext() ) { TokenDef nextTokenDef = tokenDefs.next(); try { int nextOffset = nextTokenDef.getLocation().getStartOffset( doc ); int nextEnd = nextTokenDef.getLocation().getEndOffset( doc ); int end = Math.min( offset + length, nextEnd ); IToken nextToken = getTokenFromTokenDef( nextTokenDef ); if( currentToken != null && currentToken.getData().equals( nextToken.getData() ) && currentOffset + currentLength < nextOffset ) { nextOffset = currentOffset + currentLength; } int nextLength = end - nextOffset; currentLength = nextLength; currentOffset = nextOffset; currentTokenDef = nextTokenDef; currentToken = nextToken; if( currentOffset > offset + length ) { return Token.EOF; } } catch( BadLocationException ble ) { HaskellUIPlugin.log( ble ); } } else { return Token.EOF; } } while( currentOffset < offset ); return currentToken; } @Override public void setRange( final IDocument document, final int offset, final int length ) { currentTokenDef = null; // currentToken=null; tokenDefs = null; int realOffset = offset, realLength = length; try { String prevContents = document.get( realOffset, realLength ); // Check whether this is a comment boolean isInitialComment = false, isEndComment = false; for( String initialC: initialComments ) { if( prevContents.startsWith( initialC ) ) { isInitialComment = true; break; } } for( String endC: endComments ) { if( prevContents.endsWith( endC ) ) { isEndComment = true; break; } } if( isInitialComment && isEndComment ) { // We found a comment doc = document; contents = prevContents; TokenDef def = new TokenDef( ITokenTypes.LITERATE_COMMENT, new Location( "", document, new Region( realOffset, realLength ) ) ); lTokenDefs = new ArrayList<>(); lTokenDefs.add( def ); } else { // We are not in a comment for( String initialE: initialElements ) { if( prevContents.startsWith( initialE ) ) { int initialLength = initialE.length(); realOffset += initialLength; realLength -= initialLength; for( int i = initialLength; i < prevContents.length(); i++ ) { char c = prevContents.charAt( i ); if( Character.isWhitespace( c ) ) { realOffset++; realLength--; } else { break; } } break; } } for( String endE: endElements ) { if( prevContents.endsWith( endE ) ) { realLength -= endE.length(); break; } } String newContents = document.get( realOffset, realLength ); if( !document.equals( doc ) || !newContents.equals( contents ) || lTokenDefs == null ) { doc = document; contents = newContents; BWFacade f=BuildWrapperPlugin.getFacade( file.getProject() ); if (f!=null){ f.write( file, contents ); lTokenDefs = f.tokenTypes( file ); } } try { // Move the offset to the correct place // First get line and character int line = document.getLineOfOffset( realOffset ); int lineOffset = document.getLineOffset( line ); int column = realOffset - lineOffset; if( lTokenDefs != null ) { for( TokenDef def: lTokenDefs ) { def.move( line, column ); } } } catch( BadLocationException ble ) { HaskellUIPlugin.log( ble ); } } } catch( BadLocationException ble ) { HaskellUIPlugin.log( ble ); } this.doc = document; if( lTokenDefs != null && lTokenDefs.size() > 0 ) { tokenDefs = lTokenDefs.listIterator(); } this.offset = realOffset; this.length = realLength; this.currentTokenDef = null; this.currentOffset = this.offset; this.currentLength = this.length; } private IToken getTokenFromTokenDef( final TokenDef td ) { IToken tok = tokenByTypes.get( td.getName() ); if( tok != null ) { return tok; } return man.createToken( EDITOR_DEFAULT_COLOR, EDITOR_DEFAULT_BOLD ); } @Override public void setPartialRange( final IDocument document, final int offset, final int length, final String contentType, final int partitionOffset ) { setRange( document, offset, length ); } }