def __init__(self, scope, transInhDict, typedefDict, invEntityDict, accessDict = AccessDictionary()): self.scope = scope self.resolver = AlternativeInvokeableEntityResolver(scope, transInhDict, typedefDict, invEntityDict, accessDict) self.log = Logger().get_instance() self.refCache = {} # src_file + lineNr x reference (max. 1 element)
class ParentInvokableEntityResolver: def __init__(self, scope, transInhDict, typedefDict, invEntityDict, accessDict = AccessDictionary()): self.scope = scope self.resolver = AlternativeInvokeableEntityResolver(scope, transInhDict, typedefDict, invEntityDict, accessDict) self.log = Logger().get_instance() self.refCache = {} # src_file + lineNr x reference (max. 1 element) def addSurroundingDefinitionToCache(self, srcLoc, invEntityRef): # empty cache self.refCache = {} self.refCache[getKeyFor(srcLoc)] = invEntityRef def getSurroundingDefinitionFromCache(self, srcLoc): if self.inCache(srcLoc): return self.refCache[getKeyFor(srcLoc)] else: return None def inCache(self, srcLoc): key = getKeyFor(srcLoc) if key in self.refCache: return True else: return False ## # Retrieve a reference to the invokable entity surrounding the given # invocation or access. ## def getSurroundingDefinition(self, invOrAccess, refLoc): selection = self.resolver.select(invOrAccess.src_class, invOrAccess.src_name, invOrAccess.actualSrcParams, refLoc) surroundingEntities = [] for reference in selection: referenceLoc = reference.getLocation() for defLoc in referenceLoc.getDefinitionLocations(): if defLoc.getSourceFile() == refLoc.getSourceFile(): surroundingEntities.append(reference) if (not surroundingEntities) or (len(surroundingEntities) > 1): return None # merely one invokable entity return surroundingEntities[0] ## # Retrieve the source location of the definition # that is included at the given refLoc, which # is defined above the given refLoc, and # is the nearest one to the given refLoc. ## def getDefinitionLocation(self, invokableEntityRef, refLoc): definitionLocation = None multiLoc = invokableEntityRef.getLocation() refLineNr = int(refLoc.getStart()) nearestDefinitionLineNumber = None for defLoc in multiLoc.getDefinitionLocations(): if defLoc.getSourceFile() == refLoc.getSourceFile(): lineNr = int(refLoc.getStart()) if lineNr <= refLineNr: if (nearestDefinitionLineNumber == None) or (lineNr > nearestDefinitionLineNumber): nearestDefinitionLineNumber = lineNr definitionLocation = defLoc return definitionLocation ## # Resolve the source of an invocation/access to a definition. # # Returns whether the resolution succeeded. ## def resolveSource(self, invOrAccess): resolutionReport = invOrAccess.getReport() refLoc = SourceLocation(invOrAccess.sourceFile, invOrAccess.start, invOrAccess.start) invokableEntityRef = None if self.inCache(refLoc): invokableEntityRef = self.getSurroundingDefinitionFromCache(refLoc) else: # ensure that # is not regarded as a class name if ( invOrAccess.src_class == "#" ): invOrAccess.src_class = "" invokableEntityRef = self.getSurroundingDefinition(invOrAccess, refLoc) if invokableEntityRef == None: return False resolutionReport.setSurroundingDefinitionFound() defLoc = self.getDefinitionLocation(invokableEntityRef, refLoc) if defLoc == None: return False resolutionReport.setDefinitionLocationFound() self.fillInReferenceSource(invOrAccess, invokableEntityRef, defLoc) return True def fillInReferenceSource(self, invOrAccess, invokableEntityRef, srcLoc): invOrAccess.src_class = invokableEntityRef.getOwnerName() invOrAccess.formalSrcParams = invokableEntityRef.getFormalParameters().lstrip("(").rstrip(")") invOrAccess.src_sourceFile = srcLoc.getSourceFile() invOrAccess.src_start = srcLoc.getStart() invOrAccess.src_namespace = invokableEntityRef.getNamespaceName()