blob: 170ebae0028971999153695657b9dbd644034e08 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2016 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
*
*******************************************************************************/
/*
* (c) 2002, 2005 xored software and others all rights reserved. http://www.xored.com
*/
package org.eclipse.dltk.python.parser.ast.expressions;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.dltk.ast.expressions.Expression;
import org.eclipse.dltk.ast.references.Reference;
import org.eclipse.dltk.utils.CorePrinter;
/**
* Holds extended variables as list of VariableReference, CallHolder,
* IndexHolder.. Example: 1) z.a.f() it is be: ( VariableReference,
* VariableReference, VariableReference, CallHolder ) 2) a.f().q[2] it is be: (
* VariableReference, VariableReference, CallHolder, VariableReference,
* IndexHolder )
*/
// TODO: May be needed add traverse for index and calls?
public class ExtendedVariableReference extends Reference {
/**
* List of expressions.
*/
private List fExpressions = new ArrayList();
/**
* @param expr -
* logically expr should be instance of VariableReference.
*/
public ExtendedVariableReference(Expression expr) {
if (expr != null) {
this.addExpression(expr);
this.setStart(expr.sourceStart());
this.setEnd(expr.sourceEnd());
}
}
/**
* Return Identifier Kind.
*/
@Override
public int getKind() {
return E_IDENTIFIER;
}
/**
* Adding expression to extended variable. Use only in parsers then
* construct.
*
* @param expr
*/
public void addExpression(Expression expr) {
if (expr != null) {
this.fExpressions.add(expr);
if (expr.sourceEnd() >= this.sourceEnd()) {
setEnd(expr.sourceEnd());
}
}
}
/**
* Set Expressions. Use only in parsers then construct.
*
* @param exprs
*/
public void setExpresssions(List exprs) {
this.fExpressions = exprs;
}
/**
* Return expressions.
*
* @return
*/
public List getExpressions() {
return this.fExpressions;
}
// Checkers
/**
* tests for next element of index is call
*/
public boolean isCall(int index) {
List expressions = this.getExpressions();
if (expressions == null) {
return false;
}
if (index < expressions.size() - 1) {
Expression afterIndexExpression = (Expression) expressions
.get(index + 1);
if (afterIndexExpression instanceof CallHolder) {
return true;
}
}
return false;
}
/**
* tests for next element of index is index
*/
public boolean isIndex(int index) {
List expressions = this.getExpressions();
if (expressions == null) {
return false;
}
if (index < expressions.size() - 1) {
Expression afterIndexExpression = (Expression) expressions
.get(index + 1);
if (afterIndexExpression instanceof IndexHolder) {
return true;
}
}
return false;
}
/**
* tests for next element of index is dot
*/
public boolean isDot(int index) {
List expressions = this.getExpressions();
if (expressions == null) {
return false;
}
if (index < expressions.size() - 1) {
Expression afterIndexExpression = (Expression) expressions
.get(index + 1);
if (!(afterIndexExpression instanceof CallHolder)
&& !(afterIndexExpression instanceof IndexHolder)) {
return true;
}
}
return false;
}
/**
* Used to get name of this variable from sub names.
*/
// TODO: FIX MY PERFOMANCE
@Override
public String getStringRepresentation() {
StringBuffer b = new StringBuffer();
Iterator i = this.fExpressions.iterator();
while (i.hasNext()) {
Expression e = (Expression) i.next();
switch (e.getKind()) {
case E_IDENTIFIER:
Reference s = (Reference) e;
b.append(s.getStringRepresentation());
// TODO: Add to check for next is CallHolder, or next in
// IndexHolder.
b.append('.');
break;
// (often true)
case E_INDEX:
b.append("[]");
break;
case E_CALL:
b.append("()");
break;
case E_CURLY:
b.append("{}");
break;
}
}
return b.toString();
}
/**
* Return i'th expression. No index checking.
*
* @param i
* @return expression on i' position.
*/
public Expression getExpression(int i) {
if (this.fExpressions != null) {
return (Expression) fExpressions.get(i);
}
return null;
}
/**
* Return expressions count.
*
* @return
*/
public int getExpressionCount() {
if (this.fExpressions != null) {
return fExpressions.size();
}
return 0;
}
/**
* Return true then index == this.fExpressions.size() - 1
*
* @param index
* @return
*/
public boolean isLast(int index) {
if (this.fExpressions != null) {
return this.fExpressions.size() - 1 == index;
}
return false;
}
/**
* Testing purposes only. Print extended variable.
*/
@Override
public void printNode(CorePrinter output) {
List expressions = this.getExpressions();
boolean bFirst = true;
if (expressions != null) {
Iterator i = expressions.iterator();
while (i.hasNext()) {
Expression expr = (Expression) i.next();
if (bFirst) {
bFirst = false;
} else {
if (!(expr instanceof CallHolder)
&& !(expr instanceof IndexHolder)) {
output.formatPrintLn(".");
}
}
expr.printNode(output);
}
}
}
}