<commit_before>#
# Jasy - JavaScript Tooling Refined
# Copyright 2010 <NAME>
#

import os, logging, copy, hashlib

from jasy.core.DeadCode import cleanup
from jasy.core.MetaData import MetaData
from jasy.core.Permutation import getKeys
from jasy.core.Translation import hasText
from jasy.parser.Parser import parse
from jasy.process.Compressor import compress
from jasy.process.Variables import scan

aliases = {}

__all__ = ["Class"]

class Class():
    def __init__(self, path, rel, project):
        self.__project = project
        self.__cache = project.getCache()
        self.__mtime = os.stat(path).st_mtime

        self.path = path
        self.rel = os.path.splitext(rel)[0]
        self.name = self.rel.replace("/", ".")

    def getName(self):
        return self.name
        
    def getModificationTime(self):
        return self.__mtime

    def getText(self):
        return open(self.path, mode="r", encoding="utf-8").read()


    def getTree(self, permutation=None):
        permutation = self.filterPermutation(permutation)
        
        field = "tree[%s]-%s" % (self.rel, permutation)
        tree = self.__cache.read(field, self.__mtime)
        if tree is not None:
            return tree
            
        # Parse tree
        tree = parse(self.getText(), self.rel)

        # Apply permutation
        if permutation:
            permutation.patch(tree)
            cleanup(tree)

        # Index variables
        scan(tree)
        
        self.__cache.store(field, tree, self.__mtime, True)
        return tree


    def getDependencies(self, permutation=None, classes=None):
        """ 
        Returns a set of dependencies seen through the given list of known 
        classes (ignoring all unknown items in original set) 
        """
        
        permutation = self.filterPermutation(permutation)
        
        meta = self.getMeta(permutation)
        stats = self.getStats(permutation)
        result = set()
        
        # Manually defined names/classes
        for name in meta.requires:
            if name != self.name and name in classes:
                result.add(classes[name])
        
        # Globally modified names (mostly relevant when working without namespaces)
        for name in stats.shared:
            if name != self.name and name in classes:
                result.add(classes[name])
        
        # Real filtering
        for package in stats.packages:
            if package in aliases and package in classes:
                result.add(classes[package])
            
            else:
                orig = package
                while True:
                    if package == self.name:
                        break
                
                    elif package in classes:
                        aliases[orig] = package
                        result.add(classes[package])
                        break
                
                    else:
                        pos = package.rfind(".")
                        if pos == -1:
                            break
                        
                        package = package[0:pos]
        
        return result        
        
        
    def getStats(self, permutation=None):
        permutation = self.filterPermutation(permutation)
        
        field = "stats[%s]-%s" % (self.rel, permutation)
        stats = self.__cache.read(field, self.__mtime)
        if stats == None:<commit_msg>Bug fix in caching logic<commit_after>#
# Jasy - JavaScript Tooling Refined
# Copyright 2010 <NAME>
#

import os, logging, copy, hashlib

from jasy.core.DeadCode import cleanup
from jasy.core.MetaData import MetaData
from jasy.core.Permutation import getKeys
from jasy.core.Translation import hasText
from jasy.parser.Parser import parse
from jasy.process.Compressor import compress
from jasy.process.Variables import scan

aliases = {}

__all__ = ["Class"]

class Class():
    def __init__(self, path, rel, project):
        self.__project = project
        self.__cache = project.getCache()
        self.__mtime = os.stat(path).st_mtime

        self.path = path
        self.rel = os.path.splitext(rel)[0]
        self.name = self.rel.replace("/", ".")

    def getName(self):
        return self.name
        
    def getModificationTime(self):
        return self.__mtime

    def getText(self):
        return open(self.path, mode="r", encoding="utf-8").read()


    def getTree(self, permutation=None):
        permutation = self.filterPermutation(permutation)
        
        field = "tree[%s]-%s" % (self.rel, permutation)
        tree = self.__cache.read(field, self.__mtime)
        if tree is not None:
            return tree
            
        # Parse tree
        tree = parse(self.getText(), self.rel)

        # Apply permutation
        if permutation:
            permutation.patch(tree)
            cleanup(tree)

        # Index variables
        scan(tree)
        
        self.__cache.store(field, tree, self.__mtime, True)
        return tree


    def getDependencies(self, permutation=None, classes=None):
        """ 
        Returns a set of dependencies seen through the given list of known 
        classes (ignoring all unknown items in original set) 
        """
        
        permutation = self.filterPermutation(permutation)
        
        meta = self.getMeta(permutation)
        stats = self.getStats(permutation)
        result = set()
        
        # Manually defined names/classes
        for name in meta.requires:
            if name != self.name and name in classes:
                result.add(classes[name])
        
        # Globally modified names (mostly relevant when working without namespaces)
        for name in stats.shared:
            if name != self.name and name in classes:
                result.add(classes[name])
        
        # Add classes from detected package access
        for package in stats.packages:
            if package in aliases:
                className = aliases[package]
                if className in classes:
                    result.add(classes[className])
                    continue
            
            orig = package
            while True:
                if package == self.name:
                    break
            
                elif package in classes:
                    aliases[orig] = package
                    result.add(classes[package])
                    break
            
                else:
                    pos = package.rfind(".")
                    if pos == -1:
                        break
                    
                    package = package[0:pos]
        
        return result        
        
        
    def getStats(self, permutation=None):
        permutation = self.filterPermutation(permutation)
        
        field = "stats[%s]-%s" % (self.rel, permutation)
        stats = self.__cache.read(field, self.__mtime)
        if stats == None:
{'fraction_non_alphanumeric': 0.08471163526535308, 'fraction_numerical': 0.0023011649647634116, 'mean_word_length': 1.6005983545250562, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5358374', 'n_tokens_mistral': 1868, 'n_tokens_neox': 1756, 'n_words': 493}