aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorMark Miller <erights@gmail.com>2011-09-24 11:11:24 -0700
committerMark Miller <erights@gmail.com>2011-09-24 11:11:24 -0700
commit292ee6e92c05245e945a274b4849f58e424fe9b1 (patch)
tree4afa86064190f2ae4cc6937e50c26ce67c8c5ce7 /tools
parent89ab56beb7df542b11435d8a41ebb979d3c63dff (diff)
Partial conversion of an older version of convert.js to Python.
Diffstat (limited to 'tools')
-rw-r--r--tools/converter/convert.py174
1 files changed, 174 insertions, 0 deletions
diff --git a/tools/converter/convert.py b/tools/converter/convert.py
new file mode 100644
index 000000000..f4171b9fe
--- /dev/null
+++ b/tools/converter/convert.py
@@ -0,0 +1,174 @@
+#!/usr/bin/env python
+
+# Copyright 2011 by Google, Inc. All rights reserved.
+# This code is governed by the BSD license found in the LICENSE file.
+
+# Follows convert.js as closely as possible. So to minimize
+# divergence, see convert.js for doc-comments that are missing here.
+
+
+import logging
+import optparse
+import os
+from os import path
+import platform
+import re
+import subprocess
+import sys
+import tempfile
+import time
+
+# from TestCasePackagerConfig import *
+
+headerPattern = r"(?:(?:\/\/.*)?\s*\n)*"
+captureCommentPattern = r"\/\*\*?((?:\s|\S)*?)\*\/\s*\n"
+anyPattern = r"(?:\s|\S)*"
+blanksPattern = r"(?:\s|\n)*"
+
+# only until we've done our last conversion from current sputnik
+# format to canonical test262 format
+captureStrictPattern = r"\s*('use strict'|\"use strict\");"
+
+# Should match anything
+testEnvelopePattern = r"^(" + headerPattern +
+ r")(?:" + captureCommentPattern +
+ r")?(?:" + captureStrictPattern +
+ r")?(" + anyPattern +
+ r")$"
+
+registerPattern = r"^(" + anyPattern + r"?)(" +
+ r"ES5Harness\.registerTest\s*\(\s*\{" + anyPattern +
+ r"\}\s*\)" + r")" +
+ r"\s*;?(?:\s|\n)*$"
+
+Matches a named function. Captures both the name and the body.
+captureFuncNameBodyPattern = r"^function\s+(\w*)\(\s*\)\s*\{" +
+ r"(" + anyPattern + r")" +
+ r";?" + blanksPattern +
+ r"\}$"
+
+# captureExprBodyPattern = r"^return\s+" +
+# r"(" + anyPattern + r"?)" +
+# r";$"
+
+# capturePredicatePattern = r"^if\s+\((.*?)\)\s*\{" + blanksPattern +
+# r"return\s+true;?" + blanksPattern +
+# r"\}$"
+
+stars = r"\s*\n\s*\*\s?"
+
+atattrs = r"\s*\n\s*\*\s*@"
+
+
+def stripStars(text):
+ return re.sub(stars, '\n', text).strip()
+
+
+def parseTestEnvelope(src, name):
+ envelope = { 'testRecord': {} }
+ envelopeMatch = re.match(testEnvelopePattern, src)
+ if (envelopeMatch == None):
+ raise Exception('unrecognized: ' + name)
+ envelope['header'] = envelopeMatch.group(1).strip()
+ if (envelopeMatch.group(2)):
+ propTexts = re.split(atattrs, envelopeMatch.group(2))
+ envelope['commentary'] = stripStars(propTexts[0])
+ del propTexts[0]
+ for propText in propTexts:
+ # TODO: error check for mismatch
+ propName = re.match(r"^\w+", propText).group(0)
+ propVal = propText[len(propName):]
+
+ # Just till last one-time conversion
+ # strip optional initial colon or final semicolon.
+ # The initial colon is only stripped if it comes immediately
+ # after the identifier with no intervening whitespace.
+ propVal = re.sub(r"^:\s*", '', propVal, 1)
+ propVal = re.sub(r";\s*$", '', propVal, 1)
+ propVal = stripStars(propVal)
+
+ if (propName in envelope['testRecord']):
+ raise Exception('duplicate: ' + propName)
+ envelope['testRecord'][propName] = propVal;
+ if (envelopeMatch.group(3)):
+ envelope['testRecord']['strict_only'] = '';
+ envelope['rest'] = envelopeMatch.group(4) # do not trim
+
+ # Just till last one time conversion
+ registerMatch = re.match(registerPattern, envelope['rest'])
+ if (registerMatch):
+ envelope['rest'] = registerMatch.group(1).strip()
+ envelope['registerExpr'] = registerMatch.group(2).strip()
+ else if ('ES5Harness.registerTest' in envelope['rest']):
+ raise Exception('Malformed harness? ' + name)
+ return envelope
+
+
+def functionSrcToProgramSrc(funcSrc):
+ cfnbMatch = re.match(captureFuncNameBodyPattern, funcSrc)
+ if (not cfnbMatch):
+ raise Exception('Could not recognize: "' + funcSrc + '"')
+ name = cfnbMatch.group(1).strip()
+ body = cfnbMatch.group(2).strip()
+
+ # Look for special cases
+
+ cebMatch = re.match(captureExprBodyPattern, body)
+ if (cebMatch):
+ return 'assertTruthy(' + cebMatch.group(1).strip() + ');'
+
+ cpMatch = re.match(capturePredicatePattern, body)
+ if (cpMatch):
+ return 'assertTruthy(' + cpMatch.group(1).strip() + ');'
+
+ # General case
+
+ return (funcSrc + '\n' +
+ 'runTestCase(' + name + ');')
+
+
+def gatherOne(envelope, name):
+ # TODO(erights): implement by pattern match rather than evaluation
+ raise Exception('gatherOne not implemented yet')
+
+
+def transferProp(record, fromName, toName):
+ if (((toName not in testRecord) or
+ (testRecord[toName] == '')) and
+ (fromName in testRecord)):
+ testRecord[toName] = testRecord[fromName]
+ del testRecord[fromName]
+
+
+# TODO: new midcap names
+# don't mask collisions -- give errors
+# if unrecognized names remain, give errors
+def normalizeProps(testRecord):
+ if (('strict_only' not in testRecord) and
+ ('strict' in testRecord) and
+ (testRecord['strict'] == 1)):
+ testRecord['strict_only'] = ''
+
+ if (testRecord['strict'] == 1):
+ del testRecord['strict']
+
+ if ('strict_mode_negative' in testRecord):
+ if ('strict_only' not in testRecord):
+ testRecord['strict_only'] = ''
+ transferProp(testRecord, 'strict_mode_negative', 'negative')
+
+ transferProp(testRecord, 'errortype', 'negative')
+ transferProp(testRecord, 'assertion', 'description')
+ transferProp(testRecord, 'assertion', 'commentary')
+
+
+def getGlobalScopeRecord(relPath):
+ # TODO(erights): implement
+ raise Exception('getGlobalScopeRecord not implemented yet')
+
+
+def parseTestRecord(inBase, relPath, name):
+ nextRelPath = relPath + [name]
+ nextPath = inBase + [name]
+
+