package com.redhat.ceylon.eclipse.code.correct; import static com.redhat.ceylon.model.typechecker.model.ModelUtil.isTypeUnknown; import java.util.Collection; import org.eclipse.core.resources.IFile; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.Region; import org.eclipse.jface.text.contentassist.ICompletionProposal; import org.eclipse.ltk.core.refactoring.TextChange; import org.eclipse.ltk.core.refactoring.TextFileChange; import org.eclipse.text.edits.InsertEdit; import org.eclipse.text.edits.MultiTextEdit; import org.eclipse.text.edits.ReplaceEdit; import com.redhat.ceylon.compiler.typechecker.tree.Tree; import com.redhat.ceylon.model.typechecker.model.Declaration; import com.redhat.ceylon.model.typechecker.model.Type; import com.redhat.ceylon.model.typechecker.model.Value; class AssertExistsDeclarationProposal extends CorrectionProposal { private AssertExistsDeclarationProposal(Declaration dec, String existsOrNonempty, int offset, TextChange change) { super("Change to 'assert (" + existsOrNonempty + " " + dec.getName() + ")'", change, new Region(offset, 0)); } private static void addSplitDeclarationProposal(IDocument doc, Tree.AttributeDeclaration decNode, Tree.CompilationUnit cu, IFile file, Collection<ICompletionProposal> proposals) { Value dec = decNode.getDeclarationModel(); Tree.SpecifierOrInitializerExpression sie = decNode.getSpecifierOrInitializerExpression(); if (dec==null || dec.isParameter() || dec.isToplevel() || sie==null || sie.getExpression()==null) { return; } Type siet = sie.getExpression().getTypeModel(); String existsOrNonempty; String desc; if (isTypeUnknown(siet)) { return; } else if (cu.getUnit().isOptionalType(siet)) { existsOrNonempty = "exists"; desc = "Assert Exists"; } else if (cu.getUnit().isPossiblyEmptyType(siet)) { existsOrNonempty = "nonempty"; desc = "Assert Nonempty"; } else { return; } Tree.Identifier id = decNode.getIdentifier(); if (id==null || id.getToken()==null) { return; } // int idStartOffset = id.getStartIndex(); int idEndOffset = id.getEndIndex(); int semiOffset = decNode.getEndIndex()-1; TextChange change = new TextFileChange(desc, file); change.setEdit(new MultiTextEdit()); Tree.Type type = decNode.getType(); Integer typeOffset = type.getStartIndex(); Integer typeLen = type.getDistance(); change.addEdit(new ReplaceEdit(typeOffset, typeLen, "assert (" + existsOrNonempty)); change.addEdit(new InsertEdit(semiOffset, ")")); proposals.add(new AssertExistsDeclarationProposal(dec, existsOrNonempty, idEndOffset + 8 + existsOrNonempty.length() - typeLen, change)); } static void addAssertExistsDeclarationProposals( Collection<ICompletionProposal> proposals, IDocument doc, IFile file, Tree.CompilationUnit cu, Tree.Declaration decNode) { if (decNode==null) return; Declaration dec = decNode.getDeclarationModel(); if (dec!=null) { if (decNode instanceof Tree.AttributeDeclaration) { Tree.AttributeDeclaration attDecNode = (Tree.AttributeDeclaration) decNode; Tree.SpecifierOrInitializerExpression sie = attDecNode.getSpecifierOrInitializerExpression(); if (sie!=null || dec.isParameter()) { addSplitDeclarationProposal(doc, attDecNode, cu, file, proposals); } } } } }