package com.redhat.ceylon.eclipse.code.complete;
import static com.redhat.ceylon.eclipse.code.complete.CodeCompletions.appendParameterContextInfo;
import static com.redhat.ceylon.eclipse.code.complete.CompletionUtil.getParameters;
import static com.redhat.ceylon.eclipse.code.hover.DocumentationHover.getDocumentationFor;
import static com.redhat.ceylon.eclipse.code.outline.CeylonLabelProvider.getImageForDeclaration;
import java.util.Collections;
import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.swt.graphics.Image;
import com.redhat.ceylon.compiler.typechecker.tree.Node;
import com.redhat.ceylon.compiler.typechecker.tree.Tree;
import com.redhat.ceylon.compiler.typechecker.tree.Visitor;
import com.redhat.ceylon.eclipse.code.parse.CeylonParseController;
import com.redhat.ceylon.model.typechecker.model.Declaration;
import com.redhat.ceylon.model.typechecker.model.Functional;
import com.redhat.ceylon.model.typechecker.model.Parameter;
import com.redhat.ceylon.model.typechecker.model.ParameterList;
import com.redhat.ceylon.model.typechecker.model.Reference;
import com.redhat.ceylon.model.typechecker.model.Scope;
import com.redhat.ceylon.model.typechecker.model.Type;
import com.redhat.ceylon.model.typechecker.model.TypedReference;
import com.redhat.ceylon.model.typechecker.model.Unit;
import com.redhat.ceylon.model.typechecker.model.Value;
public class InvocationCompletionProposal extends CompletionProposal {
private static final List<Type> NO_TYPES = Collections.<Type>emptyList();
// @Deprecated
// static void addProgramElementReferenceProposal(
// int offset, String prefix,
// CeylonParseController controller,
// List<ICompletionProposal> result,
// Declaration dec, Scope scope, boolean isMember) {
// Unit unit = controller.getLastCompilationUnit().getUnit();
// result.add(new InvocationCompletionProposal(
// offset, prefix,
// dec.getName(unit), escaping_.get_().escapeName(dec, unit),
// dec, dec.getReference(), scope, controller,
// true, false, false, false, isMember, null));
// }
//
// @Deprecated
// static void addReferenceProposal(
// int offset, String prefix,
// final CeylonParseController controller,
// List<ICompletionProposal> result,
// DeclarationWithProximity dwp,
// Scope scope, boolean isMember,
// Reference pr, OccurrenceLocation ol) {
// Unit unit = controller.getLastCompilationUnit().getUnit();
// Declaration dec = dwp.getDeclaration();
// //proposal with type args
// if (dec instanceof Generic) {
// result.add(new InvocationCompletionProposal(
// offset, prefix,
// getDescriptionFor(dwp, unit, true),
// getTextFor(dec, unit),
// dec, pr, scope, controller,
// true, false, false,
// ol==UPPER_BOUND ||
// ol==EXTENDS ||
// ol==SATISFIES,
// isMember, null));
// Generic g = (Generic) dec;
// if (g.getTypeParameters().isEmpty()) {
// //don't add another proposal below!
// return;
// }
// }
// //proposal without type args
// boolean isAbstract =
// dec instanceof Interface ||
// dec instanceof Class &&
// ((Class) dec).isAbstract();
// if ((!isAbstract &&
// ol!=EXTENDS && ol!=SATISFIES && ol!=UPPER_BOUND ||
// ol!=CLASS_ALIAS && ol!=TYPE_ALIAS)) {
// result.add(new InvocationCompletionProposal(
// offset, prefix,
// getDescriptionFor(dwp, unit, false),
// escaping_.get_().escapeName(dec, unit),
// dec, pr, scope, controller,
// true, false, false, false,
// isMember, null));
// }
// }
//
// @Deprecated
// static void addSecondLevelProposal(
// int offset, String prefix,
// CeylonParseController controller,
// List<ICompletionProposal> result,
// Declaration dec, Scope scope,
// boolean isMember, Reference pr,
// Type requiredType, OccurrenceLocation ol) {
// Unit unit =
// controller.getLastCompilationUnit()
// .getUnit();
// Type type = pr.getType();
// if (type!=null) {
// if (!(dec instanceof Functional) &&
// !(dec instanceof TypeDeclaration)) {
// //add qualified member proposals
// Collection<DeclarationWithProximity> members =
// type.getDeclaration()
// .getMatchingMemberDeclarations(
// unit, scope, "", 0)
// .values();
// for (DeclarationWithProximity ndwp: members) {
// Declaration m = ndwp.getDeclaration();
// if ((m instanceof FunctionOrValue ||
// m instanceof Class) &&
// !isConstructor(m)) {
// if (m.isAbstraction()) {
// for (Declaration o:
// m.getOverloads()) {
// addSecondLevelProposal(
// offset, prefix,
// controller, result, dec,
// scope, requiredType, ol,
// unit, type, ndwp, o);
// }
// }
// else {
// addSecondLevelProposal(
// offset, prefix,
// controller, result, dec,
// scope, requiredType, ol,
// unit, type, ndwp, m);
// }
// }
// }
// }
// if (dec instanceof Class) {
// //add constructor proposals
// List<Declaration> members =
// type.getDeclaration()
// .getMembers();
// for (Declaration m: members) {
// if (m instanceof FunctionOrValue &&
// isConstructor(m) &&
// m.isShared() &&
// m.getName()!=null) {
// addSecondLevelProposal(
// offset, prefix,
// controller, result, dec,
// scope, requiredType, ol,
// unit, type, null, m);
// }
// }
// }
// }
// }
//
// @Deprecated
// private static void addSecondLevelProposal(
// int offset, String prefix,
// CeylonParseController controller,
// List<ICompletionProposal> result,
// Declaration dec, Scope scope,
// Type requiredType, OccurrenceLocation ol,
// Unit unit, Type type,
// DeclarationWithProximity mwp,
// // sometimes we have no mwp so we also need the m
// Declaration m) {
// Reference ptr = type.getTypedReference(m, NO_TYPES);
// Type mt = ptr.getType();
// if (mt!=null &&
// (requiredType==null ||
// withinBounds(requiredType, mt, scope) ||
// dec instanceof Class &&
// dec.equals(requiredType.getDeclaration()))) {
// String qualifier = dec.getName() + ".";
// String desc =
// qualifier +
// getPositionalInvocationDescriptionFor(
// mwp, m, ol, ptr, unit, false, null);
// String text =
// qualifier +
// getPositionalInvocationTextFor(
// m, ol, ptr, unit, false, null);
// result.add(new InvocationCompletionProposal(
// offset, prefix, desc, text, m, ptr, scope,
// controller, true, true, false,
// ol==UPPER_BOUND ||
// ol==EXTENDS ||
// ol==SATISFIES,
// true, dec));
// }
// }
//
// @Deprecated
// static void addInvocationProposals(
// int offset, String prefix,
// CeylonParseController controller,
// List<ICompletionProposal> result,
// DeclarationWithProximity dwp,
// // sometimes we have no dwp, just a dec, so we have to handle that too
// Declaration dec,
// Reference pr,
// Scope scope, OccurrenceLocation ol,
// String typeArgs, boolean isMember) {
// if (dec instanceof Functional) {
// Unit unit =
// controller.getLastCompilationUnit()
// .getUnit();
// boolean isAbstract =
// dec instanceof TypeDeclaration &&
// ((TypeDeclaration) dec).isAbstract();
// Functional fd = (Functional) dec;
// List<ParameterList> pls = fd.getParameterLists();
// if (!pls.isEmpty()) {
// ParameterList parameterList = pls.get(0);
// List<Parameter> ps =
// parameterList.getParameters();
// String inexactMatches =
// getPreferences()
// .getString(INEXACT_MATCHES);
// boolean exact =
// prefixWithoutTypeArgs(prefix, typeArgs)
// .equalsIgnoreCase(dec.getName(unit));
// boolean positional =
// exact ||
// "both".equals(inexactMatches) ||
// "positional".equals(inexactMatches);
// boolean named =
// exact ||
// "both".equals(inexactMatches);
// boolean inheritance =
// ol==UPPER_BOUND ||
// ol==EXTENDS ||
// ol==SATISFIES;
// if (positional &&
// parameterList.isPositionalParametersSupported() &&
// (!isAbstract ||
// ol==EXTENDS || ol==CLASS_ALIAS)) {
// List<Parameter> parameters =
// getParameters(parameterList,
// false, false);
// if (ps.size()!=parameters.size()) {
// String desc =
// getPositionalInvocationDescriptionFor(
// dwp, dec, ol, pr, unit, false,
// typeArgs);
// String text =
// getPositionalInvocationTextFor(
// dec, ol, pr, unit, false,
// typeArgs);
// result.add(new InvocationCompletionProposal(
// offset, prefix, desc, text, dec, pr, scope,
// controller, false, true, false,
// inheritance, isMember, null));
// }
// String desc =
// getPositionalInvocationDescriptionFor(
// dwp, dec, ol, pr, unit, true,
// typeArgs);
// String text =
// getPositionalInvocationTextFor(
// dec, ol, pr, unit, true,
// typeArgs);
// result.add(new InvocationCompletionProposal(
// offset, prefix, desc, text, dec, pr, scope,
// controller, true, true, false,
// inheritance, isMember, null));
// }
// if (named &&
// parameterList.isNamedParametersSupported() &&
// (!isAbstract &&
// ol!=EXTENDS && ol!=CLASS_ALIAS &&
// !dec.isOverloaded())) {
// //if there is at least one parameter,
// //suggest a named argument invocation
// List<Parameter> parameters =
// getParameters(parameterList, false, true);
// if (ps.size()!=parameters.size()) {
// String desc =
// getNamedInvocationDescriptionFor(
// dec, pr, unit, false,
// typeArgs);
// String text =
// getNamedInvocationTextFor(
// dec, pr, unit, false,
// typeArgs);
// result.add(new InvocationCompletionProposal(
// offset, prefix, desc, text, dec, pr, scope,
// controller, false, false, true,
// inheritance, isMember, null));
// }
// if (!ps.isEmpty()) {
// String desc =
// getNamedInvocationDescriptionFor(
// dec, pr, unit, true,
// typeArgs);
// String text =
// getNamedInvocationTextFor(
// dec, pr, unit, true,
// typeArgs);
// result.add(new InvocationCompletionProposal(
// offset, prefix, desc, text, dec, pr, scope,
// controller, true, false, true,
// inheritance, isMember, null));
// }
// }
// }
// }
// }
private static String prefixWithoutTypeArgs(
String prefix, String typeArgs) {
if (typeArgs==null) {
return prefix;
}
else {
return prefix.substring(0,
prefix.length()-typeArgs.length());
}
}
// @Deprecated
// final class NestedCompletionProposal
// implements ICompletionProposal,
// ICompletionProposalExtension2,
// ICompletionProposalExtension6 {
// private final String op;
// private final int loc;
// private final int index;
// private final boolean basic;
// private final Declaration dec;
// private Declaration qualifier;
//
// NestedCompletionProposal(
// Declaration dec, Declaration qualifier,
// int loc, int index, boolean basic,
// String op) {
// this.qualifier = qualifier;
// this.op = op;
// this.loc = loc;
// this.index = index;
// this.basic = basic;
// this.dec = dec;
// }
//
// public String getAdditionalProposalInfo() {
// return null;
// }
//
// @Override
// public void apply(IDocument document) {
// //the following awfulness is necessary because the
// //insertion point may have changed (and even its
// //text may have changed, since the proposal was
// //instantiated).
// try {
// IRegion region =
// getCurrentArgumentRegion(document,
// loc, index,
// getFirstPosition());
// String str = getText(false);
// int start = region.getOffset();
// int len = region.getLength();
// int end = start + len;
// if (document.getChar(end)=='}') {
// str += " ";
// }
// document.replace(start, len, str);
// }
// catch (BadLocationException e) {
// e.printStackTrace();
// }
// //adding imports drops us out of linked mode :(
// //not needed anyway because we never propose
// //unimported stuff, so no big deal
// /*try {
// DocumentChange tc =
// new DocumentChange("imports", document);
// tc.setEdit(new MultiTextEdit());
// HashSet<Declaration> decs =
// new HashSet<Declaration>();
// Tree.CompilationUnit cu = cpc.getRootNode();
// importDeclaration(decs, dec, cu);
// if (dec instanceof Functional) {
// List<ParameterList> pls =
// ((Functional) dec).getParameterLists();
// if (!pls.isEmpty()) {
// for (Parameter p: pls.get(0).getParameters()) {
// FunctionOrValue pm = p.getModel();
// if (pm instanceof Function) {
// for (ParameterList ppl:
// ((Function) pm).getParameterLists()) {
// for (Parameter pp: ppl.getParameters()) {
// importSignatureTypes(pp.getModel(), cu, decs);
// }
// }
// }
// }
// }
//
// }
// applyImports(tc, decs, cu, document);
// EditorUtil.performChange(tc);
// }
// catch (Exception e) {
// e.printStackTrace();
// }*/
// }
//
// private String getText(boolean description) {
// StringBuilder sb = new StringBuilder(op);
// Unit unit = getUnit();
// sb.append(getProposedName(qualifier, dec, unit));
// if (dec instanceof Functional && !basic) {
// appendPositionalArgs(dec, unit, sb, false,
// description);
// }
// return sb.toString();
// }
//
// @Override
// public Point getSelection(IDocument document) {
// return null;
// }
//
// @Override
// public String getDisplayString() {
// return getText(true);
// }
//
// @Override
// public StyledString getStyledDisplayString() {
// StyledString result = new StyledString();
// Highlights.styleFragment(result,
// getDisplayString(), false, null,
// getCompletionFont());
// return result;
// }
//
// @Override
// public Image getImage() {
// return getImageForDeclaration(dec);
// }
//
// @Override
// public IContextInformation getContextInformation() {
// return null;
// }
//
// @Override
// public void apply(ITextViewer viewer, char trigger,
// int stateMask, int offset) {
// apply(viewer.getDocument());
// }
//
// @Override
// public void selected(ITextViewer viewer, boolean smartToggle) {}
//
// @Override
// public void unselected(ITextViewer viewer) {}
//
// @Override
// public boolean validate(IDocument document,
// int currentOffset, DocumentEvent event) {
// if (event==null) {
// return true;
// }
// else {
// try {
// IRegion region =
// getCurrentArgumentRegion(document,
// loc, index,
// getFirstPosition());
// String content =
// document.get(region.getOffset(),
// currentOffset-region.getOffset());
// return isContentValid(content);
// }
// catch (BadLocationException e) {
// // ignore concurrently modified document
// return false;
// }
// }
// }
//
// private boolean isContentValid(String content) {
// int fat = content.indexOf("=>");
// if (fat>0) {
// content = content.substring(fat+2);
// }
// int eq = content.indexOf("=");
// if (eq>0) {
// content = content.substring(eq+1);
// }
// if (content.startsWith(op)) {
// content = content.substring(op.length());
// }
// String filter = content.trim().toLowerCase();
// return ModelUtil.isNameMatching(content, dec) ||
// getProposedName(qualifier, dec, getUnit())
// .toLowerCase()
// .startsWith(filter);
// }
// }
//
// @Deprecated
// final class NestedLiteralCompletionProposal
// implements ICompletionProposal,
// ICompletionProposalExtension2,
// ICompletionProposalExtension6 {
//
// private final int loc;
// private final int index;
// private final String value;
//
// NestedLiteralCompletionProposal(String value, int loc,
// int index) {
// this.value = value;
// this.loc = loc;
// this.index = index;
// }
//
// public String getAdditionalProposalInfo() {
// return null;
// }
//
// @Override
// public void apply(IDocument document) {
// //the following awfulness is necessary because the
// //insertion point may have changed (and even its
// //text may have changed, since the proposal was
// //instantiated).
// try {
// IRegion region =
// getCurrentArgumentRegion(document,
// loc, index,
// getFirstPosition());
// String str = value;
// int start = region.getOffset();
// int len = region.getLength();
// int end = start + len;
// if (document.getChar(end)=='}') {
// str += " ";
// }
// document.replace(start, len, str);
// }
// catch (BadLocationException e) {
// e.printStackTrace();
// }
// }
//
//
// @Override
// public Point getSelection(IDocument document) {
// return null;
// }
//
// @Override
// public String getDisplayString() {
// return value;
// }
//
//
// @Override
// public StyledString getStyledDisplayString() {
// StyledString result = new StyledString();
// Highlights.styleFragment(result,
// getDisplayString(), false, null,
// getCompletionFont());
// return result;
// }
//
// @Override
// public Image getImage() {
// return getDecoratedImage(CEYLON_LITERAL, 0, false);
// }
//
// @Override
// public IContextInformation getContextInformation() {
// return null;
// }
//
// @Override
// public void apply(ITextViewer viewer, char trigger,
// int stateMask, int offset) {
// apply(viewer.getDocument());
// }
//
// @Override
// public void selected(ITextViewer viewer, boolean smartToggle) {}
//
// @Override
// public void unselected(ITextViewer viewer) {}
//
// @Override
// public boolean validate(IDocument document,
// int currentOffset, DocumentEvent event) {
// if (event==null) {
// return true;
// }
// else {
// try {
// IRegion region =
// getCurrentArgumentRegion(document,
// loc, index,
// getFirstPosition());
// String content =
// document.get(region.getOffset(),
// currentOffset-region.getOffset());
// int eq = content.indexOf("=");
// if (eq>0) {
// content = content.substring(eq+1);
// }
// String filter = content.trim().toLowerCase();
// if (value.toLowerCase().startsWith(filter)) {
// return true;
// }
// }
// catch (BadLocationException e) {
// // ignore concurrently modified document
// }
// return false;
// }
// }
// }
private final CeylonParseController cpc;
private final Declaration declaration;
private final Reference producedReference;
private final Scope scope;
private final boolean includeDefaulted;
private final boolean namedInvocation;
private final boolean positionalInvocation;
private final boolean qualified;
private Declaration qualifyingValue;
private boolean inheritance;
@Deprecated
InvocationCompletionProposal(
int offset, String prefix,
String desc, String text,
Declaration dec,
Reference producedReference,
Scope scope,
CeylonParseController controller,
boolean includeDefaulted,
boolean positionalInvocation,
boolean namedInvocation,
boolean inheritance,
boolean qualified,
Declaration qualifyingValue) {
super(offset, prefix, new CompletionProposal.DeclarationImageRetriever(dec),
desc, text);
this.cpc = controller;
this.declaration = dec;
this.producedReference = producedReference;
this.scope = scope;
this.includeDefaulted = includeDefaulted;
this.namedInvocation = namedInvocation;
this.positionalInvocation = positionalInvocation;
this.inheritance = inheritance;
this.qualified = qualified;
this.qualifyingValue = qualifyingValue;
}
//
// @Deprecated
// protected boolean isProposalMatching(String currentPrefix, String text){
// if(super.isProposalMatching(currentPrefix, text))
// return true;
// for(String alias : declaration.getAliases()){
// if(ModelUtil.isNameMatching(currentPrefix, alias))
// return true;
// }
// return false;
// }
private Unit getUnit() {
return cpc.getLastCompilationUnit().getUnit();
}
// @Deprecated
// private DocumentChange createChange(IDocument document)
// throws BadLocationException {
// DocumentChange change =
// new DocumentChange("Complete Invocation",
// document);
// change.setEdit(new MultiTextEdit());
// HashSet<Declaration> decs =
// new HashSet<Declaration>();
// Tree.CompilationUnit cu = cpc.getLastCompilationUnit();
// if (qualifyingValue!=null) {
// importProposals().importDeclaration(decs, qualifyingValue, cu);
// }
// if (!qualified) {
// importProposals().importDeclaration(decs, declaration, cu);
// }
// if (positionalInvocation||namedInvocation) {
// importProposals().importCallableParameterParamTypes(declaration,
// decs, cu);
// }
// int il= (int) importProposals().applyImports(change, decs, cu, document);
// change.addEdit(createEdit(document));
// offset+=il;
// return change;
// }
// @Override
// public void apply(IDocument document) {
// try {
// performChange(createChange(document));
// }
// catch (BadLocationException e) {
// e.printStackTrace();
// }
// if (getPreferences()
// .getBoolean(LINKED_MODE_ARGUMENTS)) {
// activeLinkedMode(document);
// }
// }
// @Deprecated
// private void activeLinkedMode(IDocument document) {
// if (declaration instanceof Generic) {
// Generic generic = (Generic) declaration;
// ParameterList paramList = null;
// if (declaration instanceof Functional &&
// (positionalInvocation || namedInvocation)) {
// Functional fd = (Functional) declaration;
// List<ParameterList> pls =
// fd.getParameterLists();
// if (!pls.isEmpty() &&
// !pls.get(0).getParameters()
// .isEmpty()) {
// paramList = pls.get(0);
// }
// }
// if (paramList!=null) {
// List<Parameter> params =
// getParameters(paramList,
// includeDefaulted,
// namedInvocation);
// if (!params.isEmpty()) {
// enterLinkedMode(document, params, null);
// return; //NOTE: early exit!
// }
// }
// List<TypeParameter> typeParams =
// generic.getTypeParameters();
// if (!typeParams.isEmpty()) {
// enterLinkedMode(document, null, typeParams);
// }
// }
// }
// @Override
// public Point getSelection(IDocument document) {
// int first = getFirstPosition();
// if (first<=0) {
// //no arg list
// return super.getSelection(document);
// }
// int next = getNextPosition(document, first);
// if (next<=0) {
// //an empty arg list
// return super.getSelection(document);
// }
// int middle = getCompletionPosition(first, next);
// int start = offset-prefix.length()+first+middle;
// int len = next-middle;
// try {
// if (document.get(start, len).trim()
// .equals("{}")) {
// start++;
// len=0;
// }
// } catch (BadLocationException e) {}
// return new Point(start, len);
// }
// @Deprecated
// protected int getCompletionPosition(int first, int next) {
// return text.substring(first, first+next-1)
// .lastIndexOf(' ') + 1;
// }
//
// @Deprecated
// protected int getFirstPosition() {
// int index;
// if (namedInvocation) {
// index = text.indexOf('{');
// }
// else if (positionalInvocation) {
// index = text.indexOf('(');
// }
// else {
// index = text.indexOf('<');
// }
// return index+1;
// }
//
// @Deprecated
// public int getNextPosition(IDocument document,
// int lastOffset) {
// int loc = offset-prefix.length();
// int comma = -1;
// try {
// int start = loc+lastOffset;
// int end = loc+text.length()-1;
// if (text.endsWith(";")) {
// end--;
// }
// comma =
// findCharCount(1, document,
// start, end,
// ",;", "", true)
// - start;
// }
// catch (BadLocationException e) {
// e.printStackTrace();
// }
// if (comma<0) {
// int index;
// if (namedInvocation) {
// index = text.lastIndexOf('}');
// }
// else if (positionalInvocation) {
// index = text.lastIndexOf(')');
// }
// else {
// index = text.lastIndexOf('>');
// }
// return index - lastOffset;
// }
// return comma;
// }
//
// @Deprecated
// public String getAdditionalProposalInfo() {
// return getAdditionalProposalInfo(null);
// }
public String getAdditionalProposalInfo(IProgressMonitor monitor) {
return getDocumentationFor(cpc, declaration,
producedReference, monitor);
}
// @Deprecated
// public void enterLinkedMode(IDocument document,
// List<Parameter> params,
// List<TypeParameter> typeParams) {
// boolean proposeTypeArguments = params==null;
// int paramCount =
// proposeTypeArguments ?
// typeParams.size() :
// params.size();
// if (paramCount==0) return;
// try {
// final int loc = offset-prefix.length();
// int first = getFirstPosition();
// if (first<=0) return; //no arg list
// int next = getNextPosition(document, first);
// if (next<=0) return; //empty arg list
// LinkedModeModel linkedModeModel =
// new LinkedModeModel();
// int seq=0, param=0;
// while (next>0 && param<paramCount) {
// boolean voidParam =
// !proposeTypeArguments &&
// params.get(param).isDeclaredVoid();
// if (proposeTypeArguments ||
// positionalInvocation ||
// //don't create linked positions for
// //void callable parameters in named
// //argument lists
// !voidParam) {
// List<ICompletionProposal> props =
// new ArrayList<ICompletionProposal>();
// if (proposeTypeArguments) {
// addTypeArgumentProposals(
// typeParams.get(seq),
// loc, first, props, seq);
// }
// else if (!voidParam) {
// addValueArgumentProposals(
// params.get(param),
// loc, first, props, seq,
// param==params.size()-1);
// }
// int middle =
// getCompletionPosition(first, next);
// int start = loc+first+middle;
// int len = next-middle;
// if (voidParam) {
// start++;
// len=0;
// }
// ProposalPosition linkedPosition =
// new ProposalPosition(
// document, start, len, seq,
// props.toArray(NO_COMPLETIONS));
// addLinkedPosition(linkedModeModel, linkedPosition);
// first = first+next+1;
// next = getNextPosition(document, first);
// seq++;
// }
// param++;
// }
// if (seq>0) {
// CeylonEditor editor =
// (CeylonEditor)
// getCurrentEditor();
// installLinkedMode(editor,
// document, linkedModeModel, this,
// new LinkedMode.NullExitPolicy(),
// seq, loc+text.length());
// }
//
// }
// catch (Exception e) {
// e.printStackTrace();
// }
// }
//
// @Deprecated
// private void addValueArgumentProposals(
// Parameter param, int loc, int first,
// List<ICompletionProposal> props,
// int index, boolean last) {
// if (param.getModel().isDynamicallyTyped()) {
// return;
// }
// Type type =
// producedReference.getTypedParameter(param)
// .getType();
// if (type==null) {
// return;
// }
// Unit unit = getUnit();
// String exactName = param.getName();
// List<DeclarationWithProximity> proposals =
// getSortedProposedValues(scope, unit,
// exactName);
// //very special case for print()
// String dname = declaration.getQualifiedNameString();
// boolean print = "ceylon.language::print".equals(dname);
// if (print) {
// for (String value: getAssignableLiterals(
// unit.getStringType(), unit)) {
// props.add(new NestedLiteralCompletionProposal(
// value, loc, index));
// }
// }
// //stuff defined in the same block, along with
// //stuff with fuzzily-matching name
// for (DeclarationWithProximity dwp: proposals) {
// if (dwp.getProximity()<=1) {
// addValueArgumentProposal(param, loc, props,
// index, last, type, unit, dwp, null);
// }
// }
// //this
// ClassOrInterface ci =
// getContainingClassOrInterface(scope);
// if (ci!=null) {
// if (ci.getType().isSubtypeOf(type)) {
// props.add(new NestedLiteralCompletionProposal(
// "this", loc, index));
// }
// }
// //literals
// if (!print) {
// for (String value: getAssignableLiterals(type, unit)) {
// props.add(new NestedLiteralCompletionProposal(
// value, loc, index));
// }
// }
// //stuff with lower proximity
// for (DeclarationWithProximity dwp: proposals) {
// if (dwp.getProximity()>1) {
// addValueArgumentProposal(param, loc, props,
// index, last, type, unit, dwp, null);
// }
// }
// }
//
// @Deprecated
// private void addValueArgumentProposal(
// Parameter p, int loc,
// List<ICompletionProposal> props,
// int index, boolean last,
// Type type, Unit unit,
// DeclarationWithProximity dwp,
// DeclarationWithProximity qualifier) {
// if (qualifier==null && dwp.isUnimported()) {
// return;
// }
// Declaration d = dwp.getDeclaration();
// if (d instanceof NothingType) {
// return;
// }
// String pname =
// d.getUnit().getPackage()
// .getNameAsString();
// boolean isInLanguageModule =
// qualifier==null &&
// pname.equals(Module.LANGUAGE_MODULE_NAME);
// Declaration qdec =
// qualifier==null ? null :
// qualifier.getDeclaration();
// if (d instanceof Value) {
// Value value = (Value) d;
// if (isInLanguageModule &&
// isIgnoredLanguageModuleValue(value)) {
// return;
// }
// Type vt = value.getType();
// if (vt!=null && !vt.isNothing()) {
// if (withinBounds(type, vt, scope)) {
// boolean isIterArg =
// namedInvocation && last &&
// unit.isIterableParameterType(type);
// boolean isVarArg =
// p.isSequenced() &&
// positionalInvocation;
// String op =
// isIterArg || isVarArg ?
// "*" : "";
// props.add(new NestedCompletionProposal(
// d, qdec, loc, index, false, op));
// }
// if (qualifier==null &&
// getPreferences()
// .getBoolean(CHAIN_LINKED_MODE_ARGUMENTS)) {
// Collection<DeclarationWithProximity> members =
// value.getTypeDeclaration()
// .getMatchingMemberDeclarations(
// unit, scope, "", 0)
// .values();
// for (DeclarationWithProximity mwp: members) {
// addValueArgumentProposal(p, loc, props,
// index, last, type, unit, mwp, dwp);
// }
// }
// }
// }
// if (d instanceof Function) {
// if (!d.isAnnotation()) {
// Function method = (Function) d;
// if (isInLanguageModule &&
// isIgnoredLanguageModuleMethod(method)) {
// return;
// }
// Type mt = method.getType();
// if (mt!=null && !mt.isNothing() &&
// withinBounds(type, mt, scope)) {
// boolean isIterArg =
// namedInvocation && last &&
// unit.isIterableParameterType(type);
// boolean isVarArg =
// p.isSequenced() &&
// positionalInvocation;
// String op =
// isIterArg || isVarArg ?
// "*" : "";
// props.add(new NestedCompletionProposal(
// d, qdec, loc, index, false, op));
// }
// }
// }
// if (d instanceof Class) {
// Class clazz = (Class) d;
// if (!clazz.isAbstract() && !d.isAnnotation()) {
// if (isInLanguageModule &&
// isIgnoredLanguageModuleClass(clazz)) {
// return;
// }
// Type ct = clazz.getType();
// if (ct!=null &&
// (withinBounds(type, ct, scope) ||
// clazz.equals(type.getDeclaration()))) {
// boolean isIterArg =
// namedInvocation && last &&
// unit.isIterableParameterType(type);
// boolean isVarArg =
// p.isSequenced() &&
// positionalInvocation;
// String op =
// isIterArg || isVarArg ?
// "*" : "";
// if (clazz.getParameterList()!=null) {
// props.add(new NestedCompletionProposal(
// d, qdec, loc, index, false, op));
// }
// for (Declaration m: clazz.getMembers()) {
// if (m instanceof FunctionOrValue &&
// isConstructor(m) &&
// m.isShared() &&
// m.getName()!=null) {
// props.add(new NestedCompletionProposal(
// m, d, loc, index, false, op));
// }
// }
// }
// }
// }
// }
//
// @Deprecated
// private void addTypeArgumentProposals(
// TypeParameter tp,
// final int loc, int first,
// List<ICompletionProposal> props,
// final int index) {
// Unit unit = getUnit();
// Class ed = unit.getExceptionDeclaration();
// for (DeclarationWithProximity dwp:
// getSortedProposedValues(scope, unit, null)) {
// Declaration dec = dwp.getDeclaration();
// if (dec instanceof TypeDeclaration &&
// !dwp.isUnimported()) {
// TypeDeclaration td = (TypeDeclaration) dec;
// Type t = td.getType();
// if (!t.isNothing() &&
// td.getTypeParameters().isEmpty() &&
// !td.isAnnotation() &&
// !td.inherits(ed)) {
// String pname =
// td.getUnit()
// .getPackage()
// .getNameAsString();
// if (pname.equals(Module.LANGUAGE_MODULE_NAME)) {
// if (isIgnoredLanguageModuleType(td)) {
// continue;
// }
// }
// if (inheritance && tp.isSelfType() ?
// scope.equals(td) :
// isInBounds(tp.getSatisfiedTypes(), t)) {
// props.add(new NestedCompletionProposal(
// dec, null, loc, index, true, ""));
// }
// }
// }
// }
// }
@Override
public IContextInformation getContextInformation() {
if (namedInvocation || positionalInvocation) { //TODO: context info for type arg lists!
if (declaration instanceof Functional) {
Functional fd = (Functional) declaration;
List<ParameterList> pls =
fd.getParameterLists();
if (!pls.isEmpty()) {
int argListOffset =
isParameterInfo() ?
this.offset :
offset-prefix.length() +
text.indexOf(namedInvocation?'{':'(');
return new ParameterContextInformation(
declaration, producedReference,
getUnit(), pls.get(0),
argListOffset,
includeDefaulted,
namedInvocation);
}
}
}
return null;
}
boolean isParameterInfo() {
return false;
}
static void addFakeShowParametersCompletion(final Node node,
final CeylonParseController cpc,
final List<ICompletionProposal> result) {
Tree.CompilationUnit upToDateAndTypeChecked =
cpc.getTypecheckedRootNode();
if (upToDateAndTypeChecked == null) {
return;
}
new Visitor() {
@Override
public void visit(Tree.InvocationExpression that) {
Tree.ArgumentList al =
that.getPositionalArgumentList();
if (al==null) {
al = that.getNamedArgumentList();
}
if (al!=null) {
Integer startIndex = al.getStartIndex();
Integer startIndex2 = node.getStartIndex();
if (startIndex!=null && startIndex2!=null &&
startIndex.intValue()==startIndex2.intValue()) {
Tree.Primary primary = that.getPrimary();
if (primary instanceof Tree.MemberOrTypeExpression) {
Tree.MemberOrTypeExpression mte =
(Tree.MemberOrTypeExpression)
primary;
if (mte.getDeclaration()!=null &&
mte.getTarget()!=null) {
result.add(new ParameterInfo(
al.getStartIndex(),
mte.getDeclaration(),
mte.getTarget(),
node.getScope(), cpc,
al instanceof Tree.NamedArgumentList));
}
}
}
}
super.visit(that);
}
}.visit(upToDateAndTypeChecked);
}
}