def lint_with_text(self, request, text):
        if not text.strip():
            return None
        cwd = request.cwd
        env = koprocessutils.getUserEnv()
        settingsDir = env.get("DJANGO_SETTINGS_MODULE", None)
        if not settingsDir:
            settingsDir = self._getSettingsDir(cwd)
        if settingsDir:
            # Save the current buffer to a temporary file.
            tmpFileName = tempfile.mktemp()
            fout = open(tmpFileName, 'wb')
            try:
                fout.write(text)
                fout.close()

                #XXX: How to tell whether we're using Python or Python3?
                prefName = "pythonExtraPaths"
                pythonPath =  request.prefset.getString(prefName, "")
                pythonPathEnv = env.get("PYTHONPATH", "")
                if pythonPathEnv:
                    if pythonPath:
                        pythonPath += os.pathsep + pythonPathEnv
                    else:
                        pythonPath = pythonPathEnv
                if pythonPath:
                    if sys.platform.startswith("win"):
                        pythonPath = pythonPath.replace('\\', '/')
                    env["PYTHONPATH"] = pythonPath
                elif env.has_key("PYTHONPATH"):
                    del env["PYTHONPATH"]

                results = koLintResults()
                pythonExe = self._pythonInfo.getExecutableFromDocument(request.koDoc)
                argv = [pythonExe, self._djangoLinterPath,
                        tmpFileName, settingsDir]
                p = process.ProcessOpen(argv, cwd=cwd, env=env, stdin=None)
                output, error = p.communicate()
                #log.debug("Django output: output:[%s], error:[%s]", output, error)
                retval = p.returncode
            finally:
                os.unlink(tmpFileName)
            if retval == 1:
                if error:
                    results.addResult(self._buildResult(text, error))
                else:
                    results.addResult(self._buildResult(text, "Unexpected error"))
        else:
            result = KoLintResult()
            result.lineStart = 1
            result.lineEnd = 1
            result.columnStart = 1
            result.columnEnd = 1 + len(text.splitlines(1)[0])
            result.description = "Can't find settings.py for this Django file"
            result.encodedDescription = result.description
            result.severity = result.SEV_ERROR
            results = koLintResults()
            results.addResult(result)
        return results
	def __init__(self, user_path, request, text):
		self.valid = True
		self.results = koLintResults()
		self.request = request
		self.text = text
		self.cwd = request.cwd

		if self.text:
			self.textlines = text.splitlines()
		else:
			self.textlines = [""]
			self.valid = False

		self.user_path = user_path

		if not user_path:
			self.add_internal_error(MSG_NO_PATH)
			self.valid = False

		self.coffeelint_exe = find_coffeelint(self.user_path)

		if not self.coffeelint_exe:
			self.add_internal_error(MSG_NO_COFFEELINT)
			self.valid = False

		# CoffeeLint looks for a coffeelint.json config file somewhere at or
		# above the directory of the input file. Unfortunately, we're
		# loading from tmp, not cwd.
		# The user still expects the config file in cwd (or above) to be honored,
		# so we have to do the searching ourselves. :S

		self.configfile = find_filename(self.cwd, "coffeelint.json")
Beispiel #3
0
    def lint_with_text(self, request, text):
        log.info(request)
        log.debug(text)
        if not text.strip():
            return None
        # consider adding lint preferences? maybe for compiler selection, paths, etc?
        
        n = uuid.uuid1()

        dst_name = n.hex + ".out"
        dst_path = os.path.join(request.cwd, dst_name)

        compilation_command = ['go', 'build', '-o', dst_name]
        try:
            env = koprocessutils.getUserEnv()
            results = koLintResults()

            log.info('Running ' + ' '.join(compilation_command))
            p = process.ProcessOpen(compilation_command, cwd=request.cwd, env=env, stdin=None)
            output, error = p.communicate()
            log.debug("output: output:[%s], error:[%s]", output, error)
            output = output + error
            retval = p.returncode
        finally:
            try:
                os.unlink(dst_path)
            except OSError:
                pass
        if output:
            for line in output.splitlines():
                if line[0] == '#':
                    continue
                results.addResult(self._buildResult(text, line, request.koDoc.baseName))
        return results
Beispiel #4
0
    def _parseWarnings(self, warntext, text, leadingWS):
        """Parse out warnings from the text like the following and return
        a list of KoLintResult's.

        Example output:
            t.py:3: SyntaxWarning: import * only allowed at module level
              def foo():
            t.py:1: DeprecationWarning: the regex module is deprecated; please use the re module
              import regex
        Also sometimes get lines like this:
            t.py: Token Error: ('EOF in multi-line string', (3, 6))
        Note that this is picked up in the SyntaxError processing so we can
        skip that here for now.
        """
        textlines = text.splitlines(1)
        if leadingWS:
            del textlines[0]
        warningRe = re.compile("^(?P<fname>.*?):(?P<line>\d+): (?P<desc>.*)$")
        results = koLintResults()
        for line in warntext.splitlines():
            match = warningRe.match(line)
            if match:
                # Ignore lines that don't match this, e.g. "  def foo():"
                r = KoLintResult()
                lineNo = int(match.group('line'))
                if leadingWS:
                    lineNo -= 1
                koLintResult.createAddResult(results, textlines, r.SEV_WARNING, lineNo, match.group('desc'), leadingWS)
        return results
Beispiel #5
0
    def lint_with_text(self, request, text):
        """Lint the given XML content.
        
        Raise an exception and set an error on koLastErrorService if there
        is a problem.
        """

        text = encodeRequestText(request, text)
        text = eollib.convertToEOLFormat(text, eollib.EOL_LF)
        cwd = request.cwd

        parser = expat.ParserCreate()
        results = koLintResults()
        
        try:
            # We need to remove the BOM on UTF-8 data to prevent expat from
            # crashing. We should check to see if this is still necesary
            # with every new Python version (we are at 2.0 now).
            utf8bom = u'\ufeff'.encode('utf-8')
            if text.startswith(utf8bom):
                parser.Parse(text[len(utf8bom):], 1)
            else:
                parser.Parse(text, 1)
                
        except expat.error:
            result = KoLintResult()
            result.description = "XML Error: %s" % expat.ErrorString(parser.ErrorCode)

            # find an existing, non-empty line on which to display result
            # XXX This logic should be in the LintDisplayer (should
            #     rearchitect a la Trent's lintx)
            text = eollib.convertToEOLFormat(request.content, eollib.EOL_LF)
            lines = text.split("\n")
            if parser.ErrorLineNumber > len(lines):
                lineStart = len(lines)
            else:
                lineStart = parser.ErrorLineNumber
            lineStart = parser.ErrorLineNumber
            retreated = 0
            while 1:
                if lineStart <= len(lines) and len(lines[lineStart-1]):
                    break
                elif lineStart == 0:
                    log.warn("Could not find a suitable line on which "
                             "to display lint result for line %d.",
                             parser.ErrorLineNumber)
                    return None
                else:
                    lineStart -= 1
                    retreated = 1
            if retreated:
                result.description += " (error is on line %d, but displayed "\
                                      "here)" % parser.ErrorLineNumber
            result.lineStart = result.lineEnd = lineStart

            result.columnStart = 1
            result.columnEnd = len(lines[result.lineEnd-1]) + 1
            result.severity = result.SEV_ERROR
            results.addResult(result)
        return results
    def lint_with_text(self, request, text):
        """Return a list of koILintResult's given a ISciMoz object."""
        cwd = request.cwd

        import re
        lines = text.split('\n')
        lineNum = 1
        complainRe = re.compile(r'\bself\b')
        results = koLintResults()
        for line in lines:
            # for testing, lets just bitch about the word 'self'
            print 'linting:', repr(line)
            complainMatch = complainRe.search(line)
            if complainMatch:
                r = KoLintResult()
                r.lineStart = lineNum
                r.lineEnd = lineNum
                r.columnStart = complainMatch.start() + 1
                r.columnEnd = complainMatch.end() + 1
                r.description = "I don't like you use of 'self' there pardner."
                r.severity = r.SEV_WARNING 
                results.addResult(r)
                print 'error: (%d,%d)(%d,%d): %s' %\
                    (r.lineStart, r.lineEnd, r.columnStart, r.columnEnd,
                    r.description)
            lineNum = lineNum + 1
        return results
Beispiel #7
0
def runGenericLinter(text, extension, cmd_start, err_ptns, warn_ptns, cwd, useStderr):
    tmpfilename = tempfile.mktemp() + extension
    fout = open(tmpfilename, "wb")
    fout.write(text)
    fout.close()
    cmd = cmd_start + [tmpfilename]
    try:
        p = process.ProcessOpen(cmd, cwd=cwd, env=koprocessutils.getUserEnv(), stdin=None)
        stdout, stderr = p.communicate()
        if useStderr:
            errLines = stderr.splitlines(0)  # Don't need the newlines.
        else:
            errLines = stdout.splitlines(0)  # Don't need the newlines.
        textLines = None
    except:
        log.exception("Failed to run %s, cwd %r", cmd, cwd)
        return None
    finally:
        os.unlink(tmpfilename)
    results = koLintResults()
    all_ptns = zip(err_ptns, [SEV_ERROR] * len(err_ptns)) + zip(warn_ptns, [SEV_WARNING] * len(warn_ptns))
    for line in errLines:
        for ptn, sev in all_ptns:
            m = ptn.match(line)
            if m:
                if textLines is None:
                    textLines = text.splitlines()
                m1 = _leading_ws_ptn.match(line)
                createAddResult(results, textLines, sev, m.group(1), m.group(2), m1 and m1.group(1) or None)
                break
    return results
Beispiel #8
0
    def parse(self, filepath, cwd=None):
        results = koLintResults()

        entries = []
        cmd = [self.xpcshell_exe, self.csslint_filepath, filepath]
        stdout = None

        # We only need the stdout result.
        try:
            p = process.ProcessOpen(cmd, cwd=cwd, env=self._setLDLibraryPath(),
                                    stdin=None)
            stdout, stderr = p.communicate()
            entries = json.loads(stdout or "[]")
        except:
            log.exception("Problem running xcshell: %r\n,output:%r\n", cmd, stdout)
            return results

        for entry in entries:
            # Convert to Komodo lint result object.
            #print 'entry: %r' % (entry, )
            results.addResult(KoLintResult(description=entry.get('description', ''),
                                           severity=entry.get('severity', 1),
                                           lineStart=entry.get('lineStart', 0),
                                           lineEnd=entry.get('lineEnd', -1),
                                           columnStart=entry.get('columnStart', 0),
                                           columnEnd=entry.get('columnEnd', 0)))

        return results
Beispiel #9
0
    def lint_with_text(self, request, text):
        log.info(request)
        logging.shit = [request, text]
        if not self.go_compiler:
            return
        if not text.strip():
            return None
        # consider adding lint preferences? maybe for compiler selection, paths, etc?

        # Save the current buffer to a temporary file.
        handle, tempfile_name = tempfile.mkstemp(suffix='.go', prefix='~', dir=request.cwd)
        fout = open(tempfile_name, 'wb')
        short_tempfile_name = os.path.basename(tempfile_name)
        try:
            fout.write(text)
            fout.close()
            env = koprocessutils.getUserEnv()
            results = koLintResults()
            p = process.ProcessOpen([self.go_compiler, 'build', short_tempfile_name], cwd=request.cwd, env=env, stdin=None)
            output, error = p.communicate()
            log.debug("%s output: output:[%s], error:[%s]", self.go_compiler, output, error)
            retval = p.returncode
        finally:
            os.unlink(tempfile_name)
        if retval != 0:
            if output:
                for line in output.splitlines()[1:]:
                    results.addResult(self._buildResult(text, line, tempfile_name))
            else:
                    results.addResult(self._buildResult(text, "Unexpected error"))
        return results
def ActionScriptWarnsToLintResults(warns, filename, code, status):
    defaultSeverity = ((status == 0 and KoLintResult.SEV_WARNING)
                       or KoLintResult.SEV_ERROR)
    lintResults = koLintResults()
    warnRe = re.compile(
        r'(?P<fileName>.*?):(?P<lineNum>\d+): (?:characters (?P<rangeStart>\d+)-(?P<rangeEnd>\d+))\s*:\s*(?P<message>.*)')
    for warn in warns:
        match = warnRe.search(warn)
        if match and match.group('fileName') == filename:
            lineNum = int(match.group('lineNum'))
            rangeStart = match.groupdict().get('rangeStart', None)
            rangeEnd = match.groupdict().get('rangeEnd', None)
            lr = KoLintResult()
            lr.description = match.group('message')
            lr.lineStart = lineNum
            lr.lineEnd = lineNum
            if rangeStart and rangeEnd:
                lr.columnStart = int(rangeStart) + 1
                lr.columnEnd = int(rangeEnd) + 1
            else:
                lr.columnStart = 1
                lr.columnEnd = len(lines[lr.lineStart - 1]) + 1
            lr.severity = defaultSeverity
            lintResults.addResult(lr)
        else:
            log.debug("%s: no match", warn)
    log.debug("returning %d lint results", lintResults.getNumResults())
    return lintResults
 def lint(self, request):
     text = request.content.encode(request.encoding.python_encoding_name)
     prefset = request.koDoc.getEffectivePrefs()
     ascExe = self._getInterpreter(prefset)
     if ascExe is None:
         lintResults = koLintResults()
         lr = KoLintResult()
         lr.description = "Can't find an ActionScript interpreter"
         lr.lineStart = lr.lineEnd = 1
         lr.columnStart = 1
         lr.columnEnd = 1 + len(text.splitlines()[0])
         lr.severity = KoLintResult.SEV_WARNING
         lintResults.addResult(lr)
         log.debug('no interpreter')
         return lintResults
     tmpFileName = None
     cwd = request.cwd
     if cwd:
         tmpFileName = os.path.join(cwd,
                                    "tmp_ko_aslint_ko%s.as" % (self._koVer.replace(".", "_").replace("-", "_")))
         try:
             fout = open(tmpFileName, 'wb')
             fout.write(text)
             fout.close()
         except (OSError, IOError), ex:
             tmpFileName = None
Beispiel #12
0
    def lint_with_text(self, request, text):
        results = koLintResults()
        log.debug(request)

        env = koprocessutils.getUserEnv()
        try:
            subprocess.call(['go', 'env'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
        except OSError:
            log.error('"go" binary not found!')
            results.addResult(_errorResult('"go" binary not found! (PATH=%s)' % env['PATH']))
            return results

        # ensure GOPATH is present
        if 'GOPATH' not in env:
            results.addResult(_errorResult('"GOPATH" not in environment, please check your general or project settings'))
            return results

        if not text.strip():
            return None
        # consider adding lint preferences? maybe for compiler selection, paths, etc?

        # Save the current buffer to a temporary file.
        base_temp_dir = tempfile.mkdtemp(prefix='kogo')
        temp_dir = os.path.join(base_temp_dir,'go')

        def non_go_files(dir,files):
            result = []
            for file in files:
                if not file.endswith('.go'):
                    result.append(file)
            return result

        shutil.copytree(request.cwd, temp_dir, ignore=non_go_files)

        buf = open(os.path.join(temp_dir, request.koDoc.baseName),'w')
        buf.write(text)
        buf.close()

        compilation_command = ['go', 'build']
        try:
            log.info('Running ' + ' '.join(compilation_command))
            p = process.ProcessOpen(compilation_command, cwd=temp_dir, env=env, stdin=None)
            output, error = p.communicate()
            log.debug("output: output:[%s], error:[%s]", output, error)
            retval = p.returncode
        finally:
            shutil.rmtree(base_temp_dir, ignore_errors=True)

        if retval != 0:
            all_output = output.splitlines() + error.splitlines()
            if all_output:
                for line in all_output:
                    if line and line[0] == '#':
                        continue
                    results.addResult(_buildResult(text, line, request.koDoc.baseName))
            else:
                    results.addResult(self._buildResult(text, "Unexpected error"))
        return results
Beispiel #13
0
 def lint_with_text(self, request, text):
     if not text:
         return None
     prefset = request.prefset
     if not prefset.getBooleanPref("lint_coffee_script"):
         return
     try:
         coffeeExe = which.which("coffee", path=self._userPath)
         if not coffeeExe:
             return
         if sys.platform.startswith("win") and os.path.exists(coffeeExe + ".cmd"):
             coffeeExe += ".cmd"
     except which.WhichError:
         msg = "coffee not found"
         if msg not in _complained:
             _complained[msg] = None
             log.error(msg)
         return
     tmpfilename = tempfile.mktemp() + '.coffee'
     fout = open(tmpfilename, 'wb')
     fout.write(text)
     fout.close()
     textlines = text.splitlines()
     cwd = request.cwd
     cmd = [coffeeExe, "-l", "-c", tmpfilename]
     # We only need the stderr result.
     try:
         p = process.ProcessOpen(cmd, cwd=cwd, stdin=None)
         _, stderr = p.communicate()
         warnLines = stderr.splitlines(0) # Don't need the newlines.
     except:
         log.exception("Problem running %s", coffeeExe)
         warnLines = []
     finally:
         os.unlink(tmpfilename)
     ptn = re.compile(r'^Error: In (.*),\s*(.*) on line (\d+):\s*(.*)')
     syntaxErrorPtn = re.compile(r'^SyntaxError: In (.*),\s*(.*) on line (\d+)')
     results = koLintResults()
     for line in warnLines:
         m = ptn.match(line)
         if m:
             part1 = m.group(2)
             lineNo = int(m.group(3))
             part2 = m.group(4)
             desc = "%s on line %d: %s" % (part1, lineNo, part2)
             severity = koLintResult.SEV_ERROR
             koLintResult.createAddResult(results, textlines, severity,
                                          lineNo, desc)
         else:
             m = syntaxErrorPtn.match(line)
             if m:
                 part1 = m.group(2)
                 lineNo = int(m.group(3))
                 desc = "SyntaxError: %s on line %d" % (part1, lineNo)
                 severity = koLintResult.SEV_ERROR
                 koLintResult.createAddResult(results, textlines, severity,
                                              lineNo, desc)
     return results
Beispiel #14
0
 def lint(self, request):
     try:
         return self._html_linter.lint(request,
                                       TPLInfo=self._tplPatterns)
     except:
         if "lint" not in self._checkValidVersion_complained:
             self._checkValidVersion_complained["lint"] = True
             log.exception("Problem in koPHPLinter.lint")
         return koLintResults()
Beispiel #15
0
 def lint(self, request):
     try:
         html_linter = UnwrapObject(self._koLintService.getLinterForLanguage("HTML"))
         return html_linter.lint(request, TPLInfo=self._tplPatterns)
     except:
         if "lint" not in self._checkValidVersion_complained:
             self._checkValidVersion_complained["lint"] = True
             log.exception("Problem in koPHPLinter.lint")
         return koLintResults()
Beispiel #16
0
    def lint_with_text(self, request, text):
        if not text:
            return None
        prefset = request.prefset
        if not prefset.getBooleanPref(self.lint_prefname):
            return
        pythonExe = self._pythonInfo.getExecutableFromPrefs(prefset)
        if not pythonExe:
            return
        try:
            checkerExe = which.which("pyflakes", path=_getUserPath())
        except which.WhichError:
            checkerExe = None
        if not checkerExe:
            log.warn("pyflakes not found")
            return
        fout, tmpfilename = _localTmpFileName()
        try:
            fout.write(text)
            fout.close()
            textlines = text.splitlines()
            cwd = request.cwd

            # For the env, don't add a PYTHONPATH entry for cwd, as it can break
            # module import lookups for pyflakes. E.g.
            #  foo/
            #    __init__.py  - an "from foo import bar" in this file will break
            env = self._get_fixed_env(prefset, cwd=None)
            
            cmd = [pythonExe, checkerExe, tmpfilename]
            # stdout for pyflakes.checker.Checker
            # stderr for __builtin__.compile()
            p = process.ProcessOpen(cmd, cwd=cwd, env=env, stdin=None)
            stdout, stderr = p.communicate()
            warnLines = []
            errorLines = []
            if p.returncode and stderr and not stdout:
                m = re.match("^(.*?):(\d+):(\d+): invalid syntax", stderr)
                if m is None:
                    _complainIfNeeded(stderr, "Error running pyflakes on file %r\n%s",
                                      request.koDoc.displayPath, stderr)
                # It's a syntax error - convert it.
                error = "%s:%s: invalid syntax (at column %s)" % (
                            m.group(1), m.group(2), m.group(3))
                errorLines = [error]
            else:
                warnLines = stdout.splitlines()
                errorLines = stderr.splitlines(0) # Don't need the newlines.
        finally:
            os.unlink(tmpfilename)
        results = koLintResults()

        # "createAddResult" will change lineno in some situation, so we use our version
        self._createAddResult(results, textlines, errorLines, koLintResult.SEV_ERROR)
        self._createAddResult(results, textlines, warnLines, koLintResult.SEV_WARNING)
        return results
Beispiel #17
0
 def lint_with_text(self, request, text):
     # log.debug("XBL text: %s", text)
     jsResults = self._js_linter.lint_with_text(request, text)
     # log.debug("XBL lint results: %s",
     #          [str(x) for x in jsResults.getResults()])
     fixedResults = koLintResults()
     for res in jsResults.getResults():
         if 'return not in function' not in res.description:
             fixedResults.addResult(res)
     return fixedResults
Beispiel #18
0
 def lint_with_text(self, request, text):
     if self._fmt_cmd_start is None:
         return
     cwd = request.cwd or None
     results = koLintResults()
     tmpfilename = tempfile.mktemp() + ".go"
     fout = open(tmpfilename, "wb")
     fout.write(text)
     fout.close()
     cmd = self._fmt_cmd_start + [tmpfilename]
     env = koprocessutils.getUserEnv()
     bad_keys = []
     for k, v in env.items():
         if not isinstance(v, (str, unicode)):
             bad_keys.append(k)
     for k in bad_keys:
         del env[k]
     try:
         p = process.ProcessOpen(cmd, cwd=cwd, env=env, stdin=None)
         stdout, stderr = p.communicate()
         if not stderr:
             return results
     except:
         log.exception("Failed to run %s, cwd %r", cmd, cwd)
         return results
     finally:
         os.unlink(tmpfilename)
     errLines = stderr.splitlines(0)  # Don't need the newlines.
     textLines = text.splitlines(0)
     for line in errLines:
         m = self._ptn_err.match(line)
         if m:
             fname = m.group(1)
             if tmpfilename not in fname:
                 continue
             lineNo = int(m.group(2))
             columnStart = int(m.group(3))
             desc = m.group(4)
             m1 = self._problem_token.search(desc)
             if m1:
                 columnEnd = columnStart + len(m1.group(1))
             else:
                 columnEnd = columnStart + 1
             result = KoLintResult(
                 description=desc,
                 severity=SEV_ERROR,
                 lineStart=lineNo,
                 lineEnd=lineNo,
                 columnStart=columnStart,
                 columnEnd=columnEnd,
             )
             results.addResult(result)
     return results
Beispiel #19
0
 def lint_with_text(self, request, text):
     if not text:
         return None
     prefset = request.prefset
     if not prefset.getBooleanPref("lint_typescript"):
         return
     try:
         tsLintExe = which.which("tslint", path=self._userPath)
         if not tsLintExe:
             return
         if sys.platform.startswith("win") and os.path.exists(tsLintExe + ".cmd"):
             tsLintExe += ".cmd"
     except which.WhichError:
         msg = "tslint not found"
         if msg not in _complained:
             _complained[msg] = None
             log.error(msg)
         return
     tmpfilename = tempfile.mktemp() + '.ts'
     fout = open(tmpfilename, 'wb')
     fout.write(text)
     fout.close()
     textlines = text.splitlines()
     cwd = request.cwd
     configfile = prefset.getStringPref("tslintConfigFile")
     if configfile:
         cmd = [tsLintExe, '-c', configfile, tmpfilename]
     else:
         cmd = [tsLintExe, tmpfilename]
     # We only need the stdout result.
     try:
         p = process.ProcessOpen(cmd, cwd=cwd, stdin=None)
         stdout, _ = p.communicate()
         warnLines = stdout.splitlines(0) # Don't need the newlines.
     except:
         log.exception("Problem running %s", tsLintExe)
         warnLines = []
     finally:
         os.unlink(tmpfilename)
     ptn = re.compile(r'^.+?\[(\d+),\s+(\d+)\]:\s+([^\r\n]+)')
     results = koLintResults()
     for line in warnLines:
         m = ptn.match(line)
         if m:
             lineNo = int(m.group(1))
             colNo = int(m.group(2))
             desc = "%s (on column %d)" % (m.group(3), colNo)
             severity = koLintResult.SEV_ERROR
             koLintResult.createAddResult(results, textlines, severity,
                                          lineNo, desc, columnStart=colNo)
     return results
 def _resetLines(self, lintResults, text):
     lines = text.splitlines()
     fixedResults = koLintResults()
     for res in lintResults.getResults():
         try:
             targetLine = lines[res.lineEnd - 1]
         except IndexError:
             log.exception("can't index %d lines at %d", len(lines), res.lineEnd - 1)
             pass # Keep the original lintResult
         else:
             if res.columnEnd > len(targetLine):
                 res.columnEnd = len(targetLine)
         fixedResults.addResult(res)
     return fixedResults
Beispiel #21
0
 def lint_with_text(self, request, text):
     linters = self._koLintService.getTerminalLintersForLanguage(self._languageName)
     finalLintResults = koLintResults()
     for linter in linters:
         try:
             newLintResults = UnwrapObject(linter).lint_with_text(request, text)
         except:
             log.exception("lint_with_text exception")
         else:
             if newLintResults and newLintResults.getNumResults():
                 if finalLintResults.getNumResults():
                     finalLintResults = finalLintResults.addResults(newLintResults)
                 else:
                     finalLintResults = newLintResults
     return finalLintResults
Beispiel #22
0
    def lint(self, request):
        text = request.content.encode("utf-8")
        tabWidth = request.koDoc.tabWidth
        log.debug("linting %s" % text[1:15])

        results = koLintResults()
        try:
            tmp_filename = tempfile.mktemp()
            fout = open(tmp_filename, "wb")
            fout.write(text)
            fout.close()
            command = 'cat(sv_quickParse("' + tmp_filename.replace("\\", "/") + '", encoding = "UTF-8"))'
            # log.debug(command)
        except Exception, e:
            log.exception(e)
 def lint_with_text(self, request, text):
     if not text:
         return None
     prefset = request.prefset
     if not prefset.getBooleanPref("lint_jsx"):
         return
     try:
         jsxHintExe = which.which("jsxhint", path=self._userPath)
         if not jsxHintExe:
             return
         if sys.platform.startswith("win") and os.path.exists(jsxHintExe + ".cmd"):
             jsxHintExe += ".cmd"
     except which.WhichError:
         msg = "jsxhint not found"
         if msg not in _complained:
             _complained[msg] = None
             log.error(msg)
         return
     tmpfilename = tempfile.mktemp() + ".jsx"
     fout = open(tmpfilename, "wb")
     fout.write(text)
     fout.close()
     textlines = text.splitlines()
     cwd = request.cwd
     cmd = [jsxHintExe, "--reporter=unix", tmpfilename]
     # We only need the stdout result.
     try:
         p = process.ProcessOpen(cmd, cwd=cwd, stdin=None)
         stdout, _ = p.communicate()
         warnLines = stdout.splitlines(0)  # Don't need the newlines.
     except:
         log.exception("Problem running %s", jsxHintExe)
         warnLines = []
     finally:
         os.unlink(tmpfilename)
     ptn = re.compile(r"^[^:]+:(\d+):(\d+): ([^\r\n]+)")
     results = koLintResults()
     for line in warnLines:
         m = ptn.match(line)
         if m:
             lineNo = int(m.group(1))
             colNo = int(m.group(2))
             desc = "%s (on column %d)" % (m.group(3), colNo)
             severity = koLintResult.SEV_ERROR
             koLintResult.createAddResult(results, textlines, severity, lineNo, desc, columnStart=colNo)
     return results
Beispiel #24
0
    def lint_with_text(self, request, text):

        if not text:
            return

        # Make the user's configured version of python available to the
        # checkers. They can start this exe in a new process or just
        # use the current interpreter.
        python = self._python.getExecutableFromDocument(request.koDoc)

        # Add the current dir so that the checkers can find relative files.
        if request.cwd not in sys.path:
            sys.path.append(request.cwd)

        # Avoid issues with windows newlines by pretending they don't exist.
        text = re.sub(r'\r\n', r'\n', text)

        text_lines = text.splitlines(True)

        results = koLintResults()

        temp_file = tempfile.NamedTemporaryFile(
            mode='w',
            suffix='.py',
            delete=False,
        )

        try:

            temp_file.write(text)
            temp_file.close()

            for checker_class in self.checker_classes:

                try:

                    checker = checker_class(request, temp_file.name, text_lines, python=python)
                    checker.add_to_results(results)

                except Exception:
                    LOG.exception('Error running %s' % checker_class.__name__)

        finally:
            os.unlink(temp_file.name)

        return results
Beispiel #25
0
    def lint_with_text(self, request, text):
        log.info(request)
        log.debug(text)
        if not text.strip():
            return None
        # consider adding lint preferences? maybe for compiler selection, paths, etc?

        # Save the current buffer to a temporary file.
        base_temp_dir = tempfile.mkdtemp(prefix='kogo')
        temp_dir = os.path.join(base_temp_dir,'go')

        def non_go_files(dir,files):
            result = []
            for file in files:
                if not file.endswith('.go'):
                    result.append(file)
            return result

        shutil.copytree(request.cwd, temp_dir, ignore=non_go_files)

        compilation_command = ['go', 'build']
        try:
            env = koprocessutils.getUserEnv()
            results = koLintResults()

            log.info('Running ' + ' '.join(compilation_command))
            p = process.ProcessOpen(compilation_command, cwd=temp_dir, env=env, stdin=None)
            output, error = p.communicate()
            log.debug("output: output:[%s], error:[%s]", output, error)
            retval = p.returncode
        finally:
            shutil.rmtree(base_temp_dir, ignore_errors=True)

        if retval != 0:
            all_output = output.splitlines() + error.splitlines()
            if all_output:
                for line in all_output:
                    if line and line[0] == '#':
                        continue
                    results.addResult(self._buildResult(text, line, request.koDoc.baseName))
            else:
                    results.addResult(self._buildResult(text, "Unexpected error"))
        return results
Beispiel #26
0
 def lint_with_text(self, request, text): #pylint: disable=R0201
     " Use the codeintel-based CSSLinter class to find error messages"
     textlines = text.splitlines()
     results = CSSLinter().lint(text, request.koDoc.language)
     lintResults = koLintResults()
     for r in results:
         if r.line_start is None:
             createAddResult(lintResults, textlines, r.status + 1,
                             len(textlines) - 1,
                             r.message)
         else:
             result = KoLintResult(description=r.message,
                                   severity=r.status + 1,
                                   lineStart=r.line_start,
                                   lineEnd=r.line_end,
                                   columnStart=r.col_start + 1,
                                   columnEnd=r.col_end + 1)
             lintResults.addResult(result)
     return lintResults
Beispiel #27
0
    def lint_with_text(self, request, text):
        self.datalines = re.split('\r\n|\r|\n',text)
        cwd = request.cwd

        self.results = koLintResults()

        fn = None
        # save buffer to a temporary file
        try:
            self.fn = fn = tempfile.mktemp()
            self.uri = URIlib.URIParser(self.fn)
            fout = open(fn, 'wb')
            fout.write(text)
            fout.close()
            
            parser = components.classes["@activestate.com/koCSSParser;1"].createInstance(components.interfaces.koICSSParser)
            parser.parseFile(fn)
            
        except Exception, e:
            log.exception(e)
Beispiel #28
0
    def lint_with_text(self, request, text):
        if not text:
            return None
        prefset = request.prefset
        if not prefset.getBooleanPref(self.lint_prefname):
            return
        pythonExe = self._pythonInfo.getExecutableFromDocument(request.koDoc)
        if not pythonExe:
            return
        try:
            checkerExe = which.which("pyflakes", path=_getUserPath())
        except which.WhichError:
            checkerExe = None
        if not checkerExe:
            log.warn("pyflakes not found")
            return
        fout, tmpfilename = _localTmpFileName()
        try:
            fout.write(text)
            fout.close()
            textlines = text.splitlines()
            cwd = request.cwd
            env = self._get_fixed_env(prefset, cwd)
            
            cmd = [pythonExe, checkerExe, tmpfilename]
            # stdout for pyflakes.checker.Checker
            # stderr for __builtin__.compile()
            p = process.ProcessOpen(cmd, cwd=cwd, env=env, stdin=None)
            stdout, stderr = p.communicate()
            errorLines = stderr.splitlines(0) # Don't need the newlines.
            warnLines = stdout.splitlines() 
        finally:
            os.unlink(tmpfilename)
        results = koLintResults()

        # "createAddResult" will change lineno in some situation, so we use our version
        self._createAddResult(results, textlines, errorLines, koLintResult.SEV_ERROR)
        self._createAddResult(results, textlines, warnLines, koLintResult.SEV_WARNING)
        return results
Beispiel #29
0
    def parse(self, filepath, cwd=None, text=None):
        results = koLintResults()

        entries = []
        cmd = [self.xpcshell_exe, self.csslint_filepath, filepath]
        stdout = None

        # We only need the stdout result.
        try:
            p = process.ProcessOpen(cmd, cwd=cwd, env=self._setEnv(),
                                    stdin=None)
            stdout, stderr = p.communicate()
            entries = json.loads(stdout or "[]")
        except:
            log.exception("Problem running xcshell: %r\n,output:%r\n", cmd, stdout)
            return results
            
        lines = text.split('\n')

        for entry in entries:
            # Convert to Komodo lint result object.
            #print 'entry: %r' % (entry, )
            line_start = entry.get('lineStart', 0)
            column_start = entry.get('columnStart', 0)
            column_end = entry.get('columnEnd', 0)
            if column_start + 1 == column_end:
                word = re.search('\\w+$', lines[line_start - 1][0:column_end - 1])
                if word:
                    column_start = word.start() + 1
            results.addResult(KoLintResult(description=entry.get('description', ''),
                                           severity=entry.get('severity', 1),
                                           lineStart=line_start,
                                           lineEnd=entry.get('lineEnd', -1),
                                           columnStart=column_start,
                                           columnEnd=column_end))

        return results
Beispiel #30
0
    def _getEncodingLintResults(self, content, encoding):
        """Return lint results for encoding errors in the given document.
        
            "content" is the document content as a unicode string
            "encoding" is the currently selected encoding for the document
        
        Returns a koLintResults instance.
        """
        try:
            encodedString = content.encode(encoding.python_encoding_name,
                                           "strict")
        except UnicodeError, ex:
            pass  # errors are handled after the try/except/else block
        else:
            return koLintResults() # no encoding errors
        
        # Find the specific errors by encoding with "replace" and finding
        # where those replacements were.
        escapedContent = content.replace('?', 'X')
        encodedString = escapedContent.encode(encoding.python_encoding_name,
                                              "replace")
        offset = 0
        indeces = []
        while 1:
            index = encodedString.find('?', offset)
            if index == -1:
                break
            indeces.append(index)
            offset = index + 1
        log.debug("encoding errors at indeces %s", indeces)
Beispiel #31
0
    def lint_with_text(self, request, text):
        """Lint the given PHP content.
        
        Raise an exception if there is a problem.
        """
        cwd = request.cwd
        
        #print "----------------------------"
        #print "PHP Lint"
        #print text
        #print "----------------------------"
        php = self.phpInfoEx.getExecutableFromDocument(request.koDoc)
        if php is None:
            errmsg = "Could not find a suitable PHP interpreter for linting."
            log.exception(errmsg)
            raise COMException(nsError.NS_ERROR_NOT_AVAILABLE, errmsg)

        if not self.checkValidVersion():
            return None

        # save php buffer to a temporary file
        phpfilename = tempfile.mktemp()
        fout = open(phpfilename, 'wb')
        fout.write(text)
        fout.close()

        p = None
        try:
            argv = [php, '-n', '-d', 'display_errors=1',
                    '-d', 'display_startup_errors=1',
                    '-d', 'output_buffering=0',
                    '-d', 'xdebug.remote_enable=off',
                    '-d', 'error_reporting=2047',
                    '-q', '-l', phpfilename]
            env = koprocessutils.getUserEnv()
            cwd = cwd or None
            p = process.ProcessOpen(argv, cwd=cwd, env=env)
            stdout, stderr = p.communicate()
            # The relevant output is contained in stdout.
            lines = stdout.splitlines(1)
        finally:
            os.unlink(phpfilename)
        
        results = koLintResults()
        if lines:
            datalines = re.split('\r\n|\r|\n',text)
            numLines = len(datalines)
            lines = [l for l in lines if l.find('error') != -1]
            
            for line in lines:
                #print line
                line = line.strip()
                # remove html from error output
                line = re.sub('<.*?>',"",line)
                lineText = line.rfind(' ')
                try:
                    lineNo = int(line[lineText+1:])
                except ValueError, e:
                    continue
                #print "Line Number: ", lineNo
                result = KoLintResult()
                # XXX error in FILENAME at line XXX
                # Previous fix (change  done for bug 42553 -- (change 254015)
                # This fix allows for either "at" or "on" between the
                # filename and the line #
                # Sample error message:
                # PHP Fatal error:  Can't use function return value in write context in C:\home\ericp\lab\komodo\bugs\bz42553a.php on line 3
                m = re.match(r'(.*?)\bin .*?(\b(?:on|at)\s+line\s+\d+)', line)
                if m:
                    result.description = string.join(m.groups())
                else:
                    result.description = line
                result.lineStart = result.lineEnd = lineNo
                result.columnStart = 1
                result.columnEnd = len(datalines[result.lineEnd-1]) + 1
                result.severity = result.SEV_ERROR
                results.addResult(result)
    def lint_with_text(self, request, text):
        encoding_name = request.encoding.python_encoding_name
        if encoding_name not in ("ascii", "utf-8"):
            try:
                # Spidermonkey will choke on latin1 file input - bug 105635 - so try
                # and use UTF-8, else fall back to the original encoding.
                utext = text.decode(request.encoding.python_encoding_name)
                text = utext.encode("utf-8")
            except UnicodeError:
                pass  # Just go with the original text then.
        jsfilename, isMacro, datalines = self._make_tempfile_from_text(
            request, text)
        cwd = request.cwd
        jsInterp = self._get_js_interp_path()

        # Lint the temp file, the jsInterp options are described here:
        # https://developer.mozilla.org/en/Introduction_to_the_JavaScript_shell
        cmd = [jsInterp, "-c"]

        # Set the JS linting preferences.
        prefset = request.prefset
        if not prefset.getBooleanPref("lintJavaScript_SpiderMonkey"):
            return
        enableWarnings = prefset.getBooleanPref('lintJavaScriptEnableWarnings')
        if enableWarnings:
            cmd.append("-w")
            enableStrict = prefset.getBooleanPref('lintJavaScriptEnableStrict')
            if enableStrict:
                cmd.append("-s")
        else:
            cmd.append("-W")

        cmd.append(jsfilename)
        cwd = cwd or None
        # We only need the stderr result.
        try:
            p = process.ProcessOpen(cmd,
                                    cwd=cwd,
                                    env=self._setLDLibraryPath(),
                                    stdin=None)
            stdout, stderr = p.communicate()
            warnLines = stderr.splitlines(0)  # Don't need the newlines.
        except:
            log.exception("Problem running CommonJSLinter")
            warnLines = []
        finally:
            os.unlink(jsfilename)

        # 'js' error reports come in 4 line chunks that look like
        # this:
        #    <filename>:8: SyntaxError: missing ; before statement:
        #    <filename>:8: ar asdf = 1;
        #
        #    <filename>:8: ...^
        #    <filename>:8: strict warning: function does not always return value:
        #    <filename>:8: strict warning:     },
        #
        #    <filename>:8: strict warning: ...^
        # There is one exception: if the file is only one line then
        # the third blank line is not there. THerefore we will strip
        # empty lines and parse 3 line chunks.
        strippedWarnLines = [line for line in warnLines if line.strip()]

        # Parse out the xpcshell lint results
        results = koLintResults()
        state = _JS_STATE_EXP_MESSAGE  # count index in 3 line groups
        # Mozilla 8 lines have a "0" after the line # -- ignore it
        headerPartRe = re.compile(r"^%s:(?P<lineNo>\d+):\d*\s*(?P<rest>.*)$" %
                                  re.escape(jsfilename))

        lineNo = desc = numDots = None
        # Implement this state machine:
        # Start => <starts with filename>
        # Message, ends with desc =>
        # Code, echoes code, not interesting =>
        # Num Dots, shows where on line error starts => Start
        i = -1
        limSub1 = len(strippedWarnLines) - 1
        while i < limSub1:
            i += 1
            line = strippedWarnLines[i]
            if not line:
                continue
            headerMatch = headerPartRe.match(line)
            if not headerMatch:
                if state == _JS_STATE_EXP_CODE:
                    desc += " " + line
                continue
            restLine = headerMatch.group("rest").strip()
            thisLineNo = int(headerMatch.group("lineNo"))
            if state == _JS_STATE_EXP_MESSAGE:
                # first line: get the error description and line number
                firstLineMatch = self._firstLineRe.match(restLine)
                if firstLineMatch:
                    lineNo = thisLineNo
                    if isMacro:
                        if lineNo > len(datalines) + 1:
                            lineNo = len(datalines)
                    errorType = firstLineMatch.group("type")
                    desc = firstLineMatch.group("desc")
                    state = _JS_STATE_EXP_CODE
                else:
                    # continue on this, it's likely just debug build output
                    msg = "Unexpected output when parsing JS syntax check(1) "\
                        "output: '%s'\n" % line
                    log.debug(msg)
                    state = _JS_STATE_EXP_MESSAGE
                continue

            if lineNo != thisLineNo:
                # This is actually the start of a new message, so log the current one,
                # and start fresh
                self._createAddResult(results, datalines, errorType, lineNo,
                                      desc, 0)
                state = _JS_STATE_EXP_MESSAGE
                desc = None
                i -= 1  # Redo this line
            elif state == _JS_STATE_EXP_CODE:
                # We don't care about this line
                state = _JS_STATE_EXP_DOTS
                continue

            # Now we should be looking at dots
            assert state == _JS_STATE_EXP_DOTS
            lastLineMatch = self._lastLineRe.search(restLine)
            if not lastLineMatch:
                lastLineMatch = self._strictLineRe.search(restLine)
                if not lastLineMatch:
                    # continue on this, it's likely just debug build output
                    msg = "Unexpected output when parsing JS syntax check(2) "\
                          "output: '%s'\n" % line
                    log.debug(msg)
                    continue
            if not desc:
                # if we don't have it, there are debug build lines
                # that have messed us up, restart at zero
                counter = _JS_STATE_EXP_MESSAGE
                continue
            # get the column of the error
            numDots = len(lastLineMatch.group("dots"))
            self._createAddResult(results, datalines, errorType, lineNo, desc,
                                  numDots)
            state = _JS_STATE_EXP_MESSAGE
            desc = None

        if desc is not None:
            self._createAddResult(results, datalines, errorType, lineNo, desc,
                                  0)
        return results
    def lint_with_text(self, request, text):
        if not text:
            #log.debug("<< no text")
            return
        prefset = request.prefset
        if not prefset.getBooleanPref("lintWithJSHint"):
            return
        jsfilename, isMacro, datalines = self._make_tempfile_from_text(
            request, text)
        jsInterp = self._get_js_interp_path()
        jsLintDir = os.path.join(self.koDirs.supportDir, "lint", "javascript")
        jsLintApp = os.path.join(jsLintDir, "lintWrapper.js")
        jsLintBasename = None
        try:
            customJSLint = prefset.getStringPref("jshint_linter_chooser")
            if customJSLint == "specific":
                p = prefset.getStringPref("jshint_linter_specific")
                if p and os.path.exists(p):
                    jsLintDir = os.path.dirname(p) + "/"
                    jsLintBasename = os.path.basename(p)
        except:
            log.exception("Problem finding the custom lintjs file")
        options = prefset.getStringPref("jshintOptions").strip()
        # Lint the temp file, the jsInterp options are described here:
        # https://developer.mozilla.org/en/Introduction_to_the_JavaScript_shell
        cmd = [jsInterp, jsLintApp, "--include=" + jsLintDir]
        if jsLintBasename:
            cmd.append("--jshint-basename=" + jsLintBasename)
        if options:
            # Drop empty parts.
            otherParts = [s for s in re.compile(r'\s+').split(options)]
            cmd += [s for s in re.compile(r'\s+').split(options)]
        if request.koDoc.language == "Node.js":
            if not "node=" in options:
                cmd.append("node=1")
        if (not self.strict_option_re.match(options)
                and 'globalstrict=' not in options):
            # jshint tests options.strict !== false, otherwise strict is on
            # Other options are tested as simply !options.strict
            cmd.append('strict=false')
        if not "esnext" in options and not "esversion" in options:
            cmd.append('esnext=true')

        fd = open(jsfilename)
        cwd = request.cwd or None
        # We only need the stderr result.
        try:
            p = process.ProcessOpen(cmd,
                                    cwd=cwd,
                                    env=self._setLDLibraryPath(),
                                    stdin=fd)
            stdout, stderr = p.communicate()
            if stderr:
                log.warn("Error in jshint: stderr: %s, command was: %s",
                         stderr, cmd)
            #log.debug("jshint: stdout: %s, stderr: %s", stdout, stderr)
            warnLines = stdout.splitlines()  # Don't need the newlines.
            i = 0
            outputStart = "++++JSHINT OUTPUT:"
            while i < len(warnLines):
                if outputStart in warnLines[i]:
                    warnLines = warnLines[i + 1:]
                    break
                i += 1
        except:
            log.exception("Problem running GenericJSLinter")
        finally:
            try:
                fd.close()
            except:
                log.error("Problem closing file des(%s)", jsfilename)
            try:
                os.unlink(jsfilename)
            except:
                log.error("Problem deleting file des(%s)", jsfilename)

        # 'jshint' error reports come in this form:
        # jshint error: at line \d+ column \d+: explanation
        results = koLintResults()
        msgRe = re.compile(
            "^jshint error: at line (?P<lineNo>\d+) column (?P<columnNo>\d+):\s*(?P<desc>.*?)$"
        )
        numDataLines = len(datalines)
        if len(warnLines) % 2 == 1:
            warnLines.append("")
        for i in range(0, len(warnLines), 2):
            msgLine = warnLines[i]
            evidenceLine = warnLines[i + 1]
            m = msgRe.match(msgLine)
            if m:
                lineNo = int(m.group("lineNo")) - 1
                if lineNo >= numDataLines:
                    lineNo = numDataLines - 1
                #columnNo = int(m.group("columnNo"))
                # build lint result object
                result = KoLintResult()
                # if the error is on the last line, work back to the last
                # character of the first nonblank line so we can display
                # the error somewhere
                if len(datalines[lineNo]) == 0:
                    while lineNo > 0 and len(datalines[lineNo - 1]) == 0:
                        lineNo -= 1
                result.columnStart = 1
                result.columnEnd = len(datalines[lineNo]) + 1
                result.lineStart = result.lineEnd = lineNo + 1
                result.severity = result.SEV_WARNING
                result.description = m.group("desc")
                results.addResult(result)

        return results
 def lint_with_text(self, request, text):
     # Pull out the EJS parts and wrap into a single JS file
     textAsBytes = text.encode("utf-8")
     lim = len(textAsBytes)
     finalPieces = ["var __ViewO = []; "]
     i = 0
     state = 0
     results = koLintResults()
     textLines = textAsBytes.splitlines()
     lineNum = 1
     haveJS = False
     while i < lim:
         if state == 0:
             idx = textAsBytes.find("<%", i)
             if idx == -1:
                 thisBit = textAsBytes[i:]
             else:
                 thisBit = textAsBytes[i:idx]
             lineNum += thisBit.count("\n")
             self._addVerbatimPieces(finalPieces, thisBit)
             if idx == -1:
                 break
             try:
                 c = textAsBytes[idx + 2]
                 if c == '=':
                     haveJS = True
                 elif c == '#':
                     haveJS = True
                 elif c == '%':
                     pass  # stay at state 0
                 else:
                     raise IndexError()
                 i = idx + 3
                 finalPieces.append("   ")
             except IndexError:
                 state = 2
                 i = idx + 2
                 finalPieces.append("  ")
         else:
             idx = textAsBytes.find("%%>", i)
             if idx >= 0:
                 finalPieces.append("   ")
                 i = idx + 3
                 continue
             idx = textAsBytes.find("%>", i)
             if idx == -1:
                 thisBit = textAsBytes[i:]
             else:
                 thisBit = textAsBytes[i:idx]
             lineNum += thisBit.count("\n")
             if state == 1:
                 self._addEmittedPieces(finalPieces, thisBit)
             elif state == 2:
                 self._addJSPieces(finalPieces, thisBit)
             else:
                 # Convert the comment block into spaces
                 finalPieces.append(self._dot_to_space_re.sub(' ', thisBit))
             finalPieces.append("  ")
             if idx == -1:
                 createAddResult(results, textLines, SEV_ERROR, lineNum,
                                 "Missing closing '%>'")
                 break
             i = idx + 2
             state = 0
     if haveJS:
         jsText = ("").join(finalPieces)
         jsResults = self._jsLinter.lint_with_text(request, jsText)
         results.addResults(jsResults)
     return results