From: <bl...@us...> - 2003-07-31 08:21:51
|
Update of /cvsroot/cpptool/rfta/src/pyrfta/test/rfta In directory sc8-pr-cvs1:/tmp/cvs-serv26696 Modified Files: alltests.py codeanalysis.py codeanalysistest.py Log Message: * added more sophisticated code analysis (still some failing test) * disabled code analysis test as focus is on the parser for the current time. Index: alltests.py =================================================================== RCS file: /cvsroot/cpptool/rfta/src/pyrfta/test/rfta/alltests.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** alltests.py 29 May 2003 14:05:56 -0000 1.1 --- alltests.py 31 Jul 2003 08:21:48 -0000 1.2 *************** *** 10,18 **** import unittest import rfta.codeanalysistest def suite(): # modules_to_test = ('rfta.codeanalysistest') # and so on alltests = unittest.TestSuite() ! alltests.addTest(unittest.findTestCases(rfta.codeanalysistest)) # for module in map(__import__, modules_to_test): # alltests.addTest(unittest.findTestCases(module)) --- 10,20 ---- import unittest import rfta.codeanalysistest + import rfta.parsertest def suite(): # modules_to_test = ('rfta.codeanalysistest') # and so on alltests = unittest.TestSuite() ! # alltests.addTest(unittest.findTestCases(rfta.codeanalysistest)) ! alltests.addTest(unittest.findTestCases(rfta.parsertest)) # for module in map(__import__, modules_to_test): # alltests.addTest(unittest.findTestCases(module)) Index: codeanalysis.py =================================================================== RCS file: /cvsroot/cpptool/rfta/src/pyrfta/test/rfta/codeanalysis.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** codeanalysis.py 30 May 2003 07:31:24 -0000 1.4 --- codeanalysis.py 31 Jul 2003 08:21:48 -0000 1.5 *************** *** 4,7 **** --- 4,10 ---- class LocalVariableDeclarator(rfta.StatementVisitor,rfta.ExpressionVisitor): + """Declare local variables and resolve all unqualified identifiers + found while walking the statements and expressions of the specified + function body""" def __init__( self, resolver ): rfta.StatementVisitor.__init__( self ) *************** *** 23,27 **** def visitDeclaratorExpression( self, expression ): for declarator in expression.getDeclarators(): ! self.resolver.declareVariable( declarator.name.identifier, expression ) def visitForStatement( self, statement ): --- 26,30 ---- def visitDeclaratorExpression( self, expression ): for declarator in expression.getDeclarators(): ! self.resolver.declareVariable( declarator.name, expression ) def visitForStatement( self, statement ): *************** *** 47,51 **** self.resolver.exitScope() ! class Identifier: def __init__( self, identifier ): self.identifier = identifier --- 50,54 ---- self.resolver.exitScope() ! class IdentifierRef: def __init__( self, identifier ): self.identifier = identifier *************** *** 55,64 **** if pos == -1: return self.identifier ! return self.identifier[pos:] ! IDTYPE_LOCALVARIABLE = 1 ! IDTYPE_IMPORTEDID = 2 class Scope: def __init__( self, parent_scope ): self.children = [] --- 58,76 ---- if pos == -1: return self.identifier ! return self.identifier[pos+2:] ! IDTYPE_LOCALVARIABLE = "local_variable" ! IDTYPE_IMPORTEDID = "using_decl" ! IDTYPE_PARAMETER = "function_parameter" ! IDTYPE_METHOD = "class_method" ! IDTYPE_ATTRIBUT = "class_attribut" ! IDTYPE_NESTED_TYPE = "class_nested_type" class Scope: + """Represents a specified scope used to resolve identifier. + + Scopes form a hierarchy. When a identifier is not resolved + by a given scope, the identifier resolution is forwarded to + the parent scope.""" def __init__( self, parent_scope ): self.children = [] *************** *** 68,72 **** def resolve( self, identifier ): ! return None def parentResolve( self, identifier ): --- 80,90 ---- def resolve( self, identifier ): ! """Resolve the specified identifier. Return a tuple of the ! form (identifier_type, declaration_element). None is returned ! if the identifier was not resolved. ! ! The specified identifier may contains nested scope (id::id::id). ! """ ! return self.parentResolve() def parentResolve( self, identifier ): *************** *** 75,90 **** return None class FunctionScope(Scope): def __init__( self, function ): Scope.__init__( self, None ) self.function = function class LocalVariableScope(Scope): def __init__( self, parent_scope ): Scope.__init__( self, parent_scope ) self.declared = {} ! def declare( self, variableName, declExpr ): ! self.declared[variableName] = declExpr def declareLocalVariable( self, variableName ): --- 93,159 ---- return None + class UsingNamespaceScope(Scope): + """Scope of a using directive (using namespace std).""" + def __init__( self, using_directive_expr, parent_scope ): + Scope.__init__( self, parent_scope ) + self.using_directive = using_directive_expr + + def resolve( self, identifier ): + # ambiguity error if both UsingNamespaceScope and parent can resolve + with_using = self.manager.resolve( self.using_directive.namespace_name.name + "::" + identifier ) + if not with_using: + return self.parentResolve( identifier ) + + class ClassImplScope(Scope): + def __init__( self, class_decl, parent_scope ): + Scope.__init__( self, parent_scope ) + self.class_decl = class_decl + + def resolve( self, identifier ): + for method in self.class_decl.getMethods(): + if method.name.name == identifier: + return (IDTYPE_METHOD, method) + for attribut in self.class_decl.getAttributs(): + if attribut.name.name == identifier: + return (IDTYPE_ATTRIBUT, attribut ) + for type in self.class_decl.getNestedTypes(): + if type.name.name == identifier: + return (IDTYPE_NESTED_TYPE, type ) + class FunctionScope(Scope): + """The scope of a function declaration. + + Resolve identifier matching the function parameters.""" def __init__( self, function ): Scope.__init__( self, None ) self.function = function + class RealFunctionScope(Scope): + """The scope of a function declaration. + + Resolve identifier matching the function parameters.""" + def __init__( self, function ): + Scope.__init__( self, None ) + self.function = function + + def resolve( self, identifier ): + for parameter in self.function.getParameters(): + if parameter.name.name == str(identifier): + return (IDTYPE_PARAMETER, parameter ) + return self.parentResolve( identifier ) + class LocalVariableScope(Scope): + """The scope of some local variables declaration. + + Resolve identifier matching the locale variable declared in + this scope.""" def __init__( self, parent_scope ): Scope.__init__( self, parent_scope ) self.declared = {} ! def declare( self, variable_name, decl_expr ): ! """Declare a local variable. ! declExpr must be the DeclarationExpression.""" ! self.declared[variable_name] = decl_expr def declareLocalVariable( self, variableName ): *************** *** 97,127 **** class UsingDeclScope(Scope): ! def __init__( self, parent_scope ): Scope.__init__( self, parent_scope ) ! self.imported = {} ! ! def importIdentifier( self, identifier ): ! imported[ Identifier(identifier).name() ] = identifier def resolve( self, identifier ): ! if declareLocalVariable( self, identifier ): ! return (IDTYPE_IMPORTEDID, imported[identifier]) return self.parentResolve( identifier ) class LocalVariableResolver: def __init__( self, function_scope ): self.current_scope = function_scope self.standard_for_scope = True - self.scope_depth = 0 self.resolved = {} ! def resolveVariable( self, variableName, variable_name_element ): ! variableDecl = self.current_scope.resolve( variableName ) ! if variableDecl: ! self.resolved[ variable_name_element ] = variableDecl ! def declareVariable( self, variableName, declExpr ): ! assert( self.scope_depth > 0 ) ! self.current_scope.declare( variableName, declExpr ) def findVariable( self, variable_name_element ): --- 166,204 ---- class UsingDeclScope(Scope): ! """Scope of using declaration (using BaseClass::function). ! ! Resolve the imported identifier.""" ! def __init__( self, parent_scope, imported_identifier, using_expr ): Scope.__init__( self, parent_scope ) ! self.identifier = imported_identifier ! self.using_expr = using_expr def resolve( self, identifier ): ! if str(identifier) == self.identifier.name(): ! return (IDTYPE_IMPORTEDID, self.using_expr) return self.parentResolve( identifier ) class LocalVariableResolver: + """Builder that creates the scope hierarchy while the code model + is traversed. Maintains the list of resolved identifiers.""" def __init__( self, function_scope ): self.current_scope = function_scope self.standard_for_scope = True self.resolved = {} + self.exit_scopes = [] ! def resolveVariable( self, variable_name, variable_name_element ): ! variable_decl = self.current_scope.resolve( variable_name ) ! if variable_decl: ! self.resolved[ variable_name_element ] = variable_decl ! def declareVariable( self, variable_name, decl_expr ): ! assert( len(self.exit_scopes) > 0 ) ! self.current_scope.declare( variable_name.identifier, decl_expr ) ! self.resolved[ variable_name ] = decl_expr ! ! def usingDeclaration( self, identifier, usingExpr ): ! using_scope = UsingDeclScope( self.current_scope, identifier, usingExpr ) ! self.current_scope = LocalVariableScope( using_scope ) def findVariable( self, variable_name_element ): *************** *** 129,139 **** def enterScope( self ): self.current_scope = LocalVariableScope( self.current_scope ) - self.scope_depth += 1 def exitScope( self ): ! assert( self.scope_depth > 0 ) ! self.scope_depth -= 1 ! self.current_scope = self.current_scope.parent_scope def enterForScope( self ): --- 206,215 ---- def enterScope( self ): + self.exit_scopes.append( self.current_scope ) self.current_scope = LocalVariableScope( self.current_scope ) def exitScope( self ): ! assert( len(self.exit_scopes) > 0 ) ! self.current_scope = self.exit_scopes.pop() def enterForScope( self ): *************** *** 144,148 **** if self.standard_for_scope: self.exitScope() - class Analyser: --- 220,223 ---- Index: codeanalysistest.py =================================================================== RCS file: /cvsroot/cpptool/rfta/src/pyrfta/test/rfta/codeanalysistest.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** codeanalysistest.py 30 May 2003 07:31:25 -0000 1.4 --- codeanalysistest.py 31 Jul 2003 08:21:48 -0000 1.5 *************** *** 87,91 **** actual_variables = [] for variable_decl in self.resolver.declareVariable.argsPassed: ! actual_variables.append( variable_decl[0] ) self.assertEqual( actual_variables, expected_variables ) --- 87,91 ---- actual_variables = [] for variable_decl in self.resolver.declareVariable.argsPassed: ! actual_variables.append( variable_decl[0].identifier ) self.assertEqual( actual_variables, expected_variables ) *************** *** 110,114 **** self.declarator.declare( self.body ) self.assertEqual( self.resolver.called, [ "enterScope", "declareVariable", "declareVariable", "exitScope" ] ) ! self.checkDeclaredVariable( ["var1", "var2" ] ) def testWhileScope( self ): --- 110,114 ---- self.declarator.declare( self.body ) self.assertEqual( self.resolver.called, [ "enterScope", "declareVariable", "declareVariable", "exitScope" ] ) ! self.checkDeclaredVariable( ['var1', 'var2'] ) def testWhileScope( self ): *************** *** 158,162 **** def setUp( self ): self.function = self.makeQuickFunctionDecl( "void", "f" ) ! self.resolver = LocalVariableResolver( FunctionScope( self.function ) ) self.declExpr1 = self.makeVariableDeclExpr( [("var1", "1"), ("var2","b"), ("var3","c")] ) self.declExpr1b = self.makeVariableDeclExpr( [("var1", "a"), ("var2","z")] ) --- 158,163 ---- def setUp( self ): self.function = self.makeQuickFunctionDecl( "void", "f" ) ! self.function_scope = FunctionScope( self.function ) ! self.resolver = LocalVariableResolver( self.function_scope ) self.declExpr1 = self.makeVariableDeclExpr( [("var1", "1"), ("var2","b"), ("var3","c")] ) self.declExpr1b = self.makeVariableDeclExpr( [("var1", "a"), ("var2","z")] ) *************** *** 165,170 **** self.declExpr3 = self.makeVariableDeclExpr( [("a", "1"), ("b","b"), ("c","c")] ) self.declExpr3b = self.makeVariableDeclExpr( [("a", "1"), ("b","b")] ) self.identifiers = {} ! for name in [ "var1", "var2", "var3", "x", "y", "z", "a", "b", "c" ]: for count in range(1,10): variable_name = name + "." + str(count) --- 166,172 ---- self.declExpr3 = self.makeVariableDeclExpr( [("a", "1"), ("b","b"), ("c","c")] ) self.declExpr3b = self.makeVariableDeclExpr( [("a", "1"), ("b","b")] ) + self.declExpr4 = self.makeVariableDeclExpr( [("vector", "x")] ) self.identifiers = {} ! for name in [ "var1", "var2", "var3", "x", "y", "z", "a", "b", "c", "vector", "string" ]: for count in range(1,10): variable_name = name + "." + str(count) *************** *** 174,180 **** pass ! def declareVariables( self, names, declExpr ): for name in names: ! self.resolver.declareVariable( name, declExpr ) def resolveVariables( self, variables ): --- 176,188 ---- pass ! def declareVariables( self, names, decl_expr ): for name in names: ! found = False ! for declarator in decl_expr.getDeclarators(): ! if declarator.name.identifier == name: ! self.resolver.declareVariable( declarator.name, decl_expr ) ! self.identifiers[ name + ".0" ] = declarator.name ! found = True ! self.assertEqual( found, True, "variable '%s' not found in the specified declaration expression" % name ) def resolveVariables( self, variables ): *************** *** 183,193 **** self.resolver.resolveVariable( variable[0], self.identifiers[id] ) ! def checkVariableResolutions( self, names, declExpr ): for name in names: self.assertEqual( self.resolver.findVariable( self.identifiers[name] ), ! (IDTYPE_LOCALVARIABLE,declExpr) ) def testConstruction( self ): self.assertEqual( self.resolver.current_scope.function, self.function ) def testResolveWithNoSubScope( self ): --- 191,229 ---- self.resolver.resolveVariable( variable[0], self.identifiers[id] ) ! def checkVariableDeclResolutions( self, names, decl_expr ): ! for name in names: ! declarator = self.findDeclarator( name, decl_expr ) ! self.assertEqual( self.resolver.findVariable( declarator.name ), ! (IDTYPE_LOCALVARIABLE,declarator.name ) ) ! ! def findDeclarator( self, name, decl_expr ): ! for declarator in decl_expr.getDeclarators(): ! if declarator.name.identifier == name: ! return declarator ! self.fail( 'no declarator found for ' + name ) ! ! def checkVariableResolutions( self, names, decl_expr ): for name in names: self.assertEqual( self.resolver.findVariable( self.identifiers[name] ), ! (IDTYPE_LOCALVARIABLE,decl_expr) ) ! ! def checkUsingDeclResolution( self, name, using_expr ): ! self.assertEqual( self.resolver.findVariable( self.identifiers[name] ), ! (IDTYPE_IMPORTEDID,using_expr) ) ! ! def checkAllScopeExited( self ): ! self.assertEqual( self.resolver.current_scope, self.function_scope ) def testConstruction( self ): self.assertEqual( self.resolver.current_scope.function, self.function ) + self.checkAllScopeExited() + + def testResolveVariableDecl( self ): + self.resolver.enterScope() + self.declareVariables( ["var1"], self.declExpr1 ) + self.resolver.exitScope() + self.checkAllScopeExited() + + self.checkVariableDeclResolutions( ["var1"], self.declExpr1 ) def testResolveWithNoSubScope( self ): *************** *** 195,203 **** self.declareVariables( ["var1", "var2", "var3"], self.declExpr1 ) self.declareVariables( ["x", "y", "z"], self.declExpr2 ) ! self.resolveVariables( [ ("var1",1), ("var2",1), ("var3",1), ("var2",2), ("var3",2), ("var3",3), ("var1",2) ] ) self.resolveVariables( [ ("x",1), ("y",1), ("x",2), ("z",1), ("z",2), ("y",1) ] ) self.resolver.exitScope() ! self.checkVariableResolutions( ["var1.1", "var2.1", "var1.2", "var2.2", "var3.1", "var3.2", "var3.3"], self.declExpr1 ) self.checkVariableResolutions( ["x.1", "x.2", "y.1", "z.1", "z.2"], self.declExpr2 ) --- 231,242 ---- self.declareVariables( ["var1", "var2", "var3"], self.declExpr1 ) self.declareVariables( ["x", "y", "z"], self.declExpr2 ) ! self.resolveVariables( [ ("var1",1), ("var2",1), ("var3",1), ("var2",2), ! ("var3",2), ("var3",3), ("var1",2) ] ) self.resolveVariables( [ ("x",1), ("y",1), ("x",2), ("z",1), ("z",2), ("y",1) ] ) self.resolver.exitScope() + self.checkAllScopeExited() ! self.checkVariableResolutions( ["var1.1", "var2.1", "var1.2", "var2.2", ! "var3.1", "var3.2", "var3.3"], self.declExpr1 ) self.checkVariableResolutions( ["x.1", "x.2", "y.1", "z.1", "z.2"], self.declExpr2 ) *************** *** 215,223 **** self.resolveVariables( [ ("var1",5), ("var2",5) ] ) self.resolver.exitScope() self.checkVariableResolutions( ["var1.1", "var1.2", "var1.5", "var2.1", "var2.2", "var2.3", "var2.4", "var2.5"], self.declExpr1 ) self.checkVariableResolutions( ["var1.3", "var1.4"], self.declExpr1b ) ! def suite(): --- 254,298 ---- self.resolveVariables( [ ("var1",5), ("var2",5) ] ) self.resolver.exitScope() + self.checkAllScopeExited() self.checkVariableResolutions( ["var1.1", "var1.2", "var1.5", "var2.1", "var2.2", "var2.3", "var2.4", "var2.5"], self.declExpr1 ) self.checkVariableResolutions( ["var1.3", "var1.4"], self.declExpr1b ) ! ! def testResolveUsing( self ): ! self.resolver.enterScope() ! using_decl_expr = self.makeTrue() # dummy place holder ! self.resolver.usingDeclaration( IdentifierRef('std::vector'), using_decl_expr ) ! self.resolveVariables( [ ("vector",1) ] ) ! self.resolver.exitScope() ! self.checkAllScopeExited() ! ! self.checkUsingDeclResolution( "vector.1", using_decl_expr ) ! ! def testResolveUsingGoesOutOfScope( self ): ! self.resolver.enterScope() ! self.declareVariables( ["vector"], self.declExpr4 ) ! self.resolveVariables( [ ("vector",1) ] ) ! self.resolver.enterScope() ! using_decl_expr = self.makeTrue() # dummy place holder ! self.resolver.usingDeclaration( IdentifierRef('std::vector'), using_decl_expr ) ! self.resolveVariables( [ ("vector",2) ] ) ! self.resolver.exitScope() ! self.resolveVariables( [ ("vector",3) ] ) ! self.resolver.exitScope() ! self.checkAllScopeExited() ! ! self.checkUsingDeclResolution( "vector.2", using_decl_expr ) ! self.checkVariableResolutions( ["vector.1", "vector.3"], self.declExpr4 ) ! ! class IdentifierTest(unittest.TestCase): ! """IdentifierRef tests""" ! ! def testName( self ): ! self.assertEqual( IdentifierRef( 'std::vector' ).name(), 'vector' ) ! self.assertEqual( IdentifierRef( 'std::tr1::vector' ).name(), 'vector' ) ! self.assertEqual( IdentifierRef( '::tr1::vector' ).name(), 'vector' ) ! self.assertEqual( IdentifierRef( '::vector' ).name(), 'vector' ) ! self.assertEqual( IdentifierRef( 'vector' ).name(), 'vector' ) def suite(): |