Beispiel #1
0
    def _compileDependency(self, dep, out, replacements, targetImports,
                           classList):
        classPattern = re.compile(CoffeescriptBuilder.CLASS_PATTERN)
        missingPattern = re.compile(CoffeescriptBuilder.MISSING_CLASS_PATTERN)

        #-------------------------------------------------------------------------------------------
        # MISSING DEPENDENCIES
        # Handle missing dependencies
        if not os.path.exists(dep.path):
            print("\n\n")
            self._log.write('ERROR: ' + dep.package +
                            ' package does not exist at: ' + dep.path)
            return False

        lastWhitespace = ''
        openParens = 0
        openBrackets = 0
        openBraces = 0
        skipNextLine = False
        methodName = ''
        className = ''
        registryEntry = None

        raw = dep.source
        dep.close()

        s = '\n\n\t#' + ('%' * 100) + '\n\t#' + (
            '%' * 100) + '\n#\t\t' + dep.package + '\n'

        out.write(s)
        if dep.allowCaching:
            cacheOut = open(dep.cachePath, 'w')
            cacheOut.write(s)
        else:
            try:
                if os.path.exists(dep.cachePath):
                    os.remove(dep.cachePath)
            except Exception as err:
                pass

            cacheOut = None

        self._log.write('\tCOMPILING: ' + dep.package)

        analyzer = CoffeescriptAnalyzer(raw, debug=self._debug)
        analyzer.analyze()

        #---------------------------------------------------------------------------------------
        # COMPILE
        # Line by line compile to ccs output file
        for l in analyzer:

            #-----------------------------------------------------------------------------------
            # RETARGET CLASS ACCESSORS TO VIZME registry
            # All classes (except internal class references) are made to
            # VIZME registry ClassName to prevent class conflicts.
            for rep in replacements + targetImports:
                if rep != dep:
                    offset = 0
                    res = rep.searchPattern.finditer(l.redacted)
                    for r in res:
                        start = r.start() + offset
                        end = r.end() + offset

                        if self._trace:
                            self._log.write('RETARGET: ' +
                                            l.source[start:end] + ' | ' +
                                            str(r.groupdict()))

                        # Make the replacement and adjust offsets for additional replacements
                        l.insert(start, end, rep.registryName)
                        offset += len(rep.registryName) - end + start

            #-----------------------------------------------------------------------------------
            # IDENTIFY CLASS DEFINITIONS
            # Find class definitions so they can be added to the VIZME registry.
            res = classPattern.search(l.redacted)
            if res:
                registryEntry = self._writeRegistryEntry(
                    out, cacheOut, registryEntry)
                className = res.group('class').strip()
                registryEntry = '\n%s.%s ?= %s' % (
                    CoffeescriptDependency.REGISTRY, className, className)
                classList.append(className)

            #-----------------------------------------------------------------------------------
            # CHECK FOR MISSING CLASSES
            # Search and find any missing class imports. If a possible missing import is found
            # flag it in the response.
            res = missingPattern.finditer(l.redacted)
            if res:
                for r in res:
                    cn = r.group('class').strip()
                    start = r.start()

                    if cn == className:
                        continue

                    # Ignore anything in all CAPS!
                    if cn.upper() == cn:
                        continue

                    # Ignore globally defined objects and classes
                    if cn in CoffeescriptBuilder._GLOBAL_CLASSES + analyzer.globalObjects:
                        continue

                    self._warnings.append({
                        'id': CoffeescriptBuilder._WARN_ID_MISSING_IMPORT,
                        'class': cn,
                        'line': l.lineNumber,
                        'package': dep.package
                    })

                    print('\n')
                    self._log.write(
                        'WARNING: Possible missing import\n\tmissing: %s\n\tfrom: %s [line #%s]'
                        % (cn, dep.package, str(l.lineNumber)))

            #-----------------------------------------------------------------------------------
            # LINE DEBUGGER ANALYSIS
            c = l.redacted.strip()
            skip = skipNextLine or not l.isSignificant
            skipNextLine = False

            if not skip:
                skips = [
                    'class', 'try', 'catch', 'else', 'when', '.', '+', '-',
                    '/', '=', '*', ',', 'and', 'or'
                ]
                for s in skips:
                    if c.startswith(s):
                        skip = True
                        break

            if not skip:
                skips = ['->', '=>']
                methodPattern = re.compile('^(?P<method>[^:]+)')

                for s in skips:
                    if c.endswith(s):
                        skip = True
                        res = methodPattern.search(c)
                        if res and res.group('method'):
                            methodName = res.group('method')
                        elif c.startswith('$'):
                            methodName = '$'

                        break

            # Check for line continuations
            if l.isSignificant:
                skips = ['.', '+', '-', '/', '=', '*', ',', 'and', 'or']
                for s in skips:
                    if c.endswith(s):
                        skipNextLine = True
                        break

            if self._trace:
                self._log.write(
                    c.replace('\n', '') +
                    ('\n\t@@@@ skip: ' + str(skip) + '\n\t@@@@ parens: ' +
                     str(openParens) + '\n\t@@@@ braces: ' + str(openBraces) +
                     '\n\t@@@@ brackets: ' + str(openBraces) +
                     '\n\t@@@@ skipNext: ' + str(skipNextLine)))

            if self._debug and not skip and openParens == 0 and openBraces == 0 and openBrackets == 0:
                debugLine = 'window.___vmiDebug(\'%s\', \'%s\', \'%s\', %s)\n' % \
                            (dep.package, className, methodName, str(l.lineNumber))

                indent = len(l.indent) > len(lastWhitespace)
                dedent = len(l.indent) < len(lastWhitespace)

                skips = [')', ']', '}']
                skip = False
                for s in skips:
                    if c.startswith(s):
                        skip = True
                        break

                if dedent and skip:
                    lastWhitespace = lastWhitespace
                else:
                    lastWhitespace = l.indent

                codePattern = re.compile('(?P<code>[^\s\t\n]+)')
                res = codePattern.search(c)
                if not res or len(res.groupdict()['code']) == 0:
                    if self._trace:
                        self._log.write('EMPTY: "' + c + '"')
                    debugLine = ''

                l.insert(0, 0, l.indent + debugLine)

            if l.isSignificant:
                openParens += l.redacted.count('(') - l.redacted.count(')')
                openBrackets += l.redacted.count('[') - l.redacted.count(']')
                openBraces += l.redacted.count('{') - l.redacted.count('}')

            #---------------------------------------------------------------------------------------
            # WRITE MODIFIED OUTPUT
            out.write(l.source)

            if cacheOut:
                cacheOut.write(l.source)

        self._writeRegistryEntry(out, cacheOut, registryEntry)

        if cacheOut:
            cacheOut.close()

        return True
Beispiel #2
0
    def _compileDependency(self, dep, out, replacements, targetImports, classList):
        classPattern = re.compile(CoffeescriptBuilder.CLASS_PATTERN)
        missingPattern = re.compile(CoffeescriptBuilder.MISSING_CLASS_PATTERN)

        # -------------------------------------------------------------------------------------------
        # MISSING DEPENDENCIES
        # Handle missing dependencies
        if not os.path.exists(dep.path):
            print("\n\n")
            self._log.write("ERROR: " + dep.package + " package does not exist at: " + dep.path)
            return False

        lastWhitespace = ""
        openParens = 0
        openBrackets = 0
        openBraces = 0
        skipNextLine = False
        methodName = ""
        className = ""
        registryEntry = None

        raw = dep.source
        dep.close()

        s = "\n\n\t#" + ("%" * 100) + "\n\t#" + ("%" * 100) + "\n#\t\t" + dep.package + "\n"

        out.write(s)
        if dep.allowCaching:
            cacheOut = open(dep.cachePath, "w")
            cacheOut.write(s)
        else:
            try:
                if os.path.exists(dep.cachePath):
                    os.remove(dep.cachePath)
            except Exception as err:
                pass

            cacheOut = None

        self._log.write("\tCOMPILING: " + dep.package)

        analyzer = CoffeescriptAnalyzer(raw, debug=self._debug)
        analyzer.analyze()

        # ---------------------------------------------------------------------------------------
        # COMPILE
        # Line by line compile to ccs output file
        for l in analyzer:

            # -----------------------------------------------------------------------------------
            # RETARGET CLASS ACCESSORS TO VIZME registry
            # All classes (except internal class references) are made to
            # VIZME registry ClassName to prevent class conflicts.
            for rep in replacements + targetImports:
                if rep != dep:
                    offset = 0
                    res = rep.searchPattern.finditer(l.redacted)
                    for r in res:
                        start = r.start() + offset
                        end = r.end() + offset

                        if self._trace:
                            self._log.write("RETARGET: " + l.source[start:end] + " | " + str(r.groupdict()))

                        # Make the replacement and adjust offsets for additional replacements
                        l.insert(start, end, rep.registryName)
                        offset += len(rep.registryName) - end + start

            # -----------------------------------------------------------------------------------
            # IDENTIFY CLASS DEFINITIONS
            # Find class definitions so they can be added to the VIZME registry.
            res = classPattern.search(l.redacted)
            if res:
                registryEntry = self._writeRegistryEntry(out, cacheOut, registryEntry)
                className = res.group("class").strip()
                registryEntry = "\n%s.%s ?= %s" % (CoffeescriptDependency.REGISTRY, className, className)
                classList.append(className)

            # -----------------------------------------------------------------------------------
            # CHECK FOR MISSING CLASSES
            # Search and find any missing class imports. If a possible missing import is found
            # flag it in the response.
            res = missingPattern.finditer(l.redacted)
            if res:
                for r in res:
                    cn = r.group("class").strip()
                    start = r.start()

                    if cn == className:
                        continue

                    # Ignore anything in all CAPS!
                    if cn.upper() == cn:
                        continue

                    # Ignore globally defined objects and classes
                    if cn in CoffeescriptBuilder._GLOBAL_CLASSES + analyzer.globalObjects:
                        continue

                    self._warnings.append(
                        {
                            "id": CoffeescriptBuilder._WARN_ID_MISSING_IMPORT,
                            "class": cn,
                            "line": l.lineNumber,
                            "package": dep.package,
                        }
                    )

                    print("\n")
                    self._log.write(
                        "WARNING: Possible missing import\n\tmissing: %s\n\tfrom: %s [line #%s]"
                        % (cn, dep.package, str(l.lineNumber))
                    )

            # -----------------------------------------------------------------------------------
            # LINE DEBUGGER ANALYSIS
            c = l.redacted.strip()
            skip = skipNextLine or not l.isSignificant
            skipNextLine = False

            if not skip:
                skips = ["class", "try", "catch", "else", "when", ".", "+", "-", "/", "=", "*", ",", "and", "or"]
                for s in skips:
                    if c.startswith(s):
                        skip = True
                        break

            if not skip:
                skips = ["->", "=>"]
                methodPattern = re.compile("^(?P<method>[^:]+)")

                for s in skips:
                    if c.endswith(s):
                        skip = True
                        res = methodPattern.search(c)
                        if res and res.group("method"):
                            methodName = res.group("method")
                        elif c.startswith("$"):
                            methodName = "$"

                        break

            # Check for line continuations
            if l.isSignificant:
                skips = [".", "+", "-", "/", "=", "*", ",", "and", "or"]
                for s in skips:
                    if c.endswith(s):
                        skipNextLine = True
                        break

            if self._trace:
                self._log.write(
                    c.replace("\n", "")
                    + (
                        "\n\t@@@@ skip: "
                        + str(skip)
                        + "\n\t@@@@ parens: "
                        + str(openParens)
                        + "\n\t@@@@ braces: "
                        + str(openBraces)
                        + "\n\t@@@@ brackets: "
                        + str(openBraces)
                        + "\n\t@@@@ skipNext: "
                        + str(skipNextLine)
                    )
                )

            if self._debug and not skip and openParens == 0 and openBraces == 0 and openBrackets == 0:
                debugLine = "window.___vmiDebug('%s', '%s', '%s', %s)\n" % (
                    dep.package,
                    className,
                    methodName,
                    str(l.lineNumber),
                )

                indent = len(l.indent) > len(lastWhitespace)
                dedent = len(l.indent) < len(lastWhitespace)

                skips = [")", "]", "}"]
                skip = False
                for s in skips:
                    if c.startswith(s):
                        skip = True
                        break

                if dedent and skip:
                    lastWhitespace = lastWhitespace
                else:
                    lastWhitespace = l.indent

                codePattern = re.compile("(?P<code>[^\s\t\n]+)")
                res = codePattern.search(c)
                if not res or len(res.groupdict()["code"]) == 0:
                    if self._trace:
                        self._log.write('EMPTY: "' + c + '"')
                    debugLine = ""

                l.insert(0, 0, l.indent + debugLine)

            if l.isSignificant:
                openParens += l.redacted.count("(") - l.redacted.count(")")
                openBrackets += l.redacted.count("[") - l.redacted.count("]")
                openBraces += l.redacted.count("{") - l.redacted.count("}")

            # ---------------------------------------------------------------------------------------
            # WRITE MODIFIED OUTPUT
            out.write(l.source)

            if cacheOut:
                cacheOut.write(l.source)

        self._writeRegistryEntry(out, cacheOut, registryEntry)

        if cacheOut:
            cacheOut.close()

        return True
Beispiel #3
0
        out.write(s)
        if dep.allowCaching:
            cacheOut = open(dep.cachePath, 'w')
            cacheOut.write(s)
        else:
            try:
                if os.path.exists(dep.cachePath):
                    os.remove(dep.cachePath)
            except Exception, err:
                pass

            cacheOut = None

        self._log.write('\tCOMPILING: ' + dep.package)

        analyzer = CoffeescriptAnalyzer(raw, debug=self._debug)
        analyzer.analyze()

        #---------------------------------------------------------------------------------------
        # COMPILE
        # Line by line compile to ccs output file
        for l in analyzer:

            #-----------------------------------------------------------------------------------
            # RETARGET CLASS ACCESSORS TO VIZME registry
            # All classes (except internal class references) are made to
            # VIZME registry ClassName to prevent class conflicts.
            for rep in replacements + targetImports:
                if rep != dep:
                    offset = 0
                    res    = rep.searchPattern.finditer(l.redacted)