/* * Copyright (c) 2013, 2015 QNX Software Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package org.eclipse.cdt.internal.qt.ui; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import org.eclipse.cdt.core.dom.ast.IASTCompletionContext; import org.eclipse.cdt.core.dom.ast.IASTCompletionNode; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.internal.qt.core.QtNature; import org.eclipse.cdt.internal.ui.text.contentassist.CContentAssistInvocationContext; import org.eclipse.cdt.internal.ui.text.contentassist.ParsingBasedProposalComputer; import org.eclipse.cdt.ui.text.contentassist.ContentAssistInvocationContext; import org.eclipse.cdt.ui.text.contentassist.ICEditorContentAssistInvocationContext; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.text.contentassist.ICompletionProposal; @SuppressWarnings("restriction") public class QtCompletionProposalComputer extends ParsingBasedProposalComputer { @Override public List<ICompletionProposal> computeCompletionProposals( ContentAssistInvocationContext context, IProgressMonitor monitor) { // this is overridden in order to find proposals when the completion node is null try { if (context instanceof CContentAssistInvocationContext) { CContentAssistInvocationContext cContext = (CContentAssistInvocationContext) context; String prefix = null; IASTCompletionNode completionNode = cContext.getCompletionNode(); // the parent implementation gives up when this condition is false if (completionNode != null) prefix = completionNode.getPrefix(); if (prefix == null) prefix = cContext.computeIdentifierPrefix().toString(); return computeCompletionProposals(cContext, completionNode, prefix); } } catch (Exception e) { Activator.log(e); } return Collections.emptyList(); } private boolean isApplicable(ICEditorContentAssistInvocationContext context) { ITranslationUnit tu = context.getTranslationUnit(); if (tu == null) return false; ICProject cProject = tu.getCProject(); if (cProject == null) return false; IProject project = cProject.getProject(); if (project == null) return false; return QtNature.hasNature(project); } @Override protected List<ICompletionProposal> computeCompletionProposals( CContentAssistInvocationContext context, IASTCompletionNode completionNode, String prefix) throws CoreException { // make sure this is a Qt project if (!isApplicable(context)) return Collections.emptyList(); List<ICompletionProposal> proposals = null; if (completionNode != null) { IASTName[] names = completionNode.getNames(); for (IASTName name : names) { // the node isn't properly hooked up, must have backtracked out of this node if (name.getTranslationUnit() == null) continue; IASTCompletionContext astContext = name.getCompletionContext(); if (astContext == null || !(astContext instanceof IASTNode)) continue; IASTNode astNode = (IASTNode) astContext; proposals = addAll(proposals, QObjectConnectCompletion.getProposals(context, name, astContext, astNode)); proposals = addAll(proposals, QObjectDeclarationCompletion.getProposals(context, name)); proposals = addAll(proposals, QPropertyCompletion.getProposals(context, name, astContext, astNode)); } } // Attributes within Q_PROPERTY declarations proposals = addAll(proposals, QPropertyCompletion.getAttributeProposals(context)); return proposals == null ? Collections.<ICompletionProposal>emptyList() : proposals; } private static <T> List<T> addAll(List<T> list, Collection<T> toAdd) { if (toAdd == null || toAdd.isEmpty()) return list; if (list == null) return new ArrayList<T>(toAdd); list.addAll(toAdd); return list; } }