src.org.python.indexer.Ref Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jython Show documentation
Show all versions of jython Show documentation
Jython is an implementation of the high-level, dynamic, object-oriented
language Python written in 100% Pure Java, and seamlessly integrated with
the Java platform. It thus allows you to run Python on any Java platform.
/**
* Copyright 2009, Google Inc. All rights reserved.
* Licensed to PSF under a Contributor Agreement.
*/
package org.python.indexer;
import org.python.indexer.ast.NAttribute;
import org.python.indexer.ast.NName;
import org.python.indexer.ast.NNode;
import org.python.indexer.ast.NStr;
/**
* Encapsulates information about a binding reference.
*/
public class Ref {
private static final int ATTRIBUTE = 0x1;
private static final int CALL = 0x2; // function/method call
private static final int NEW = 0x4; // instantiation
private static final int STRING = 0x8; // source node is a String
private int start;
private String file;
private String name;
private int flags;
public Ref(NNode node) {
if (node == null) {
throw new IllegalArgumentException("null node");
}
file = node.getFile();
start = node.start();
if (node instanceof NName) {
NName nn = ((NName)node);
name = nn.id;
if (nn.isCall()) {
// We don't always have enough information at this point to know
// if it's a constructor call or a regular function/method call,
// so we just determine if it looks like a call or not, and the
// indexer will convert constructor-calls to NEW in a later pass.
markAsCall();
}
} else if (node instanceof NStr) {
markAsString();
name = ((NStr)node).n.toString();
} else {
throw new IllegalArgumentException("I don't know what " + node + " is.");
}
NNode parent = node.getParent();
if ((parent instanceof NAttribute)
&& node == ((NAttribute)parent).attr) {
markAsAttribute();
}
}
/**
* Constructor that provides a way for clients to add additional references
* not associated with an AST node (e.g. inside a comment or doc string).
* @param path absolute path to the file containing the reference
* @param offset the 0-indexed file offset of the reference
* @param text the text of the reference
*/
public Ref(String path, int offset, String text) {
if (path == null) {
throw new IllegalArgumentException("'path' cannot be null");
}
if (text == null) {
throw new IllegalArgumentException("'text' cannot be null");
}
file = path;
start = offset;
name = text;
}
/**
* Returns the file containing the reference.
*/
public String getFile() {
return file;
}
/**
* Returns the text of the reference.
*/
public String getName() {
return name;
}
/**
* Returns the starting file offset of the reference.
*/
public int start() {
return start;
}
/**
* Returns the ending file offset of the reference.
*/
public int end() {
return start + length();
}
/**
* Returns the length of the reference text.
*/
public int length() {
return isString() ? name.length() + 2 : name.length();
}
/**
* Returns {@code true} if this reference was unquoted name.
*/
public boolean isName() {
return !isString();
}
/**
* Returns {@code true} if this reference was an attribute
* of some other node.
*/
public boolean isAttribute() {
return (flags & ATTRIBUTE) != 0;
}
public void markAsAttribute() {
flags |= ATTRIBUTE;
}
/**
* Returns {@code true} if this reference was a quoted name.
* If so, the {@link #start} and {@link #length} include the positions
* of the opening and closing quotes, but {@link #isName} returns the
* text within the quotes.
*/
public boolean isString() {
return (flags & STRING) != 0;
}
public void markAsString() {
flags |= STRING;
}
/**
* Returns {@code true} if this reference is a function or method call.
*/
public boolean isCall() {
return (flags & CALL) != 0;
}
/**
* Returns {@code true} if this reference is a class instantiation.
*/
public void markAsCall() {
flags |= CALL;
flags &= ~NEW;
}
public boolean isNew() {
return (flags & NEW) != 0;
}
public void markAsNew() {
flags |= NEW;
flags &= ~CALL;
}
public boolean isRef() {
return !(isCall() || isNew());
}
@Override
public String toString() {
return "";
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Ref)) {
return false;
}
Ref ref = (Ref)obj;
if (start != ref.start) {
return false;
}
if (name != null) {
if (!name.equals(ref.name)) {
return false;
}
} else {
if (ref.name != null) {
return false;
}
}
if (file != null) {
if (!file.equals(ref.file)) {
return false;
}
} else {
if (ref.file != null) {
return false;
}
}
// This should never happen, but checking it here can help surface bugs.
if (flags != ref.flags) {
return false;
}
return true;
}
@Override
public int hashCode() {
return ("" + file + name + start).hashCode();
}
}