<commit_before>package com.redhat.ceylon.eclipse.code.complete;

import static com.redhat.ceylon.compiler.typechecker.tree.Util.formatPath;
import static com.redhat.ceylon.eclipse.code.complete.CompletionUtil.fullPath;
import static com.redhat.ceylon.eclipse.code.hover.DocumentationHover.getDocumentationFor;
import static com.redhat.ceylon.eclipse.code.hover.DocumentationHover.getDocumentationForModule;
import static com.redhat.ceylon.eclipse.core.builder.CeylonBuilder.getPackageName;
import static com.redhat.ceylon.eclipse.ui.CeylonResources.MODULE;
import static com.redhat.ceylon.eclipse.util.ModuleQueries.getModuleSearchResults;

import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.swt.graphics.Point;

import com.redhat.ceylon.cmr.api.JDKUtils;
import com.redhat.ceylon.cmr.api.ModuleSearchResult.ModuleDetails;
import com.redhat.ceylon.cmr.api.ModuleVersionDetails;
import com.redhat.ceylon.compiler.typechecker.TypeChecker;
import com.redhat.ceylon.compiler.typechecker.model.Module;
import com.redhat.ceylon.compiler.typechecker.tree.Node;
import com.redhat.ceylon.compiler.typechecker.tree.Tree;
import com.redhat.ceylon.eclipse.code.parse.CeylonParseController;

public class ModuleCompletions {
    
    static final class ModuleDescriptorProposal extends CompletionProposal {
        
        ModuleDescriptorProposal(int offset, String prefix, String moduleName) {
            super(offset, prefix, MODULE, 
                    "module " + moduleName,
                    "module " + moduleName + " \"1.0.0\" {}");
        }

        @Override
        public Point getSelection(IDocument document) {
            return new Point(offset - prefix.length() + text.indexOf('\"')+1, 5);
        }
        
        @Override
        protected boolean qualifiedNameIsPath() {
            return true;
        }
    }

    static final class ModuleProposal extends CompletionProposal {
        private final int len;
        private final String versioned;
        private final ModuleDetails module;
        private final boolean withBody;
        private final ModuleVersionDetails version;
        private final String name;

        ModuleProposal(int offset, String prefix, int len, 
                String versioned, ModuleDetails module,
                boolean withBody, ModuleVersionDetails version, 
                String name) {
            super(offset, prefix, MODULE, versioned, 
                    versioned.substring(len));
            this.len = len;
            this.versioned = versioned;
            this.module = module;
            this.withBody = withBody;
            this.version = version;
            this.name = name;
        }

        @Override
        public Point getSelection(IDocument document) {
            final int off = offset+versioned.length()-prefix.length()-len;
            if (withBody) {
                final int verlen = version.getVersion().length();
                return new Point(off-verlen-2, verlen);
            }
            else {
                return new Point(off, 0);
            }
        }

        @Override
        public String getAdditionalProposalInfo() {<commit_msg>linked mode proposals for imported module version #643<commit_after>package com.redhat.ceylon.eclipse.code.complete;

import static com.redhat.ceylon.compiler.typechecker.tree.Util.formatPath;
import static com.redhat.ceylon.eclipse.code.complete.CeylonCompletionProcessor.NO_COMPLETIONS;
import static com.redhat.ceylon.eclipse.code.complete.CompletionUtil.fullPath;
import static com.redhat.ceylon.eclipse.code.editor.CeylonSourceViewerConfiguration.LINKED_MODE;
import static com.redhat.ceylon.eclipse.code.hover.DocumentationHover.getDocumentationFor;
import static com.redhat.ceylon.eclipse.code.hover.DocumentationHover.getDocumentationForModule;
import static com.redhat.ceylon.eclipse.core.builder.CeylonBuilder.getPackageName;
import static com.redhat.ceylon.eclipse.ui.CeylonResources.MODULE;
import static com.redhat.ceylon.eclipse.util.ModuleQueries.getModuleSearchResults;

import java.util.ArrayList;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.text.link.ILinkedModeListener;
import org.eclipse.jface.text.link.LinkedModeModel;
import org.eclipse.jface.text.link.ProposalPosition;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.ui.editors.text.EditorsUI;

import com.redhat.ceylon.cmr.api.JDKUtils;
import com.redhat.ceylon.cmr.api.ModuleSearchResult.ModuleDetails;
import com.redhat.ceylon.cmr.api.ModuleVersionDetails;
import com.redhat.ceylon.compiler.typechecker.TypeChecker;
import com.redhat.ceylon.compiler.typechecker.model.Module;
import com.redhat.ceylon.compiler.typechecker.tree.Node;
import com.redhat.ceylon.compiler.typechecker.tree.Tree;
import com.redhat.ceylon.eclipse.code.editor.CeylonEditor;
import com.redhat.ceylon.eclipse.code.parse.CeylonParseController;
import com.redhat.ceylon.eclipse.ui.CeylonResources;
import com.redhat.ceylon.eclipse.util.EditorUtil;
import com.redhat.ceylon.eclipse.util.LinkedMode;

public class ModuleCompletions {
    
    static final class ModuleDescriptorProposal extends CompletionProposal {
        
        ModuleDescriptorProposal(int offset, String prefix, String moduleName) {
            super(offset, prefix, MODULE, 
                    "module " + moduleName,
                    "module " + moduleName + " \"1.0.0\" {}");
        }

        @Override
        public Point getSelection(IDocument document) {
            return new Point(offset - prefix.length() + text.indexOf('\"')+1, 5);
        }
        
        @Override
        protected boolean qualifiedNameIsPath() {
            return true;
        }
    }

    static final class ModuleProposal extends CompletionProposal {
        private final int len;
        private final String versioned;
        private final ModuleDetails module;
        private final boolean withBody;
        private final ModuleVersionDetails version;
        private final String name;

        ModuleProposal(int offset, String prefix, int len, 
                String versioned, ModuleDetails module,
                boolean withBody, ModuleVersionDetails version, 
                String name) {
            super(offset, prefix, MODULE, versioned, 
                    versioned.substring(len));
            this.len = len;
            this.versioned = versioned;
            this.module = module;
            this.withBody = withBody;
            this.version = version;
            this.name = name;
        }

        @Override
        public Point getSelection(IDocument document) {
            final int off = offset+versioned.length()-prefix.length()-len;
            if (withBody) {
                final int verlen = version.getVersion().length();
                return new Point(off-verlen-2, verlen);
            }
            else {
                return new Point(off, 0);
            }
        }

        @Override
        public void apply(IDocument document) {
            super.apply(document);
            if (withBody && 
                    EditorsUI.getPreferenceStore()
                             .getBoolean(LINKED_MODE)) {
                final LinkedModeModel linkedModeModel = new LinkedModeModel();
                final Point selection = getSelection(document);
                List<ICompletionProposal> proposals = new ArrayList<ICompletionProposal>();
                for (final ModuleVersionDetails d: module.getVersions()) {
                    proposals.add(new ICompletionProposal() {
                        @Override
                        public Point getSelection(IDocument document) {
                            return null;
                        }
                        @Override
                        public Image getImage() {
                            return CeylonResources.VERSION;
                        }

                        @Override
                        public String getDisplayString() {
                            return d.getVersion();
                        }

                        @Override
                        public IContextInformation getContextInformation() {
                            return null;
                        }

                        @Override
                        public String getAdditionalProposalInfo() {
                            return "Repository: " + d.getOrigin();
                        }

                        @Override
                        public void apply(IDocument document) {
                            try {
                                document.replace(selection.x, selection.y, 
                                        d.getVersion());
                            }
                            catch (BadLocationException e) {
                                e.printStackTrace();
                            }
                            linkedModeModel.exit(ILinkedModeListener.UPDATE_CARET);
                        }
                    });
                }
                ProposalPosition linkedPosition = 
                        new ProposalPosition(document, selection.x, selection.y, 0, 
                                proposals.toArray(NO_COMPLETIONS));
                try {
                    LinkedMode.addLinkedPosition(linkedModeModel, linkedPosition);
                    LinkedMode.installLinkedMode((CeylonEditor) EditorUtil.getCurrentEditor(), 
                            document, linkedModeModel, this, new LinkedMode.NullExitPolicy(),
                            -1, 0);
                }
                catch (BadLocationException ble) {
                    ble.printStackTrace();
                }
            }
        }
        
        @Override
        public String getAdditionalProposalInfo() {
{'fraction_non_alphanumeric': 0.08278846153846153, 'fraction_numerical': 0.0019230769230769232, 'mean_word_length': 2.03767523364486, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2898785', 'n_tokens_mistral': 2684, 'n_tokens_neox': 2590, 'n_words': 509}