WALA/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/impl/CAstImpl.java

188 lines
4.9 KiB
Java

/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* 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
*****************************************************************************/
package com.ibm.wala.cast.tree.impl;
import com.ibm.wala.cast.tree.*;
import com.ibm.wala.cast.util.CAstPrinter;
import com.ibm.wala.util.debug.Assertions;
import java.util.NoSuchElementException;
/**
* An implementation of CAst, i.e. a simple factory for creating capa
* ast nodes. This class simply creates generic nodes with a kind
* field, and either an array of children or a constant values. Note
* that there is no easy way to mutate these trees; do not change
* this (see CAstNode for the rationale for this rule).
*
* @author Julian Dolby (dolby@us.ibm.com)
*
*/
public class CAstImpl implements CAst {
private int nextID= 0;
public String makeUnique() {
return "id" + (nextID++);
}
protected static class CAstNodeImpl implements CAstNode {
protected final CAstNode[] cs;
protected final int kind;
protected CAstNodeImpl(int kind, CAstNode[] cs) {
this.kind = kind;
this.cs = cs;
if (Assertions.verifyAssertions)
for(int i = 0; i < cs.length; i++)
Assertions._assert(cs[i] != null,
"argument " + i + " is null for node kind " + kind + " [" + CAstPrinter.entityKindAsString(kind) + "]");
}
public int getKind() {
return kind;
}
public Object getValue() {
return null;
}
public CAstNode getChild(int n) {
try {
return cs[n];
} catch (ArrayIndexOutOfBoundsException e) {
throw new NoSuchElementException();
}
}
public int getChildCount() {
return cs.length;
}
public String toString() {
return CAstPrinter.print(this);
}
public int hashCode() {
int code = getKind() * (getChildCount()+13);
for(int i = 0; i < getChildCount(); i++) {
code *= getChild(i).getKind();
}
return code;
}
}
public CAstNode makeNode(final int kind, final CAstNode[] cs) {
return new CAstNodeImpl(kind, cs);
}
public CAstNode makeNode(int kind, CAstNode c1, CAstNode[] cs) {
CAstNode[] children = new CAstNode[ cs.length + 1 ];
children[0] = c1;
System.arraycopy(cs, 0, children, 1, cs.length);
return makeNode(kind, children);
}
public CAstNode makeNode(int kind) {
return makeNode(kind, new CAstNode[0]);
}
public CAstNode makeNode(int kind, CAstNode c1) {
return makeNode(kind, new CAstNode[]{c1});
}
public CAstNode makeNode(int kind, CAstNode c1, CAstNode c2) {
return makeNode(kind, new CAstNode[]{c1, c2});
}
public CAstNode makeNode(int kind, CAstNode c1, CAstNode c2, CAstNode c3) {
return makeNode(kind, new CAstNode[]{c1, c2, c3});
}
public CAstNode makeNode(int kind, CAstNode c1, CAstNode c2, CAstNode c3, CAstNode c4) {
return makeNode(kind, new CAstNode[]{c1, c2, c3, c4});
}
public CAstNode makeNode(int kind, CAstNode c1, CAstNode c2, CAstNode c3, CAstNode c4, CAstNode c5) {
return makeNode(kind, new CAstNode[]{c1, c2, c3, c4, c5});
}
public CAstNode makeNode(int kind, CAstNode c1, CAstNode c2, CAstNode c3, CAstNode c4, CAstNode c5, CAstNode c6) {
return makeNode(kind, new CAstNode[]{c1, c2, c3, c4, c5, c6});
}
protected static class CAstValueImpl implements CAstNode {
protected final Object value;
protected CAstValueImpl(Object value) {
this.value = value;
}
public int getKind() {
return CAstNode.CONSTANT;
}
public Object getValue() {
return value;
}
public CAstNode getChild(int n) {
throw new NoSuchElementException();
}
public int getChildCount() {
return 0;
}
public String toString() {
return "CAstValue: " + value;
}
public int hashCode() {
return getKind() * toString().hashCode();
}
}
public CAstNode makeConstant(final Object value) {
return new CAstValueImpl(value);
}
public CAstNode makeConstant(boolean value) {
return makeConstant(value? Boolean.TRUE: Boolean.FALSE);
}
public CAstNode makeConstant(char value) {
return makeConstant( new Character(value) );
}
public CAstNode makeConstant(short value) {
return makeConstant( new Short(value) );
}
public CAstNode makeConstant(int value) {
return makeConstant( new Integer(value) );
}
public CAstNode makeConstant(long value) {
return makeConstant( new Long(value) );
}
public CAstNode makeConstant(float value) {
return makeConstant( new Float(value) );
}
public CAstNode makeConstant(double value) {
return makeConstant( new Double(value) );
}
}