diff options
author | Steven Knight <knight@baldmt.com> | 2003-05-09 20:34:37 (GMT) |
---|---|---|
committer | Steven Knight <knight@baldmt.com> | 2003-05-09 20:34:37 (GMT) |
commit | 3ff79698a1d206f9be1804376004777c6c7f7929 (patch) | |
tree | e34f3b4515444d2effd07c0caea091dc353ae4d0 /src/engine/SCons/Tool/javac.py | |
parent | d5aff94f2c90a162e2c36775b0fc80cabdc7ad64 (diff) | |
download | SCons-3ff79698a1d206f9be1804376004777c6c7f7929.zip SCons-3ff79698a1d206f9be1804376004777c6c7f7929.tar.gz SCons-3ff79698a1d206f9be1804376004777c6c7f7929.tar.bz2 |
Split the Java parser into a JavaCommon.py module.
Diffstat (limited to 'src/engine/SCons/Tool/javac.py')
-rw-r--r-- | src/engine/SCons/Tool/javac.py | 188 |
1 files changed, 2 insertions, 186 deletions
diff --git a/src/engine/SCons/Tool/javac.py b/src/engine/SCons/Tool/javac.py index be600f1..3d4df10 100644 --- a/src/engine/SCons/Tool/javac.py +++ b/src/engine/SCons/Tool/javac.py @@ -40,191 +40,7 @@ import string import SCons.Builder from SCons.Node.FS import _my_normcase - -java_parsing = 1 - -if java_parsing: - # Parse Java files for class names. - # - # This is a really cool parser from Charles Crain - # that finds appropriate class names in Java source. - - # A regular expression that will find, in a java file, - # any alphanumeric token (keyword, class name, specifier); open or - # close brackets; a single-line comment "//"; the multi-line comment - # begin and end tokens /* and */; single or double quotes; and - # single or double quotes preceeded by a backslash. - _reToken = re.compile(r'(//[^\r\n]*|\\[\'"]|[\'"\{\}]|[A-Za-z_][\w\.]*|' + - r'/\*|\*/)') - - class OuterState: - """The initial state for parsing a Java file for classes, - interfaces, and anonymous inner classes.""" - def __init__(self): - self.listClasses = [] - self.listOutputs = [] - self.stackBrackets = [] - self.brackets = 0 - self.nextAnon = 1 - self.package = None - - def __getClassState(self): - try: - return self.classState - except AttributeError: - ret = ClassState(self) - self.classState = ret - return ret - - def __getPackageState(self): - try: - return self.packageState - except AttributeError: - ret = PackageState(self) - self.packageState = ret - return ret - - def __getAnonClassState(self): - try: - return self.anonState - except AttributeError: - ret = SkipState(1, AnonClassState(self)) - self.anonState = ret - return ret - - def __getSkipState(self): - try: - return self.skipState - except AttributeError: - ret = SkipState(1, self) - self.skipState = ret - return ret - - def parseToken(self, token): - if token[:2] == '//': - pass # ignore comment - elif token == '/*': - return IgnoreState('*/', self) - elif token == '{': - self.brackets = self.brackets + 1 - elif token == '}': - self.brackets = self.brackets - 1 - if len(self.stackBrackets) and \ - self.brackets == self.stackBrackets[-1]: - self.listOutputs.append(string.join(self.listClasses, '$')) - self.listClasses.pop() - self.stackBrackets.pop() - elif token == '"' or token == "'": - return IgnoreState(token, self) - elif token == "new": - # anonymous inner class - if len(self.listClasses) > 0: - return self.__getAnonClassState() - return self.__getSkipState() # Skip the class name - elif token == 'class' or token == 'interface': - if len(self.listClasses) == 0: - self.nextAnon = 1 - self.stackBrackets.append(self.brackets) - return self.__getClassState() - elif token == 'package': - return self.__getPackageState() - return self - - def addAnonClass(self): - """Add an anonymous inner class""" - clazz = self.listClasses[0] - self.listOutputs.append('%s$%d' % (clazz, self.nextAnon)) - self.brackets = self.brackets + 1 - self.nextAnon = self.nextAnon + 1 - - def setPackage(self, package): - self.package = package - - class AnonClassState: - """A state that looks for anonymous inner classes.""" - def __init__(self, outer_state): - # outer_state is always an instance of OuterState - self.outer_state = outer_state - self.tokens_to_find = 2 - def parseToken(self, token): - # This is an anonymous class if and only if the next token is a bracket - if token == '{': - self.outer_state.addAnonClass() - return self.outer_state - - class SkipState: - """A state that will skip a specified number of tokens before - reverting to the previous state.""" - def __init__(self, tokens_to_skip, old_state): - self.tokens_to_skip = tokens_to_skip - self.old_state = old_state - def parseToken(self, token): - self.tokens_to_skip = self.tokens_to_skip - 1 - if self.tokens_to_skip < 1: - return self.old_state - return self - - class ClassState: - """A state we go into when we hit a class or interface keyword.""" - def __init__(self, outer_state): - # outer_state is always an instance of OuterState - self.outer_state = outer_state - def parseToken(self, token): - # the only token we get should be the name of the class. - self.outer_state.listClasses.append(token) - return self.outer_state - - class IgnoreState: - """A state that will ignore all tokens until it gets to a - specified token.""" - def __init__(self, ignore_until, old_state): - self.ignore_until = ignore_until - self.old_state = old_state - def parseToken(self, token): - if self.ignore_until == token: - return self.old_state - return self - - class PackageState: - """The state we enter when we encounter the package keyword. - We assume the next token will be the package name.""" - def __init__(self, outer_state): - # outer_state is always an instance of OuterState - self.outer_state = outer_state - def parseToken(self, token): - self.outer_state.setPackage(token) - return self.outer_state - - def parse_java(fn): - """Parse a .java file and return a double of package directory, - plus a list of .class files that compiling that .java file will - produce""" - package = None - initial = OuterState() - currstate = initial - for token in _reToken.findall(open(fn, 'r').read()): - # The regex produces a bunch of groups, but only one will - # have anything in it. - currstate = currstate.parseToken(token) - if initial.package: - package = string.replace(initial.package, '.', os.sep) - return (package, initial.listOutputs) - -else: - # Don't actually parse Java files for class names. - # - # We might make this a configurable option in the future if - # Java-file parsing takes too long (although it shouldn't relative - # to how long the Java compiler itself seems to take...). - - def parse_java(file): - """ "Parse" a .java file. - - This actually just splits the file name, so the assumption here - is that the file name matches the public class name, and that - the path to the file is the same as the package name. - """ - return os.path.split(file) +from SCons.Tool.JavaCommon import parse_java_file def classname(path): """Turn a string (path name) into a Java class name.""" @@ -250,7 +66,7 @@ def emit_java_classes(target, source, env): tlist = [] for file in slist: - pkg_dir, classes = parse_java(file.get_abspath()) + pkg_dir, classes = parse_java_file(file.get_abspath()) if pkg_dir: for c in classes: t = target[0].Dir(pkg_dir).File(c+class_suffix) |