summaryrefslogtreecommitdiffstats
path: root/src/engine/SCons/Tool/javac.py
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2003-05-09 20:34:37 (GMT)
committerSteven Knight <knight@baldmt.com>2003-05-09 20:34:37 (GMT)
commit3ff79698a1d206f9be1804376004777c6c7f7929 (patch)
treee34f3b4515444d2effd07c0caea091dc353ae4d0 /src/engine/SCons/Tool/javac.py
parentd5aff94f2c90a162e2c36775b0fc80cabdc7ad64 (diff)
downloadSCons-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.py188
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)