#!/usr/bin/env python
# Copyright (c) 2001-2002, MetaSlash Inc. All rights reserved.
"""
Module to hold manipulation of elements on the stack.
"""
import types
from pychecker import utils
DATA_UNKNOWN = "-unknown-"
LOCALS = 'locals'
# These should really be defined by subclasses
TYPE_UNKNOWN = "-unknown-"
TYPE_FUNC_RETURN = "-return-value-"
TYPE_ATTRIBUTE = "-attribute-"
TYPE_COMPARISON = "-comparison-"
TYPE_GLOBAL = "-global-"
TYPE_EXCEPT = "-except-"
class Item :
"Representation of data on the stack"
def __init__(self, data, dataType, const = 0, length = 0) :
self.data = data
self.type = dataType
self.const = const
self.length = length
self.is_really_string = 0
def __str__(self) :
if type(self.data) == types.TupleType :
value = '('
for item in self.data :
value = value + utils.safestr(item) + ', '
# strip off the ', ' for multiple items
if len(self.data) > 1 :
value = value[:-2]
return value + ')'
return utils.safestr(self.data)
def __repr__(self):
return 'Stack Item: (%r, %r, %d)' % (self.data, self.type, self.const)
def isNone(self) :
return (self.type != TYPE_UNKNOWN and self.data is None or
(self.data == 'None' and not self.const))
def isImplicitNone(self) :
return self.data is None and self.const
def isMethodCall(self, c, methodArgName):
return self.type == TYPE_ATTRIBUTE and c != None and \
len(self.data) == 2 and self.data[0] == methodArgName
def isLocals(self) :
return self.type == types.DictType and self.data == LOCALS
def setStringType(self, value = types.StringType):
self.is_really_string = value == types.StringType
def getType(self, typeMap) :
if self.type != types.StringType or self.is_really_string:
return self.type
if self.const :
return type(self.data)
if type(self.data) == types.StringType :
localTypes = typeMap.get(self.data, [])
if len(localTypes) == 1 :
return localTypes[0]
return TYPE_UNKNOWN
def getName(self) :
if self.type == TYPE_ATTRIBUTE and type(self.data) != types.StringType:
strValue = ""
# convert the tuple into a string ('self', 'data') -> self.data
for item in self.data :
strValue = '%s.%s' % (strValue, utils.safestr(item))
return strValue[1:]
return utils.safestr(self.data)
def addAttribute(self, attr) :
if type(self.data) == types.TupleType :
self.data = self.data + (attr,)
else :
self.data = (self.data, attr)
self.type = TYPE_ATTRIBUTE
def makeDict(values = (), const = 1) :
values = tuple(values)
if not values:
values = ('<on-stack>',)
return Item(values, types.DictType, const, len(values))
def makeTuple(values = (), const = 1) :
return Item(tuple(values), types.TupleType, const, len(values))
def makeList(values = [], const = 1) :
return Item(values, types.ListType, const, len(values))
def makeFuncReturnValue(stackValue, argCount) :
data = DATA_UNKNOWN
# vars() without params == locals()
if stackValue.type == TYPE_GLOBAL and \
(stackValue.data == LOCALS or
(argCount == 0 and stackValue.data == 'vars')) :
data = LOCALS
return Item(data, TYPE_FUNC_RETURN)
def makeComparison(stackItems, comparison) :
return Item((stackItems[0], comparison, stackItems[1]), TYPE_COMPARISON)
|