/net.sf.eclipsefp.haskell.ui/src/net/sf/eclipsefp/haskell/ui/internal/refactoring/participants/Util.java
https://github.com/thiagoarrais/eclipsefp · Java · 469 lines · 393 code · 48 blank · 28 comment · 63 complexity · 2eafb90865be85212d959f89dc57b5a0 MD5 · raw file
- /**
- * (c) 2011, Alejandro Serrano
- * Released under the terms of the EPL.
- */
- package net.sf.eclipsefp.haskell.ui.internal.refactoring.participants;
- import java.util.ArrayList;
- import java.util.HashSet;
- import java.util.List;
- import java.util.Set;
- import net.sf.eclipsefp.haskell.core.cabalmodel.CabalSyntax;
- import net.sf.eclipsefp.haskell.core.cabalmodel.PackageDescription;
- import net.sf.eclipsefp.haskell.core.cabalmodel.PackageDescriptionLoader;
- import net.sf.eclipsefp.haskell.core.cabalmodel.PackageDescriptionStanza;
- import net.sf.eclipsefp.haskell.core.cabalmodel.RealValuePosition;
- import net.sf.eclipsefp.haskell.scion.client.ScionInstance;
- import net.sf.eclipsefp.haskell.util.FileUtil;
- import org.eclipse.core.resources.IFile;
- import org.eclipse.core.resources.IProject;
- import org.eclipse.core.resources.IResource;
- import org.eclipse.core.resources.IResourceVisitor;
- import org.eclipse.core.runtime.CoreException;
- import org.eclipse.core.runtime.IPath;
- import org.eclipse.core.runtime.Path;
- import org.eclipse.jface.text.BadLocationException;
- import org.eclipse.jface.text.IDocument;
- import org.eclipse.jface.text.IRegion;
- import org.eclipse.ui.editors.text.TextFileDocumentProvider;
- /**
- * Utilities and shared changes creation for participants.
- * @author Alejandro Serrano
- *
- */
- public class Util {
- public static Set<IPath> getPaths( final IProject project ) {
- HashSet<IPath> paths = new HashSet<IPath>();
- try {
- IFile cabalF = ScionInstance.getCabalFile( project );
- PackageDescription pd = PackageDescriptionLoader.load( cabalF );
- List<PackageDescriptionStanza> lpds = pd.getStanzas();
- for( PackageDescriptionStanza pds: lpds ) {
- String propList = pds.getProperties().get(
- CabalSyntax.FIELD_HS_SOURCE_DIRS.getCabalName().toLowerCase() );
- propList = propList == null ? "" : propList;
- List<String> props = PackageDescriptionLoader.parseList( propList );
- for (String prop : props) {
- IPath prefixPath = Path.fromPortableString( prop );
- paths.add( prefixPath );
- }
- }
- } catch (Exception e) {
- return new HashSet<IPath>();
- }
- return paths;
- }
- public static Set<IPath> getStanzaPaths( final IProject project,
- final IFile file ) {
- HashSet<IPath> paths = new HashSet<IPath>();
- try {
- IFile cabalF = ScionInstance.getCabalFile( project );
- PackageDescription pd = PackageDescriptionLoader.load( cabalF );
- List<PackageDescriptionStanza> lpds = pd.getStanzas();
- for( PackageDescriptionStanza pds: lpds ) {
- String propList = pds.getProperties().get(
- CabalSyntax.FIELD_HS_SOURCE_DIRS.getCabalName().toLowerCase() );
- propList = propList == null ? "" : propList;
- List<String> props = PackageDescriptionLoader.parseList( propList );
- // If the file is in one of these directories, we should change it
- boolean shouldBeAdded = false;
- for (String prop : props) {
- IPath prefixPath = Path.fromPortableString( prop );
- if (prefixPath.isPrefixOf( file.getProjectRelativePath() )) {
- shouldBeAdded = true;
- }
- }
- // If should be changed, add every directory in the stanza
- if (shouldBeAdded) {
- for (String prop : props) {
- IPath prefixPath = Path.fromPortableString( prop );
- paths.add( prefixPath );
- }
- }
- }
- } catch (Exception e) {
- return new HashSet<IPath>();
- }
- return paths;
- }
- public static String getModuleName( final IResource resource ) {
- return getModuleName( resource.getProject(),
- resource.getProjectRelativePath() );
- }
- public static List<IResource> getHaskellFiles( final IProject project,
- final IFile file ) {
- final ArrayList<IResource> resources = new ArrayList<IResource>();
- final Set<IPath> allowedPaths = getStanzaPaths( project, file );
- try {
- project.accept( new IResourceVisitor() {
- public boolean visit( final IResource resource ) {
- if( resource instanceof IFile && !( file.equals( resource ) )
- && FileUtil.hasHaskellExtension( resource )) {
- // Check if we are in one of the allowed paths
- for (IPath allowedPath : allowedPaths) {
- if (allowedPath.isPrefixOf( resource.getProjectRelativePath() )) {
- resources.add( resource );
- break;
- }
- }
- }
- return true;
- }
- } );
- } catch( Exception e ) {
- // Do nothing
- }
- return resources;
- }
- public static String getModuleName( final IProject project,
- final IPath projectRelativePath ) {
- String path = projectRelativePath.toPortableString();
- for( IPath prefix: getPaths( project ) ) {
- String prefixPath = prefix.toPortableString();
- if( path.startsWith( prefixPath ) ) {
- String filePath = path.substring( prefixPath.length() + 1 );
- if( filePath.endsWith( ".hs" ) ) {
- return filePath.substring( 0, filePath.length() - 3 ).replace( '/',
- '.' );
- } else if( filePath.endsWith( ".lhs" ) ) {
- return filePath.substring( 0, filePath.length() - 4 ).replace( '/',
- '.' );
- }
- }
- }
- return null;
- }
- public static int getModuleNameOffset( final IResource resource ) {
- TextFileDocumentProvider provider = new TextFileDocumentProvider();
- try {
- provider.connect( resource );
- } catch( CoreException e ) {
- return -1;
- }
- int offset = -1;
- try {
- IDocument doc = provider.getDocument( resource );
- int numberOfLines = doc.getNumberOfLines();
- for( int i = 0; i < numberOfLines; i++ ) {
- IRegion region = doc.getLineInformation( i );
- String text = doc.get( region.getOffset(), region.getLength() );
- String[] words = text.split( " " );
- if( words[ 0 ].equals( "module" ) ) {
- // We are in a module declaration
- String moduleName = words[ 1 ];
- if( moduleName.length() == 0 ) {
- moduleName = words[ 2 ];
- }
- int moduleNamePos = text.indexOf( moduleName );
- offset = region.getOffset() + moduleNamePos;
- break;
- }
- }
- } catch( BadLocationException e ) {
- // This should not happen
- } finally {
- provider.disconnect( resource );
- }
- return offset;
- }
- public static List<Integer> getImportModuleOffsets( final IResource resource,
- final String moduleName ) {
- TextFileDocumentProvider provider = new TextFileDocumentProvider();
- ArrayList<Integer> offsets = new ArrayList<Integer>();
- try {
- provider.connect( resource );
- } catch( CoreException e ) {
- return offsets;
- }
- try {
- IDocument doc = provider.getDocument( resource );
- int numberOfLines = doc.getNumberOfLines();
- for( int i = 0; i < numberOfLines; i++ ) {
- IRegion region = doc.getLineInformation( i );
- String text = doc.get( region.getOffset(), region.getLength() );
- String[] words = text.split( " " );
- for( int j = 0; j < words.length; j++ ) {
- if( words[ j ].equals( "module" ) ) {
- try {
- String mname = words[ j + 1 ];
- if( mname.length() == 0 ) {
- mname = words[ j + 2 ];
- }
- if( mname.equals( moduleName ) ) {
- int modulePos = text.indexOf( mname );
- offsets.add( region.getOffset() + modulePos );
- }
- } catch( Exception e ) {
- // We are out of bounds
- }
- break;
- } else if( words[ j ].equals( "import" ) ) {
- try {
- String mname = words[ j + 1 ];
- if( mname.length() == 0 ) {
- mname = words[ j + 2 ];
- }
- if( mname.equals( "qualified" ) ) {
- mname = words[ j + 3 ];
- if( mname.length() == 0 ) {
- mname = words[ j + 4 ];
- }
- }
- if( mname.equals( moduleName ) ) {
- int modulePos = text.indexOf( mname );
- offsets.add( region.getOffset() + modulePos );
- }
- } catch( Exception e ) {
- // We are out of bounds
- }
- break;
- }
- }
- }
- } catch( BadLocationException e ) {
- // This should not happen
- } finally {
- provider.disconnect( resource );
- }
- return offsets;
- }
- public static String newCabalFile( final IProject project,
- final IFile oldFile, final String newModuleName ) {
- TextFileDocumentProvider provider = new TextFileDocumentProvider();
- String oldModuleName = getModuleName( oldFile );
- IFile cabalF = ScionInstance.getCabalFile( project );
- PackageDescription pd = null;
- try {
- pd = PackageDescriptionLoader.load( cabalF );
- provider.connect( cabalF );
- } catch( Exception e ) {
- return null;
- }
- IDocument doc = provider.getDocument( cabalF );
- try {
- List<PackageDescriptionStanza> lpds = pd.getStanzas();
- for( PackageDescriptionStanza pds: lpds ) {
- // Should we change this stanza?
- String srcList = pds.getProperties().get(
- CabalSyntax.FIELD_HS_SOURCE_DIRS.getCabalName().toLowerCase() );
- srcList = srcList == null ? "" : srcList;
- List<String> srcs = PackageDescriptionLoader.parseList( srcList );
- final Set<IPath> allowedPaths = getStanzaPaths( project, oldFile );
- boolean shouldBeChanged = false;
- for (String src : srcs) {
- IPath srcPath = Path.fromPortableString( src );
- if (allowedPaths.contains( srcPath )) {
- shouldBeChanged = true;
- break;
- }
- }
- if (!shouldBeChanged) {
- continue; // We should not
- }
- // Modules sections
- CabalSyntax[] elements = new CabalSyntax[] {
- CabalSyntax.FIELD_EXPOSED_MODULES, CabalSyntax.FIELD_OTHER_MODULES };
- for( CabalSyntax element: elements ) {
- pds = pd.getSameStanza( pds );
- String propList = pds.getProperties().get(
- element.getCabalName().toLowerCase() );
- propList = propList == null ? "" : propList;
- List<String> props = PackageDescriptionLoader.parseList( propList );
- if( props.indexOf( oldModuleName ) != -1 ) {
- RealValuePosition rvp = pds.removeFromPropertyList( element,
- oldModuleName );
- rvp.updateDocument( doc );
- pd = PackageDescriptionLoader.load( doc.get() );
- pds = pd.getSameStanza( pds );
- rvp = pds.addToPropertyList( element, newModuleName );
- rvp.updateDocument( doc );
- pd = PackageDescriptionLoader.load( doc.get() );
- pds = pd.getSameStanza( pds );
- }
- }
- // Main-is section
- String oldMainName = oldModuleName.replace( '.', '/' ) + ".hs";
- String newMainName = newModuleName.replace( '.', '/' ) + ".hs";
- pds = pd.getSameStanza( pds );
- String mainProp = pds.getProperties().get(
- CabalSyntax.FIELD_MAIN_IS.getCabalName().toLowerCase() );
- mainProp = mainProp == null ? "" : mainProp;
- if( oldMainName.equals( mainProp ) ) {
- RealValuePosition rvp = pds.update( CabalSyntax.FIELD_MAIN_IS,
- newMainName );
- rvp.updateDocument( doc );
- pd = PackageDescriptionLoader.load( doc.get() );
- pds = pd.getSameStanza( pds );
- }
- }
- } catch( Exception e ) {
- // Do nothing
- } finally {
- provider.disconnect( cabalF );
- }
- return doc.get();
- }
- public static String newRemoveModuleCabalFile( final IProject project,
- final IFile oldFile ) {
- TextFileDocumentProvider provider = new TextFileDocumentProvider();
- String oldModuleName = getModuleName( oldFile );
- IFile cabalF = ScionInstance.getCabalFile( project );
- PackageDescription pd = null;
- try {
- pd = PackageDescriptionLoader.load( cabalF );
- provider.connect( cabalF );
- } catch( Exception e ) {
- return null;
- }
- IDocument doc = provider.getDocument( cabalF );
- try {
- List<PackageDescriptionStanza> lpds = pd.getStanzas();
- for( PackageDescriptionStanza pds: lpds ) {
- // Should we change this stanza?
- String srcList = pds.getProperties().get(
- CabalSyntax.FIELD_HS_SOURCE_DIRS.getCabalName().toLowerCase() );
- srcList = srcList == null ? "" : srcList;
- List<String> srcs = PackageDescriptionLoader.parseList( srcList );
- final Set<IPath> allowedPaths = getStanzaPaths( project, oldFile );
- boolean shouldBeChanged = false;
- for (String src : srcs) {
- IPath srcPath = Path.fromPortableString( src );
- if (allowedPaths.contains( srcPath )) {
- shouldBeChanged = true;
- break;
- }
- }
- if (!shouldBeChanged) {
- continue; // We should not
- }
- // Modules sections
- CabalSyntax[] elements = new CabalSyntax[] {
- CabalSyntax.FIELD_EXPOSED_MODULES, CabalSyntax.FIELD_OTHER_MODULES };
- for( CabalSyntax element: elements ) {
- pds = pd.getSameStanza( pds );
- String propList = pds.getProperties().get(
- element.getCabalName().toLowerCase() );
- propList = propList == null ? "" : propList;
- List<String> props = PackageDescriptionLoader.parseList( propList );
- if( props.indexOf( oldModuleName ) != -1 ) {
- RealValuePosition rvp = pds.removeFromPropertyList( element,
- oldModuleName );
- rvp.updateDocument( doc );
- pd = PackageDescriptionLoader.load( doc.get() );
- pds = pd.getSameStanza( pds );
- }
- }
- // Main-is section
- String oldMainName = oldModuleName.replace( '.', '/' ) + ".hs";
- pds = pd.getSameStanza( pds );
- String mainProp = pds.getProperties().get(
- CabalSyntax.FIELD_MAIN_IS.getCabalName().toLowerCase() );
- mainProp = mainProp == null ? "" : mainProp;
- if( oldMainName.equals( mainProp ) ) {
- RealValuePosition rvp = pds.update( CabalSyntax.FIELD_MAIN_IS, "" );
- rvp.updateDocument( doc );
- pd = PackageDescriptionLoader.load( doc.get() );
- pds = pd.getSameStanza( pds );
- }
- }
- } catch( Exception e ) {
- // Do nothing
- } finally {
- provider.disconnect( cabalF );
- }
- return doc.get();
- }
- public static String newSourceFolderCabalFile(final IProject project,
- final IPath oldPath, final IPath newPath) {
- TextFileDocumentProvider provider = new TextFileDocumentProvider();
- IFile cabalF = ScionInstance.getCabalFile( project );
- PackageDescription pd = null;
- try {
- pd = PackageDescriptionLoader.load( cabalF );
- provider.connect( cabalF );
- } catch( Exception e ) {
- return null;
- }
- IDocument doc = provider.getDocument( cabalF );
- try {
- List<PackageDescriptionStanza> lpds = pd.getStanzas();
- for( PackageDescriptionStanza pds: lpds ) {
- // Should we change this stanza?
- String srcList = pds.getProperties().get(
- CabalSyntax.FIELD_HS_SOURCE_DIRS.getCabalName().toLowerCase() );
- srcList = srcList == null ? "" : srcList;
- List<String> srcs = PackageDescriptionLoader.parseList( srcList );
- for (String src : srcs) {
- IPath srcPath = Path.fromPortableString( src );
- if (srcPath.equals( oldPath )) {
- RealValuePosition rvp = pds.removeFromPropertyList(
- CabalSyntax.FIELD_HS_SOURCE_DIRS,
- oldPath.toPortableString() );
- rvp.updateDocument( doc );
- pd = PackageDescriptionLoader.load( doc.get() );
- pds = pd.getSameStanza( pds );
- rvp = pds.addToPropertyList(
- CabalSyntax.FIELD_HS_SOURCE_DIRS,
- newPath.toPortableString() );
- rvp.updateDocument( doc );
- pd = PackageDescriptionLoader.load( doc.get() );
- pds = pd.getSameStanza( pds );
- break;
- }
- }
- }
- } catch( Exception e ) {
- // Do nothing
- } finally {
- provider.disconnect( cabalF );
- }
- return doc.get();
- }
- }