/*******************************************************************************
* Copyright © 2000, 2013 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*
*******************************************************************************/
package org.eclipse.edt.ide.core.internal.search.matching;
import java.io.IOException;
import org.eclipse.edt.compiler.core.ast.NestedFunction;
import org.eclipse.edt.compiler.core.ast.Node;
import org.eclipse.edt.compiler.core.ast.Part;
import org.eclipse.edt.compiler.internal.core.utils.CharOperation;
import org.eclipse.edt.ide.core.internal.model.index.IEntryResult;
import org.eclipse.edt.ide.core.internal.model.index.impl.IndexInput;
import org.eclipse.edt.ide.core.internal.model.index.impl.IndexedFile;
import org.eclipse.edt.ide.core.internal.model.indexing.AbstractIndexer;
import org.eclipse.edt.ide.core.internal.search.IIndexSearchRequestor;
import org.eclipse.edt.ide.core.model.IIndexConstants;
import org.eclipse.edt.ide.core.model.IMember;
import org.eclipse.edt.ide.core.model.IPart;
import org.eclipse.edt.ide.core.search.IEGLSearchScope;
import org.eclipse.edt.mof.egl.Type;
public class FunctionDeclarationPattern extends FunctionPattern {
public FunctionDeclarationPattern(
char[] selector,
int matchMode,
boolean isCaseSensitive,
char[] declaringQualification){
//char[] declaringSimpleName,
//char[] returnQualification,
//char[] returnSimpleName,
//char[][] parameterQualifications,
//char[][] parameterSimpleNames) {
super(matchMode, isCaseSensitive);
this.selector = isCaseSensitive ? selector : CharOperation.toLowerCase(selector);
this.declaringQualification = isCaseSensitive ? declaringQualification : CharOperation.toLowerCase(declaringQualification);
//this.declaringSimpleName = isCaseSensitive ? declaringSimpleName : CharOperation.toLowerCase(declaringSimpleName);
//this.returnQualification = isCaseSensitive ? returnQualification : CharOperation.toLowerCase(returnQualification);
//this.returnSimpleName = isCaseSensitive ? returnSimpleName : CharOperation.toLowerCase(returnSimpleName);
// if (parameterSimpleNames != null){
//this.parameterQualifications = new char[parameterSimpleNames.length][];
//this.parameterSimpleNames = new char[parameterSimpleNames.length][];
//for (int i = 0, max = parameterSimpleNames.length; i < max; i++){
// this.parameterQualifications[i] = isCaseSensitive ? parameterQualifications[i] : CharOperation.toLowerCase(parameterQualifications[i]);
// this.parameterSimpleNames[i] = isCaseSensitive ? parameterSimpleNames[i] : CharOperation.toLowerCase(parameterSimpleNames[i]);
//}
// }
this.needsResolve = this.needsResolve();
}
public void decodeIndexEntry(IEntryResult entryResult){
char[] word = entryResult.getWord();
int size = word.length;
int lastSeparatorIndex = CharOperation.lastIndexOf(SEPARATOR, word);
//don't process entries that are refs
if(!CharOperation.prefixEquals(IIndexConstants.REF,word)){
decodedParameterCount = Integer.parseInt(new String(word, lastSeparatorIndex + 1, size - lastSeparatorIndex - 1));
decodedSelector = CharOperation.subarray(word, FUNCTION_DECL.length, lastSeparatorIndex);
}
}
/**
* see SearchPattern.feedIndexRequestor
*/
public void feedIndexRequestor(IIndexSearchRequestor requestor, int detailLevel, int[] references, IndexInput input, IEGLSearchScope scope) throws IOException {
for (int i = 0, max = references.length; i < max; i++) {
IndexedFile file = input.getIndexedFile(references[i]);
String path;
if (file != null && scope.encloses(path = IndexedFile.convertPath(file.getPath()))) {
requestor.acceptFunctionDeclaration(path, decodedSelector, decodedParameterCount);
}
}
}
public String getPatternName(){
return "FunctionDeclarationPattern: "; //$NON-NLS-1$
}
/**
* @see SearchPattern#indexEntryPrefix
*/
public char[] indexEntryPrefix() {
return AbstractIndexer.bestFunctionDeclarationPrefix(
selector,
-1, // EGL does not search based on arity
matchMode,
isCaseSensitive);
}
/**
* @see SearchPattern#matchContainer()
*/
protected int matchContainer() {
return EGL_FILE | FUNCTION;
}
/**
* @see SearchPattern#matchLevel(AstNode, boolean)
*/
public int matchLevel(Node node, boolean resolve) {
if (node instanceof NestedFunction){
NestedFunction function = (NestedFunction)node;
if (!this.matchesName(this.selector, function.getName().getCanonicalName().toCharArray()))
return IMPOSSIBLE_MATCH;
}else return IMPOSSIBLE_MATCH;
// EGLTODO: Support searching based on return types and parameters?
// return type
// TypeReference functionReturnType = function.returnType;
// if (functionReturnType != null) {
// char[][] functionReturnTypeName = functionReturnType.getTypeName();
// char[] sourceName = this.toArrayName(
// functionReturnTypeName[functionReturnTypeName.length-1],
// functionReturnType.dimensions());
// if (!this.matchesName(this.returnSimpleName, sourceName))
// return IMPOSSIBLE_MATCH;
// }
//
// // parameter types
// int parameterCount = this.parameterSimpleNames == null ? -1 : this.parameterSimpleNames.length;
// if (parameterCount > -1) {
// int argumentCount = function.arguments == null ? 0 : function.arguments.length;
// if (parameterCount != argumentCount)
// return IMPOSSIBLE_MATCH;
// }
return POSSIBLE_MATCH ;
}
@Override
public int matchLevel(IMember member, boolean resolve) {
//TODO Rocky
if (!this.matchesName(this.selector, member.getElementName().toCharArray()))
return IMPOSSIBLE_MATCH;
return POSSIBLE_MATCH;
}
protected org.eclipse.edt.mof.egl.Part getPartBinding(Part part){
Type type = part.getName().resolveType();
if (type instanceof org.eclipse.edt.mof.egl.Part){
return (org.eclipse.edt.mof.egl.Part)type;
}
return null;
}
//public int matchLevelForType(char[] simpleNamePattern, char[] qualificationPattern,TopLevelFunction function) {
// return IMPOSSIBLE_MATCH;
//}
public int matchTopLevelFunctionLevel(IPart functionPart) {
if (functionPart == null) return INACCURATE_MATCH;
int level;
level = this.matchLevelForType(this.selector, this.declaringQualification, functionPart);
if (level == IMPOSSIBLE_MATCH) return IMPOSSIBLE_MATCH;
return level;
}
@Override
public int getPatternType() {
return SearchPattern.DECLARATION;
}
}