/*******************************************************************************
* Copyright (c) 2009 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
* Zend Technologies
*******************************************************************************/
package org.eclipse.php.internal.core.typeinference;
import org.eclipse.dltk.ast.ASTNode;
import org.eclipse.dltk.ast.ASTVisitor;
import org.eclipse.dltk.ast.declarations.Declaration;
import org.eclipse.dltk.ast.declarations.MethodDeclaration;
import org.eclipse.dltk.ast.declarations.ModuleDeclaration;
import org.eclipse.dltk.ast.declarations.TypeDeclaration;
import org.eclipse.dltk.ast.expressions.Expression;
import org.eclipse.dltk.ast.statements.Statement;
import org.eclipse.dltk.core.IMember;
import org.eclipse.dltk.core.ISourceRange;
import org.eclipse.dltk.core.ModelException;
class DeclarationSearcher extends ASTVisitor {
enum DeclarationType {
METHOD, CLASS, FIELD
};
private int bestScore = Integer.MAX_VALUE;
private int modelStart;
private int modelEnd;
private int modelCutoffStart;
private int modelCutoffEnd;
private String elementName;
private Declaration result;
private DeclarationType declarationType;
public DeclarationSearcher(ModuleDeclaration moduleDeclaration, IMember modelElement,
DeclarationType declarationType) throws ModelException {
ISourceRange sourceRange = modelElement.getSourceRange();
modelStart = sourceRange.getOffset();
modelEnd = modelStart + sourceRange.getLength();
modelCutoffStart = modelStart - 100;
modelCutoffEnd = modelEnd + 100;
elementName = modelElement.getElementName();
this.declarationType = declarationType;
}
public Declaration getResult() {
return result;
}
protected void checkElementDeclaration(Declaration s) {
if (s.getName().equals(elementName)) {
int astStart = s.sourceStart();
int astEnd = s.sourceEnd();
int diff1 = modelStart - astStart;
int diff2 = modelEnd - astEnd;
int score = diff1 * diff1 + diff2 * diff2;
if (score < bestScore) {
bestScore = score;
result = s;
}
}
}
protected boolean interesting(ASTNode s) {
if (s.sourceStart() < 0 || s.sourceEnd() < s.sourceStart()) {
return true;
}
if (modelCutoffEnd < s.sourceStart() || modelCutoffStart >= s.sourceEnd()) {
return false;
}
return true;
}
public boolean visit(Expression s) throws Exception {
if (!interesting(s)) {
return false;
}
return true;
}
public boolean visit(Statement s) throws Exception {
if (!interesting(s)) {
return false;
}
if (declarationType == DeclarationType.FIELD && s instanceof Declaration) {
checkElementDeclaration((Declaration) s);
}
return true;
}
public boolean visit(MethodDeclaration s) throws Exception {
if (!interesting(s)) {
return false;
}
if (declarationType == DeclarationType.METHOD) {
checkElementDeclaration(s);
}
return true;
}
public boolean visit(ModuleDeclaration s) throws Exception {
if (!interesting(s)) {
return false;
}
return true;
}
public boolean visit(TypeDeclaration s) throws Exception {
if (!interesting(s)) {
return false;
}
if (declarationType == DeclarationType.CLASS) {
checkElementDeclaration(s);
}
return true;
}
public boolean visitGeneral(ASTNode s) throws Exception {
if (!interesting(s)) {
return false;
}
return true;
}
}