blob: e7cd81770ed4140c49ed0a86bd73bafc366995b4 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2017 IBM Corporation and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* xored software, Inc. - initial API and Implementation
* xored software, Inc. - Search All occurences bugfix,
* hilight only class name when class is in search results ( Alex Panchenko <alex@xored.com>)
*******************************************************************************/
package org.eclipse.dltk.ast;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.core.ISourceNode;
import org.eclipse.dltk.core.ISourceRange;
import org.eclipse.dltk.core.SourceRange;
import org.eclipse.dltk.utils.CorePrinter;
public abstract class ASTNode implements ISourceNode {
// storage for internal flags (32 bits) BIT USAGE
public final static int Bit1 = 0x1; // return type (operator) | name
// reference kind (name ref) | add
// assertion (type decl) | useful empty
// statement (empty statement)
public final static int Bit2 = 0x2; // return type (operator) | name
// reference kind (name ref) | has local
// type (type, method, field decl)
public final static int Bit3 = 0x4; // return type (operator) | name
// reference kind (name ref) | implicit
// this (this ref)
public final static int Bit4 = 0x8; // return type (operator) | first
// assignment to local (local decl) |
// undocumented empty block (block, type
// and method decl)
public final static int Bit5 = 0x10; // value for return (expression) |
// has all method bodies (unit) |
// supertype ref (type ref)
public final static int Bit6 = 0x20; // depth (name ref, msg) | ignore
// need cast check (cast expression)
public final static int Bit7 = 0x40; // depth (name ref, msg) | operator
// (operator) | need runtime
// checkcast (cast expression) |
// label used (labelStatement)
public final static int Bit8 = 0x80; // depth (name ref, msg) | operator
// (operator) | unsafe cast (cast
// expression)
public final static int Bit9 = 0x100; // depth (name ref, msg) | operator
// (operator) | is local type (type
// decl)
public final static int Bit10 = 0x200; // depth (name ref, msg) | operator
// (operator) | is anonymous type
// (type decl)
public final static int Bit11 = 0x400; // depth (name ref, msg) | operator
// (operator) | is member type (type
// decl)
public final static int Bit12 = 0x800; // depth (name ref, msg) | operator
// (operator) | has abstract methods
// (type decl)
public final static int Bit13 = 0x1000; // depth (name ref, msg) | is
// secondary type (type decl)
public final static int Bit14 = 0x2000; // strictly assigned (reference lhs)
public final static int Bit15 = 0x4000; // is unnecessary cast (expression)
// | is varargs (type ref) |
// isSubRoutineEscaping (try
// statement)
public final static int Bit16 = 0x8000; // in javadoc comment (name ref,
// type ref, msg)
public final static int Bit17 = 0x10000; // compound assigned (reference
// lhs)
public final static int Bit18 = 0x20000; // non null (expression)
public final static int Bit19 = 0x40000;
public final static int Bit20 = 0x80000;
public final static int Bit21 = 0x100000;
public final static int Bit22 = 0x200000; // parenthesis count
// (expression)
public final static int Bit23 = 0x400000; // parenthesis count
// (expression)
public final static int Bit24 = 0x800000; // parenthesis count
// (expression)
public final static int Bit25 = 0x1000000; // parenthesis count
// (expression)
public final static int Bit26 = 0x2000000; // parenthesis count
// (expression)
public final static int Bit27 = 0x4000000; // parenthesis count
// (expression)
public final static int Bit28 = 0x8000000; // parenthesis count
// (expression)
public final static int Bit29 = 0x10000000; // parenthesis count
// (expression)
public final static int Bit30 = 0x20000000; // elseif (if statement) | try
// block exit (try statement) |
// fall-through (case statement)
public final static int Bit31 = 0x40000000; // local declaration reachable
// (local decl) | ignore raw
// type check (type ref) |
// discard entire assignment
// (assignment)
public final static int Bit32 = 0x80000000; // reachable (statement)
public final static long Bit32L = 0x80000000L;
public final static long Bit33L = 0x100000000L;
public final static long Bit34L = 0x200000000L;
public final static long Bit35L = 0x400000000L;
public final static long Bit36L = 0x800000000L;
public final static long Bit37L = 0x1000000000L;
public final static long Bit38L = 0x2000000000L;
public final static long Bit39L = 0x4000000000L;
public final static long Bit40L = 0x8000000000L;
public final static long Bit41L = 0x10000000000L;
public final static long Bit42L = 0x20000000000L;
public final static long Bit43L = 0x40000000000L;
public final static long Bit44L = 0x80000000000L;
public final static long Bit45L = 0x100000000000L;
public final static long Bit46L = 0x200000000000L;
public final static long Bit47L = 0x400000000000L;
public final static long Bit48L = 0x800000000000L;
public final static long Bit49L = 0x1000000000000L;
public final static long Bit50L = 0x2000000000000L;
public final static long Bit51L = 0x4000000000000L;
public final static long Bit52L = 0x8000000000000L;
public final static long Bit53L = 0x10000000000000L;
public final static long Bit54L = 0x20000000000000L;
public final static long Bit55L = 0x40000000000000L;
public final static long Bit56L = 0x80000000000000L;
public final static long Bit57L = 0x100000000000000L;
public final static long Bit58L = 0x200000000000000L;
public final static long Bit59L = 0x400000000000000L;
public final static long Bit60L = 0x800000000000000L;
public final static long Bit61L = 0x1000000000000000L;
public final static long Bit62L = 0x2000000000000000L;
public final static long Bit63L = 0x4000000000000000L;
public final static long Bit64L = 0x8000000000000000L;
public final static int D_METHOD_DECL = 1;
public final static int D_TYPE_DECL = 2;
public final static int D_VAR_DECL = 3;
private int sourceStart;
private int sourceEnd;
protected ASTNode() {
this(0, 0);
}
protected ASTNode(int start, int end) {
this.sourceStart = start;
this.sourceEnd = end;
}
protected ASTNode(DLTKToken token) {
this.sourceStart = token.getColumn();
String tokenValue = token.getText();
if (tokenValue != null) {
this.sourceEnd = this.sourceStart + tokenValue.length();
} else {
this.sourceEnd = this.sourceStart;
}
}
public final int sourceStart() {
return this.sourceStart;
}
@Override
public int start() {
return sourceStart();
}
public final int sourceEnd() {
return this.sourceEnd;
}
@Override
public int end() {
return sourceEnd();
}
/**
* Returns the offset of the region which should be highlighted when this
* item is added to search results.
*
* The goal is to highlight only classname when searching for types.
*/
public int matchStart() {
return sourceStart();
}
/**
* Returns the length of the region which should be highlighted when this
* item is added to search results.
*/
public int matchLength() {
return sourceEnd() - sourceStart();
}
// TODO: Need to find way to change visibility to protected.
public void setStart(int start) {
this.sourceStart = start;
}
// TODO: Need to find way to change visibility to protected.
public void setEnd(int end) {
this.sourceEnd = end;
}
public abstract void traverse(ASTVisitor visitor) throws Exception;
public void printNode(CorePrinter output) {
output.println(
this.getClass() + " (node doesn't support debug printing)"); //$NON-NLS-1$
}
protected ISourceRange getSourceRange() {
return new SourceRange(this.sourceStart(),
this.sourceEnd() - this.sourceStart() + 1);
}
private static String simplifyClassName(String name) {
int pos = name.lastIndexOf('.');
return name.substring(pos + 1);
}
public String debugString() {
return simplifyClassName(this.getClass().getName()) + "@" //$NON-NLS-1$
+ this.getSourceRange().toString();
}
@Override
public String toString() {
StringWriter writer = new StringWriter();
CorePrinter printer = new CorePrinter(writer);
this.printNode(printer);
printer.flush();
printer.close();
return writer.getBuffer().toString();
}
/**
* Uses simplest visitor to get childs and returns collection of ASTNode
* objects
*
* @return
*/
public List<ASTNode> getChilds() {
final List<ASTNode> result = new ArrayList<>();
ASTVisitor visitor = new ASTVisitor() {
@Override
public boolean visitGeneral(ASTNode node) throws Exception {
if (node == ASTNode.this) {
return true;
}
result.add(node);
return false; // we needn't subchilds and more
}
};
try {
this.traverse(visitor);
} catch (Exception e) {
if (DLTKCore.DEBUG) {
e.printStackTrace();
}
}
return result;
}
/**
* Tests if the specified node is located at the same location.
*
* @param other
* @return
*/
public boolean locationMatches(ASTNode other) {
if (other == this)
return true;
if (other == null) {
return false;
}
return other.sourceEnd() >= 0 && other.sourceStart() >= 0
&& sourceStart() == other.sourceStart()
&& sourceEnd() == other.sourceEnd();
}
}