package net.sf.eclipsefp.haskell.ui.internal.resolve;
import net.sf.eclipsefp.haskell.ui.HaskellUIPlugin;
import net.sf.eclipsefp.haskell.ui.internal.util.UITexts;
import net.sf.eclipsefp.haskell.ui.util.HaskellUIImages;
import net.sf.eclipsefp.haskell.ui.util.IImageNames;
import net.sf.eclipsefp.haskell.util.PlatformUtil;
import org.eclipse.core.resources.IMarker;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.contentassist.CompletionProposal;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
/**
* <p>Add type signature</p>
*
* @author JP Moresmau
*/
public class MissingTypeWarningResolution extends MarkerCompletion {
private final String toSearch;
public MissingTypeWarningResolution( final String toSearch ) {
super();
this.toSearch = toSearch;
}
@Override
public String getLabel() {
return UITexts.resolve_missingtype;
}
/**
* extract the proper type from the message
* @param prefix
* @param msg
* @return
*/
public static String extractTypeFromMessage(final String prefix,final String msg){
int ix=msg.toLowerCase().indexOf( prefix);
if (ix>-1){
String type=msg.substring(ix+prefix.length()).trim();
// replace [Char] by String
type=type.replace("[Char]","String");
int ixStartType=type.indexOf( "::" );
if (ixStartType>-1){
StringBuilder sb=new StringBuilder();
String name= type.substring( 0,ixStartType );
// if we're in Main, symbol name gets prefixed with Main.
int lidx=name.lastIndexOf( '.' );
if (lidx>-1){
name=name.substring(lidx+1);
}
sb.append(name );
sb.append("::" );
// for (int a=ixStartType;a<type.length();a++){
// if (Character.isUpperCase( type.charAt( a ) )){
// break;
// } else if (Character.isLowerCase( type.charAt( a ) )){
int start=ixStartType+2;
// package names can appear in signature
int end=type.indexOf( ":",start );
while (end>-1){
// but if we have :: inside, it's a kind signature, maybe?, so we don't truncate
if (type.indexOf( ":",end+1 )!=end+1){
int startPkg1=type.substring(start,end).lastIndexOf( ' ' );
int startPkg2=type.substring(start,end).lastIndexOf( '(' );
int startPkg=Math.max( startPkg1, startPkg2 );
if (startPkg==-1){
startPkg=start;
} else {
startPkg+=start+1;
}
sb.append(type.substring( start,startPkg ));
start=end+1;
} else {
sb.append(type.substring( start,end ));
sb.append("::");
start=end+2;
}
end=type.indexOf( ":",start );
}
sb.append(type.substring( start ));
//type=type.substring( 0,startPkg )+type.substring( end+1,type.length() );
// break;
// }
// }
// }
// if we're in Main, symbol name gets prefixed with Main.
// int lidx=type.substring(0,ixStartType).lastIndexOf( '.' );
// if (lidx>-1){
// type=type.substring(lidx+1);
// }
return sb.toString();
}
return type;
}
return null;
}
@Override
public ICompletionProposal getCompletionProposal( final IMarker marker,final IDocument document){
String msg=marker.getAttribute(IMarker.MESSAGE,""); //$NON-NLS-1$
//String toSearch=GhcMessages.WARNING_INFERREDTYPE_START;
String type=extractTypeFromMessage( toSearch, msg );
if (type!=null){
int line=marker.getAttribute(IMarker.LINE_NUMBER, 0);
try {
final int offset=document.getLineOffset( line-1 );
final String txt=type+PlatformUtil.NL;
final ICompletionProposal comp=new CompletionProposal(getLineStartAddition(txt,marker.getResource()) , offset, 0, txt.length(),HaskellUIImages.getImage( IImageNames.TYPE_SIGNATURE ),getLabel(),null,null );
// we ensure KindSignatures is enabled if we have type *?
// But it could be in Cabal file?
// if (type.contains( "*" )){
// return new ICompletionProposal() {
//
// @Override
// public Point getSelection( final IDocument paramIDocument ) {
// return comp.getSelection( paramIDocument );
// }
//
// @Override
// public Image getImage() {
// return comp.getImage();
// }
//
// @Override
// public String getDisplayString() {
// return comp.getDisplayString();
// }
//
// @Override
// public IContextInformation getContextInformation() {
// return null;
// }
//
// @Override
// public String getAdditionalProposalInfo() {
// return null;
// }
//
// @Override
// public void apply( final IDocument paramIDocument ) {
// comp.apply( paramIDocument );
// ICompletionProposal p=new AddLanguagePragmaResolution( "KindSignatures" ).getCompletionProposal( marker, document );
// if (p!=null){
// p.apply( paramIDocument );
// }
// }
// };
//
//
// }
return comp;
} catch( BadLocationException ex ) {
HaskellUIPlugin.log( ex );
}
}
return null;
}
}