blob: 480e75ead6541b6f8575fe7d5c814780a57c1482 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2007 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.ruby.internal.core.search;
import org.eclipse.dltk.ast.ASTNode;
import org.eclipse.dltk.ast.declarations.FieldDeclaration;
import org.eclipse.dltk.ast.declarations.MethodDeclaration;
import org.eclipse.dltk.ast.expressions.BigNumericLiteral;
import org.eclipse.dltk.ast.expressions.BooleanLiteral;
import org.eclipse.dltk.ast.expressions.CallExpression;
import org.eclipse.dltk.ast.expressions.FloatNumericLiteral;
import org.eclipse.dltk.ast.expressions.Literal;
import org.eclipse.dltk.ast.expressions.NilLiteral;
import org.eclipse.dltk.ast.expressions.NumericLiteral;
import org.eclipse.dltk.ast.expressions.StringLiteral;
import org.eclipse.dltk.ast.references.ConstantReference;
import org.eclipse.dltk.ast.references.Reference;
import org.eclipse.dltk.ast.references.SimpleReference;
import org.eclipse.dltk.ast.references.TypeReference;
import org.eclipse.dltk.ast.references.VariableReference;
import org.eclipse.dltk.core.search.matching.MatchLocator;
import org.eclipse.dltk.core.search.matching.MatchLocatorParser;
import org.eclipse.dltk.core.search.matching.PatternLocator;
import org.eclipse.dltk.ruby.ast.IRubyASTVisitor;
import org.eclipse.dltk.ruby.ast.RubyAliasExpression;
import org.eclipse.dltk.ruby.ast.RubyAssignment;
import org.eclipse.dltk.ruby.ast.RubyColonExpression;
import org.eclipse.dltk.ruby.ast.RubyConstantDeclaration;
import org.eclipse.dltk.ruby.ast.RubyRegexpExpression;
import org.eclipse.dltk.ruby.ast.RubySymbolReference;
public class RubyMatchLocatorParser extends MatchLocatorParser {
public RubyMatchLocatorParser(MatchLocator locator) {
super(locator);
}
protected class RubyMatchVisitor extends MatchVisitor implements
IRubyASTVisitor {
public void visitTypeName(ASTNode node) {
// empty
}
}
protected MatchVisitor getMatchVisitor() {
return new RubyMatchVisitor();
}
private void reportTypeReferenceMatch(ASTNode node, PatternLocator locator) {
String typeName;
while (node != null) {
if (node instanceof RubyColonExpression) {
typeName = ((RubyColonExpression) node).getName();
TypeReference ref = new TypeReference(node.sourceStart(), node
.sourceEnd(), typeName);
locator.match(ref, this.getNodeSet());
node = ((RubyColonExpression) node).getLeft();
} else if (node instanceof ConstantReference) {
typeName = ((ConstantReference) node).getName();
TypeReference ref = new TypeReference(node.sourceStart(), node
.sourceEnd(), typeName);
locator.match(ref, this.getNodeSet());
node = null;
} else {
node = null;
}
}
}
private void reportSimpleReferenceMatch(SimpleReference simpleRef,
PatternLocator locator) {
int pos = simpleRef.sourceStart();
if (pos < 0) {
pos = 0;
}
locator.match(new SimpleReference(pos, pos
+ simpleRef.getName().length(), simpleRef.getName()), this
.getNodeSet());
}
protected void processStatement(ASTNode node, PatternLocator locator) {
if (node == null) {
return;
}
if (node instanceof CallExpression) {
CallExpression call = (CallExpression) node;
// int start = call.sourceStart();
// int end = call.sourceEnd();
// if (start < 0) {
// start = 0;
// }
// if (end < 0) {
// end = 1;
// }
locator.match(call, this.getNodeSet());
/*
* (CallExpression) new CallExpression(start, end,
* call.getReceiver(), call.getName(), call.getArgs())
*/
} else if (node instanceof RubyAliasExpression) {
final RubyAliasExpression alias = (RubyAliasExpression) node;
final MethodDeclaration method = new MethodDeclaration(alias
.getNewValue(), alias.sourceStart(), alias.sourceEnd(),
alias.sourceStart(), alias.sourceEnd());
locator.match(method, this.getNodeSet());
} else if (node instanceof RubyAssignment) {
// Assignment handling (this is static variable assignment.)
RubyAssignment assignment = (RubyAssignment) node;
ASTNode left = assignment.getLeft();
if (left instanceof VariableReference) {
VariableReference var = (VariableReference) left;
FieldDeclaration field = new FieldDeclaration(var.getName(),
var.sourceStart(), var.sourceEnd() - 1, var
.sourceStart(), var.sourceEnd() - 1);
locator.match(field, this.getNodeSet());
}
} else if (node instanceof Literal) {
if (node instanceof RubyRegexpExpression) {
TypeReference ref = new TypeReference(node.sourceStart(), node
.sourceEnd(), "Regexp"); //$NON-NLS-1$
locator.match(ref, this.getNodeSet());
} else if (node instanceof StringLiteral) {
TypeReference ref = new TypeReference(node.sourceStart(), node
.sourceEnd(), "String"); //$NON-NLS-1$
locator.match(ref, this.getNodeSet());
} else if (node instanceof BooleanLiteral) {
BooleanLiteral boolLit = (BooleanLiteral) node;
TypeReference ref;
if (boolLit.boolValue()) {
ref = new TypeReference(node.sourceStart(), node
.sourceEnd(), "TrueClass"); //$NON-NLS-1$
} else {
ref = new TypeReference(node.sourceStart(), node
.sourceEnd(), "FalseClass"); //$NON-NLS-1$
}
locator.match(ref, this.getNodeSet());
} else if (node instanceof NumericLiteral) {
TypeReference ref = new TypeReference(node.sourceStart(), node
.sourceEnd(), "Fixnum"); //$NON-NLS-1$
locator.match(ref, this.getNodeSet());
} else if (node instanceof NilLiteral) {
TypeReference ref = new TypeReference(node.sourceStart(), node
.sourceEnd(), "NilClass"); //$NON-NLS-1$
locator.match(ref, this.getNodeSet());
} else if (node instanceof FloatNumericLiteral) {
TypeReference ref = new TypeReference(node.sourceStart(), node
.sourceEnd(), "Float"); //$NON-NLS-1$
locator.match(ref, this.getNodeSet());
} else if (node instanceof BigNumericLiteral) {
TypeReference ref = new TypeReference(node.sourceStart(), node
.sourceEnd(), "Bignum"); //$NON-NLS-1$
locator.match(ref, this.getNodeSet());
}
} else if (node instanceof Reference) {
if (node instanceof RubySymbolReference) {
TypeReference ref = new TypeReference(node.sourceStart(), node
.sourceEnd(), "Symbol"); //$NON-NLS-1$
locator.match(ref, this.getNodeSet());
} else if (node instanceof VariableReference) {
reportSimpleReferenceMatch((SimpleReference) node, locator);
} else if (node instanceof ConstantReference) {
reportSimpleReferenceMatch((SimpleReference) node, locator);
reportTypeReferenceMatch(node, locator);
}
} else if (node instanceof RubyColonExpression) {
reportTypeReferenceMatch(node, locator);
} else if (node instanceof RubyConstantDeclaration) {
RubyConstantDeclaration var = (RubyConstantDeclaration) node;
SimpleReference name = var.getName();
FieldDeclaration field = new FieldDeclaration(name.getName(), name
.sourceStart(), name.sourceEnd(), name.sourceStart(), name
.sourceEnd());
locator.match(field, this.getNodeSet());
}
}
}