/*******************************************************************************
* Copyright (c) 2000, 2016 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
*
*******************************************************************************/
package org.eclipse.dltk.internal.core.search.matching;
import java.util.List;
import org.eclipse.dltk.ast.ASTNode;
import org.eclipse.dltk.ast.declarations.MethodDeclaration;
import org.eclipse.dltk.ast.expressions.CallExpression;
import org.eclipse.dltk.compiler.CharOperation;
import org.eclipse.dltk.core.DLTKLanguageManager;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.ISearchPatternProcessor;
import org.eclipse.dltk.core.search.SearchMatch;
import org.eclipse.dltk.core.search.matching.MatchLocator;
import org.eclipse.dltk.core.search.matching.PatternLocator;
public class MethodDeclarationLocator extends PatternLocator {
protected MethodDeclarationPattern pattern;
public MethodDeclarationLocator(MethodDeclarationPattern pattern) {
super(pattern);
this.pattern = pattern;
}
/*
* Clear caches
*/
@Override
protected void clear() {
}
@Override
public void initializePolymorphicSearch(MatchLocator locator) {
}
@Override
public int match(MethodDeclaration node, MatchingNodeSet nodeSet) {
// Verify method name
if (!matchesName(this.pattern.simpleName, node.getName().toCharArray()))
return IMPOSSIBLE_MATCH;
// Verify parameters types
List arguments = node.getArguments();
if (this.pattern.parameterNames != null) {
int length = this.pattern.parameterNames.length;
int argsLength = arguments == null ? 0 : arguments.size();
if (length != argsLength)
return IMPOSSIBLE_MATCH;
}
// check type names
String declaringType = node.getDeclaringTypeName();
if (!checkTypeName(declaringType)) {
return INACCURATE_MATCH;
}
// Method declaration may match pattern
return nodeSet.addMatch(node, ACCURATE_MATCH);
}
// public int match(TypeDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
// public int match(TypeReference node, MatchingNodeSet nodeSet) - SKIP IT
@Override
public int matchContainer() {
return COMPILATION_UNIT_CONTAINER | CLASS_CONTAINER | METHOD_CONTAINER;
}
@Override
public SearchMatch newDeclarationMatch(ASTNode reference,
IModelElement element, int accuracy, MatchLocator locator) {
return super.newDeclarationMatch(reference, element, accuracy, locator);
}
@Override
protected int referenceType() {
return IModelElement.METHOD;
}
@Override
public String toString() {
return "Locator for " + this.pattern.toString(); //$NON-NLS-1$
}
@Override
public int match(CallExpression node, MatchingNodeSet nodeSet) {
// this locator matches only declarations
return IMPOSSIBLE_MATCH;
}
@Override
protected void matchReportReference(ASTNode reference,
IModelElement element, int accuracy, MatchLocator locator) {
// Since this is the declaration locator - it is not interested in
// references.
}
/**
* Tests if the specified {@code declaringType} matches the search pattern.
* Returns <code>true</code> if matches and <code>false</code> otherwise.
*
* @param declaringType
* @return
*/
private boolean checkTypeName(String declaringType) {
if (this.pattern.enclosingTypeNames != null
&& this.pattern.enclosingTypeNames.length > 0) {
if (declaringType != null) {
ISearchPatternProcessor processor = DLTKLanguageManager
.getSearchPatternProcessor(this.pattern.getToolkit());
char[] delimeter = processor != null ? processor
.getDelimiterReplacementString().toCharArray()
: new char[] { '.' };
char[] typeName = this.pattern.enclosingTypeNames[0];
if (typeName == null) {
return true;
}
for (int i = 1; i < this.pattern.enclosingTypeNames.length; ++i) {
typeName = CharOperation.concatWithSeparator(typeName,
this.pattern.enclosingTypeNames[i], delimeter);
}
if (!matchesName(typeName, declaringType.toCharArray())) {
return false;
}
} else {
return false;
}
}
return true;
}
}