Beispiel #1
0
def runLint(jobconf, classes):
    def getFilteredClassList(classes, includePatt_, excludePatt_):
        # Although lint-check doesn't work with dependencies, we allow
        # '=' in class pattern for convenience; stripp those now
        intelli, explicit = textutil.splitPrefixedStrings(includePatt_)
        includePatt = intelli + explicit
        intelli, explicit = textutil.splitPrefixedStrings(excludePatt_)
        excludePatt = intelli + explicit
        if len(includePatt):
            incRegex = map(textutil.toRegExpS, includePatt)
            incRegex = re.compile("|".join(incRegex))
        else:
            incRegex = re.compile(".")  # catch-all
        if len(excludePatt):
            excRegex = map(textutil.toRegExpS, excludePatt)
            excRegex = re.compile("|".join(excRegex))
        else:
            excRegex = re.compile("^$")  # catch-none

        classesFiltered = (c for c in classes
                           if incRegex.search(c) and not excRegex.search(c))
        return classesFiltered

    # ----------------------------------------------------------------------

    if not jobconf.get('lint-check', False) or not jobconf.get(
            'lint-check/run', False):
        return

    console = Context.console
    lib_class_names = classes.keys()
    console.info("Checking Javascript source code...")
    console.indent()

    # Options
    lintJob = jobconf
    opts = lint.defaultOptions()
    opts.include_patts = lintJob.get('include', [])  # this is for future use
    opts.exclude_patts = lintJob.get('exclude', [])

    classesToCheck = list(
        getFilteredClassList(lib_class_names, opts.include_patts,
                             opts.exclude_patts))
    opts.library_classes = lib_class_names
    opts.class_namespaces = [
        x[:x.rfind(".")] for x in opts.library_classes if x.find(".") > -1
    ]
    # the next requires that the config keys and option attributes be identical (modulo "-"_")
    for option, value in lintJob.get("lint-check").items():
        setattr(opts, option.replace("-", "_"), value)

    for pos, classId in enumerate(classesToCheck):
        console.debug("Checking %s" % classId)
        tree = classes[classId].tree()
        lint.lint_check(tree, classId, opts)

    console.outdent()
def runLint(jobconf, classes):

    def getFilteredClassList(classes, includePatt_, excludePatt_):
        # Although lint-check doesn't work with dependencies, we allow
        # '=' in class pattern for convenience; stripp those now
        intelli, explicit = textutil.splitPrefixedStrings(includePatt_)
        includePatt = intelli + explicit
        intelli, explicit = textutil.splitPrefixedStrings(excludePatt_)
        excludePatt = intelli + explicit
        if len(includePatt):
            incRegex = map(textutil.toRegExpS, includePatt)
            incRegex = re.compile("|".join(incRegex))
        else:
            incRegex = re.compile(".")  # catch-all
        if len(excludePatt):
            excRegex = map(textutil.toRegExpS, excludePatt)
            excRegex = re.compile("|".join(excRegex))
        else:
            excRegex = re.compile("^$")  # catch-none

        classesFiltered = (c for c in classes if incRegex.search(c) and not excRegex.search(c))
        return classesFiltered

    # ----------------------------------------------------------------------

    if not jobconf.get('lint-check', False) or not jobconf.get('lint-check/run', False):
        return

    console = Context.console
    lib_class_names = classes.keys()
    console.info("Checking Javascript source code...")
    console.indent()

    # Options
    lintJob        = jobconf
    opts = lint.defaultOptions()
    opts.include_patts    = lintJob.get('include', [])  # this is for future use
    opts.exclude_patts    = lintJob.get('exclude', [])

    classesToCheck = list(getFilteredClassList(lib_class_names, opts.include_patts, opts.exclude_patts))
    opts.library_classes  = lib_class_names
    opts.class_namespaces = [x[:x.rfind(".")] for x in opts.library_classes if x.find(".")>-1]
    # the next requires that the config keys and option attributes be identical (modulo "-"_")
    for option, value in lintJob.get("lint-check").items():
        setattr(opts, option.replace("-","_"), value)

    for pos, classId in enumerate(classesToCheck):
        console.debug("Checking %s" % classId)
        tree = classes[classId].tree()
        lint.lint_check(tree, classId, opts)

    console.outdent()
 def lint_warnings(self, lint_opts):
     classInfo, mTime = self._getClassCache()
     if (not 'lint-basics' in classInfo
         and True):  # not up-to-date?! when is the class cache invalidated?!
         warns = lint.lint_check(self.tree(), self.id, lint_opts)
         classInfo['lint-basics'] = (warns, time.time())
         self._writeClassCache(classInfo)
     return classInfo['lint-basics'][0]
Beispiel #4
0
def do_lint(file_, popup):
    if popup:
        logger = util.PopupLogger()
    else:
        logger = util.TextMateLogger()

    logger.printHeader("qooxdoo JavaScript lint", "qooxdoo JavaScript lint")
    try:
        opts = lint.defaultOptions()
        opts.allowed_globals = ['qx', 'qxWeb', 'q']

        tree_ = treegenerator.createFileTree_from_string(
            codecs.open(file_, "r", "utf-8").read())
        tree_ = scopes.create_scopes(tree_)
        if not getattr(context, 'console', None):
            context.console = Log()
        if not getattr(context, 'jobconf', None):
            context.jobconf = ExtMap()
        context.jobconf.set("lint-check/warn-unknown-jsdoc-keys", True)
        lint.lint_check(tree_, "", opts)

    except treegenerator.SyntaxException, e:
        logger.log(file_, 0, 0, str(e))
Beispiel #5
0
def main(argv=None):

    # init Context module
    Context.console = Log()
    Context.jobconf = {}

    if argv is None:
        argv = sys.argv

    parser = OptionParser(
        description="Checks ECMAScript/JavaScript files for common errors.")
    parser.add_option(
        "--action",
        "-a",
        dest="actions",
        metavar="ACTION",
        choices=[
            "ALL", "undefined_variables", "unused_variables",
            "multidefined_variables", "maps", "blocks", "fields"
        ],
        action="append",
        default=[],
        help=
        """Performs the given checks on the input files. This parameter may be supplied multiple times.
Valid arguments are: "ALL" (default): Perform all checks
"undefined_variables": Look for identifier, which are referenced in the global scope. This action can find
misspelled identifier and missing 'var' statements. You can use the '-g' flag to add valid global identifiers.
  "unused_variables": Look for identifier, which are defined but never used.
  "multidefined_variables": Look for identifier, which are defined multiple times.
  "blocks" : Look for single statments in bodies of if's and loops that are not enclosed by braces.
  "fields" : Look for class attributes, checking definedness, privates and protected fields.
  "maps": Look for duplicate keys in map declarations. """)
    parser.add_option("-g",
                      dest="globals",
                      help="Add an allowed global identifier GLOBAL",
                      metavar="GLOBAL",
                      action="append",
                      default=[])

    (options, args) = parser.parse_args(argv)

    if len(args) == 1:
        parser.print_help()
        sys.exit(1)

    if options.globals:
        globals_ = options.globals
    else:
        globals_ = []

    checkAll = "ALL" in options.actions or len(options.actions) == 0

    # construct opts argument for lint_check
    keys_map ={  # map cli 'action' keys to lint.options
        "undefined_variables"    : ["ignore_undefined_globals"],
        "unused_variables"       : ["ignore_unused_variables", "ignore_unused_parameter"],
        "multidefined_variables" : ["ignore_multiple_vardecls"],
        "maps"   : ["ignore_multiple_mapkeys"],
        "blocks" : ["ignore_no_loop_block"],
        "fields" : ["ignore_reference_fields", "ignore_undeclared_privates"],
    }
    opts = lint.defaultOptions()
    opts.allowed_globals = options.globals
    for opt in (o for o in vars(opts) if o.startswith("ignore_")):
        if checkAll:
            setattr(opts, opt, False)
        else:
            for argopt in keys_map:
                if argopt in options.actions and opt in keys_map[argopt]:
                    setattr(opts, opt, False)
                    break
            else:
                setattr(opts, opt, True)

    for filename in args[1:]:
        tree_ = treegenerator.createFileTree_from_string(
            codecs.open(filename, "r", "utf-8").read())
        tree_ = scopes.create_scopes(tree_)
        lint.lint_check(tree_, filename, opts)

    return  ## TODO: rc
Beispiel #6
0
def lint_check(classObj, opts):
    tree = classObj.tree()
    return lint.lint_check(tree, classObj.id, opts)
Beispiel #7
0
            # annotate scopes reg. load time evaluation
            if True:
                if hasattr(tree,'scope') and tree.scope:
                    console.outdent()
                    console.debug("Annotating scopes with load time information: %s..." % self.id)
                    console.indent()
                    load_time.load_time_check(tree.scope)

            # lint check
            if False:  # currently done in MClassDependencies, due to global classList
                console.outdent()
                console.debug("Checking JavaScript source code: %s..." % self.id)
                console.indent()
                # construct parse-level check options
                opts = lint.defaultOptions()
                lint.lint_check(tree, self.id, opts)

            # store unoptimized tree
            cache.write(cacheId, tree, memory=tradeSpaceForSpeed)

            console.outdent()
        return tree


    ##
    # Raises in case of inconsistencies, otherwise returns None
    #
    def checkClassId(self, tree):
        className = None  # not-found return value
        filePathId = self.id
        qxDefine = treeutil.findQxDefine(tree)
Beispiel #8
0
                    console.outdent()
                    console.debug(
                        "Annotating scopes with load time information: %s..." %
                        self.id)
                    console.indent()
                    load_time.load_time_check(tree.scope)

            # lint check
            if False:  # currently done in MClassDependencies, due to global classList
                console.outdent()
                console.debug("Checking JavaScript source code: %s..." %
                              self.id)
                console.indent()
                # construct parse-level check options
                opts = lint.defaultOptions()
                lint.lint_check(tree, self.id, opts)

            # store unoptimized tree
            cache.write(cacheId, tree, memory=tradeSpaceForSpeed)

            console.outdent()
        return tree

    ##
    # Raises in case of inconsistencies, otherwise returns None
    #
    def checkClassId(self, tree):
        className = None  # not-found return value
        filePathId = self.id
        qxDefine = treeutil.findQxDefine(tree)
        if qxDefine:
        def buildShallowDeps(tree=None):

            load = []
            run = []
            ignore = [
                DependencyItem(x, '', "|DefaultIgnoredNamesDynamic|")
                for x in self.defaultIgnoredNamesDynamic
            ]

            console.debug("Analyzing tree: %s" % self.id)
            console.indent()

            # Read meta data
            meta = self.getHints()
            metaLoad = meta.get("loadtimeDeps", [])
            metaRun = meta.get("runtimeDeps", [])
            metaOptional = meta.get("optionalDeps", [])
            metaIgnore = meta.get("ignoreDeps", [])
            metaIgnore.extend(metaOptional)

            # regexify globs in metaignore
            metaIgnore = map(MetaIgnore, metaIgnore)

            # Turn strings into DependencyItems()
            for target, metaHint in ((load, metaLoad), (run, metaRun),
                                     (ignore, metaIgnore)):
                for key in metaHint:
                    # add all feature checks if requested
                    if key == "feature-checks" and metaHint in (metaLoad,
                                                                metaRun):
                        target.extend(
                            self.getAllEnvChecks(-1, metaHint == metaLoad))
                    # turn an entry into a DependencyItem
                    elif isinstance(key, types.StringTypes):
                        sig = key.split('#', 1)
                        className = sig[0]
                        attrName = sig[1] if len(sig) > 1 else ''
                        target.append(
                            DependencyItem(className, attrName, self.id,
                                           "|hints|"))

            # Read source tree data
            if not tree:
                if variantSet:  # a filled variantSet map means that "variants" optimization is wanted
                    tree = self.optimize(None, ["variants"], variantSet)
                else:
                    tree = self.tree()

            # do lint checking here, as we have a classList ("ClassesAll") to check globals against
            if True:
                # construct parse-level lint options
                opts = lint.defaultOptions()
                opts.library_classes = ClassesAll.keys()
                opts.class_namespaces = ClassList.namespaces_from_classnames(
                    opts.library_classes)
                # some sensible settings (deviating from defaultOptions)
                opts.ignore_no_loop_block = True
                opts.ignore_reference_fields = True
                opts.ignore_undeclared_privates = True
                opts.ignore_unused_variables = True
                # override from config
                jobConf = Context.jobconf
                for option, value in jobConf.get("lint-check", {}).items():
                    setattr(opts, option.replace("-", "_"), value)
                lint.lint_check(tree, self.id, opts)

            # analyze tree
            treeDeps = []  # will be filled by _analyzeClassDepsNode
            self._analyzeClassDepsNode(tree, treeDeps, inLoadContext=True)

            # Process source tree data
            for dep in treeDeps:
                if dep.isLoadDep:
                    if "auto-require" not in metaIgnore:
                        item = dep.name
                        if item in metaIgnore:
                            pass
                        elif item in metaLoad:
                            console.warn("%s: #require(%s) is auto-detected" %
                                         (self.id, item))
                        else:
                            # adding all items to list (the second might have needsRecursion)
                            load.append(dep)

                else:  # runDep
                    if "auto-use" not in metaIgnore:
                        item = dep.name
                        if item in metaIgnore:
                            pass
                        #elif item in (x.name for x in load):
                        #    pass
                        elif item in metaRun:
                            console.warn("%s: #use(%s) is auto-detected" %
                                         (self.id, item))
                        else:
                            # adding all items to list (to comply with the 'load' deps)
                            run.append(dep)

            console.outdent()

            # Build data structure
            deps = {
                "load": load,
                "run": run,
                "ignore": ignore,
            }

            return deps
        def buildShallowDeps(tree=None):

            load   = []
            run    = []
            ignore = [DependencyItem(x, '', "|DefaultIgnoredNamesDynamic|") for x in self.defaultIgnoredNamesDynamic]

            console.debug("Analyzing tree: %s" % self.id)
            console.indent()

            # Read meta data
            meta         = self.getHints()
            metaLoad     = meta.get("loadtimeDeps", [])
            metaRun      = meta.get("runtimeDeps" , [])
            metaOptional = meta.get("optionalDeps", [])
            metaIgnore   = meta.get("ignoreDeps"  , [])
            metaIgnore.extend(metaOptional)

            # regexify globs in metaignore
            metaIgnore = map(MetaIgnore, metaIgnore)

            # Turn strings into DependencyItems()
            for target,metaHint in ((load,metaLoad), (run,metaRun), (ignore,metaIgnore)):
                for key in metaHint:
                    # add all feature checks if requested
                    if key == "feature-checks" and metaHint in (metaLoad, metaRun):
                        target.extend(self.getAllEnvChecks(-1, metaHint==metaLoad))
                    # turn an entry into a DependencyItem
                    elif isinstance(key, types.StringTypes):
                        sig = key.split('#',1)
                        className = sig[0]
                        attrName  = sig[1] if len(sig)>1 else ''
                        target.append(DependencyItem(className, attrName, self.id, "|hints|"))

            # Read source tree data
            if not tree:
                if variantSet: # a filled variantSet map means that "variants" optimization is wanted
                    tree = self.optimize(None, ["variants"], variantSet)
                else:
                    tree = self.tree()

            # do lint checking here, as we have a classList ("ClassesAll") to check globals against
            if True:
                # construct parse-level lint options
                opts = lint.defaultOptions()
                opts.library_classes = ClassesAll.keys()
                opts.class_namespaces = ClassList.namespaces_from_classnames(opts.library_classes)
                # some sensible settings (deviating from defaultOptions)
                opts.ignore_no_loop_block = True
                opts.ignore_reference_fields = True
                opts.ignore_undeclared_privates = True
                opts.ignore_unused_variables = True
                # override from config
                jobConf = Context.jobconf
                for option, value in jobConf.get("lint-check", {}).items():
                    setattr(opts, option.replace("-","_"), value)
                lint.lint_check(tree, self.id, opts)

            # analyze tree
            treeDeps  = []  # will be filled by _analyzeClassDepsNode
            self._analyzeClassDepsNode(tree, treeDeps, inLoadContext=True)

            # Process source tree data
            for dep in treeDeps:
                if dep.isLoadDep:
                    if "auto-require" not in metaIgnore:
                        item = dep.name
                        if item in metaIgnore:
                            pass
                        elif item in metaLoad:
                            console.warn("%s: #require(%s) is auto-detected" % (self.id, item))
                        else:
                            # adding all items to list (the second might have needsRecursion)
                            load.append(dep)

                else: # runDep
                    if "auto-use" not in metaIgnore:
                        item = dep.name
                        if item in metaIgnore:
                            pass
                        #elif item in (x.name for x in load):
                        #    pass
                        elif item in metaRun:
                            console.warn("%s: #use(%s) is auto-detected" % (self.id, item))
                        else:
                            # adding all items to list (to comply with the 'load' deps)
                            run.append(dep)

            console.outdent()

            # Build data structure
            deps = {
                "load"   : load,
                "run"    : run,
                "ignore" : ignore,
            }

            return deps
Beispiel #11
0
def main(argv=None):

    # init Context module
    Context.console = Log()
    Context.jobconf = {}

    if argv is None:
        argv = sys.argv

    parser = OptionParser(description="Checks ECMAScript/JavaScript files for common errors.")
    parser.add_option(
        "--action", "-a", dest="actions", metavar="ACTION",
        choices=["ALL", "undefined_variables", "unused_variables", "multidefined_variables", "maps", "blocks", "fields"], action="append", default=[],
        help="""Performs the given checks on the input files. This parameter may be supplied multiple times.
Valid arguments are: "ALL" (default): Perform all checks
"undefined_variables": Look for identifier, which are referenced in the global scope. This action can find
misspelled identifier and missing 'var' statements. You can use the '-g' flag to add valid global identifiers.
  "unused_variables": Look for identifier, which are defined but never used.
  "multidefined_variables": Look for identifier, which are defined multiple times.
  "blocks" : Look for single statments in bodies of if's and loops that are not enclosed by braces.
  "fields" : Look for class attributes, checking definedness, privates and protected fields.
  "maps": Look for duplicate keys in map declarations. """
    )
    parser.add_option(
        "-g", dest="globals", help="Add an allowed global identifier GLOBAL",
        metavar="GLOBAL", action="append", default=[]
    )

    (options, args) = parser.parse_args(argv)

    if len(args) == 1:
        parser.print_help()
        sys.exit(1)

    if options.globals:
        globals_ = options.globals
    else:
        globals_ = []

    checkAll = "ALL" in options.actions or len(options.actions) == 0

    # construct opts argument for lint_check
    keys_map ={  # map cli 'action' keys to lint.options
        "undefined_variables"    : ["ignore_undefined_globals"], 
        "unused_variables"       : ["ignore_unused_variables", "ignore_unused_parameter"],
        "multidefined_variables" : ["ignore_multiple_vardecls"], 
        "maps"   : ["ignore_multiple_mapkeys"], 
        "blocks" : ["ignore_no_loop_block"], 
        "fields" : ["ignore_reference_fields", "ignore_undeclared_privates"],
    }
    opts = lint.defaultOptions()
    opts.allowed_globals = options.globals
    for opt in (o for o in vars(opts) if o.startswith("ignore_")):
        if checkAll:
            setattr(opts, opt, False)
        else:
            for argopt in keys_map:
                if argopt in options.actions and opt in keys_map[argopt]:
                    setattr(opts, opt, False)
                    break
            else:
                setattr(opts, opt, True)


    for filename in args[1:]:
        tree_ = treegenerator.createFileTree_from_string(codecs.open(filename, "r", "utf-8").read())
        tree_ = scopes.create_scopes(tree_)
        lint.lint_check(tree_, filename, opts)

    return ## TODO: rc
Beispiel #12
0
def lint_check(classObj, opts):
    tree = classObj.tree()
    return lint.lint_check(tree, classObj.id, opts)
Beispiel #13
0
class MClassCode(object):

    # --------------------------------------------------------------------------
    #   Tree Interface
    # --------------------------------------------------------------------------

    ##
    # Interface method. Delivers class syntax tree:
    # - handles cache
    # - can be called with alternative parser (treegenerator)
    #
    def tree(self, treegen=treegenerator, force=False):

        cache = self.context['cache']
        console = self.context['console']
        tradeSpaceForSpeed = False  # Caution: setting this to True seems to make builds slower, at least on some platforms!?
        cacheId = "tree%s-%s-%s" % (treegen.tag, self.path, util.toString({}))
        self.treeId = cacheId

        # Lookup for unoptimized tree
        tree, _ = cache.read(cacheId, self.path, memory=tradeSpaceForSpeed)

        # Tree still undefined?, create it!
        if tree == None or force:
            console.debug("Parsing file: %s..." % self.id)
            console.indent()

            # tokenize
            fileContent = filetool.read(self.path, self.encoding)
            fileId = self.path if self.path else self.id
            try:
                tokens = tokenizer.parseStream(fileContent, self.id)
            except SyntaxException, e:
                # add file info
                e.args = (e.args[0] + "\nFile: %s" % fileId,) + e.args[1:]
                raise e
            
            # parse
            console.outdent()
            console.debug("Generating tree: %s..." % self.id)
            console.indent()
            try:
                tree = treegen.createFileTree(tokens, fileId)
            except SyntaxException, e:
                # add file info
                e.args = (e.args[0] + "\nFile: %s" % fileId,) + e.args[1:]
                raise e

            # annotate with scopes
            if True:
                console.outdent()
                console.debug("Calculating scopes: %s..." % self.id)
                console.indent()
                tree = scopes.create_scopes(tree)
                #if self.id == "gui.Application":
                #    import pydb; pydb.debugger()
                #tree.scope.prrnt()

            # lint check
            if False:
                console.outdent()
                console.debug("Checking JavaScript source code: %s..." % self.id)
                console.indent()
                # construct parse-level check options
                opts = lint.defaultOptions()
                lint.lint_check(tree, self.id, opts)

            # store unoptimized tree
            cache.write(cacheId, tree, memory=tradeSpaceForSpeed)

            console.outdent()