diff options
Diffstat (limited to 'bundles/org.eclipse.wst.jsdt.ui/src/org/eclipse/wst/jsdt/internal/ui/text/java/FieldProposalInfo.java')
-rw-r--r-- | bundles/org.eclipse.wst.jsdt.ui/src/org/eclipse/wst/jsdt/internal/ui/text/java/FieldProposalInfo.java | 148 |
1 files changed, 123 insertions, 25 deletions
diff --git a/bundles/org.eclipse.wst.jsdt.ui/src/org/eclipse/wst/jsdt/internal/ui/text/java/FieldProposalInfo.java b/bundles/org.eclipse.wst.jsdt.ui/src/org/eclipse/wst/jsdt/internal/ui/text/java/FieldProposalInfo.java index 5d69f003..b31e9451 100644 --- a/bundles/org.eclipse.wst.jsdt.ui/src/org/eclipse/wst/jsdt/internal/ui/text/java/FieldProposalInfo.java +++ b/bundles/org.eclipse.wst.jsdt.ui/src/org/eclipse/wst/jsdt/internal/ui/text/java/FieldProposalInfo.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2010 IBM Corporation and others. + * Copyright (c) 2005, 2011 IBM Corporation 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 @@ -10,13 +10,30 @@ *******************************************************************************/ package org.eclipse.wst.jsdt.internal.ui.text.java; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.wst.jsdt.core.CompletionProposal; import org.eclipse.wst.jsdt.core.IField; +import org.eclipse.wst.jsdt.core.IJavaScriptElement; import org.eclipse.wst.jsdt.core.IJavaScriptProject; +import org.eclipse.wst.jsdt.core.ILocalVariable; import org.eclipse.wst.jsdt.core.IMember; import org.eclipse.wst.jsdt.core.IType; import org.eclipse.wst.jsdt.core.JavaScriptModelException; +import org.eclipse.wst.jsdt.core.search.IJavaScriptSearchScope; +import org.eclipse.wst.jsdt.core.search.SearchEngine; +import org.eclipse.wst.jsdt.core.search.SearchMatch; +import org.eclipse.wst.jsdt.core.search.SearchParticipant; +import org.eclipse.wst.jsdt.core.search.SearchPattern; +import org.eclipse.wst.jsdt.core.search.SearchRequestor; +import org.eclipse.wst.jsdt.internal.core.DefaultWorkingCopyOwner; +import org.eclipse.wst.jsdt.internal.core.search.matching.FieldPattern; +import org.eclipse.wst.jsdt.internal.core.util.QualificationHelpers; import org.eclipse.wst.jsdt.internal.corext.template.java.SignatureUtil; +import org.eclipse.wst.jsdt.internal.ui.Logger; /** @@ -24,8 +41,7 @@ import org.eclipse.wst.jsdt.internal.corext.template.java.SignatureUtil; * * */ -public final class FieldProposalInfo extends MemberProposalInfo { - +public final class FieldProposalInfo extends MemberProposalInfo { /** * Creates a new proposal info. * @@ -35,34 +51,116 @@ public final class FieldProposalInfo extends MemberProposalInfo { public FieldProposalInfo(IJavaScriptProject project, CompletionProposal proposal) { super(project, proposal); } - + /** - * Resolves the member described by the receiver and returns it if found. - * Returns <code>null</code> if no corresponding member can be found. - * - * @return the resolved member or <code>null</code> if none is found - * @throws JavaScriptModelException if accessing the java model fails + * <p>Returns the java element that this computer corresponds to, possibly <code>null</code>.</p> + * + * <p><b>NOTE:</b> This overrides the parent implementation so that {@link #resolveMember()} is not called + * because the field proposal can resolve to a none {@link IMember}.</p> + * + * @return the java element that this computer corresponds to, possibly <code>null</code> + * @throws JavaScriptModelException + */ + public IJavaScriptElement getJavaElement() throws JavaScriptModelException { + if (!fJavaElementResolved) { + fJavaElementResolved= true; + //call the internal resolve rather then #resolveMember + fElement = resolve(); + } + return fElement; + } + + /** + * @see org.eclipse.wst.jsdt.internal.ui.text.java.MemberProposalInfo#resolveMember() */ protected IMember resolveMember() throws JavaScriptModelException { - char[] declarationSignature= fProposal.getDeclarationSignature(); - // for synthetic fields on arrays, declaration signatures may be null - // TODO remove when https://bugs.eclipse.org/bugs/show_bug.cgi?id=84690 gets fixed - if (declarationSignature == null) - return null; - String typeName= SignatureUtil.stripSignatureToFQN(String.valueOf(declarationSignature)); - IType[] types = this.fJavaProject.findTypes(typeName); - if(types != null && types.length > 0) { - for(int i = 0; i < types.length; ++i) { - IType type = types[i]; - if (type != null) { - String name= String.valueOf(fProposal.getName()); - IField field= type.getField(name); - if (field.exists()) - return field; + IMember member = null; + IJavaScriptElement element = this.resolve(); + if(element instanceof IMember) { + member = (IMember)element; + } + return member; + } + + /** + * @return {@link IJavaScriptElement} that this field proposal resolves to + * + * @throws JavaScriptModelException + */ + private IJavaScriptElement resolve() throws JavaScriptModelException { + //get the type name + char[] typeNameChars = fProposal.getDeclarationTypeName(); + String declaringTypeName = null; + if(typeNameChars != null) { + declaringTypeName = String.valueOf(typeNameChars); + } + + /* try using the signature if type name not set + * NOTE: old way of doing things, should be removed at some point + */ + if(declaringTypeName == null) { + char[] declarationSignature= fProposal.getDeclarationSignature(); + if(declarationSignature != null) { + declaringTypeName = SignatureUtil.stripSignatureToFQN(String.valueOf(declarationSignature)); + } + } + + //find the field + IJavaScriptElement resolvedField = null; + if(declaringTypeName != null) { + String fieldName = String.valueOf(fProposal.getName()); + + IType[] types = this.fJavaProject.findTypes(declaringTypeName); + if(types != null && types.length > 0) { + for(int i = 0; i < types.length && resolvedField == null; ++i) { + IType type = types[i]; + if (type != null) { + IField field = type.getField(fieldName); + if (field.exists()) { + resolvedField = field; + } + } } + } else { + //create the search pattern + char[][] seperatedDeclaringTypename = QualificationHelpers.seperateFullyQualifedName(declaringTypeName.toCharArray()); +// if(!CharOperation.equals(seperatedDeclaringTypename[QualificationHelpers.SIMPLE_NAMES_INDEX], IIndexConstants.GLOBAL_SYMBOL)) { + FieldPattern fieldPattern = new FieldPattern(true, false, false, + fieldName.toCharArray(), + seperatedDeclaringTypename[QualificationHelpers.QULIFIERS_INDEX], + seperatedDeclaringTypename[QualificationHelpers.SIMPLE_NAMES_INDEX], + SearchPattern.R_EXACT_MATCH); + + //search the index for a match + SearchEngine searchEngine = new SearchEngine(DefaultWorkingCopyOwner.PRIMARY); + IJavaScriptSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaScriptElement[] {this.fJavaProject}); + final List matches = new ArrayList(); + try { + searchEngine.search(fieldPattern, + new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()}, + scope, + new SearchRequestor() { + public void acceptSearchMatch(SearchMatch match) throws CoreException { + Object element = match.getElement(); + if(element instanceof IField || element instanceof ILocalVariable) { + matches.add(element); + } + } + }, + new NullProgressMonitor()); //using a NPM here maybe a bad idea, but nothing better to do right now + } + catch (CoreException e) { + Logger.logException("Failed index search for field: " + fieldName, e); //$NON-NLS-1$ + } + + // just use the first match found + if(!matches.isEmpty()) { + resolvedField = (IJavaScriptElement)matches.get(0); + } +// } } } - return null; + return resolvedField; } } |