diff options
Diffstat (limited to 'src/engine/SCons/Tool')
-rw-r--r-- | src/engine/SCons/Tool/JavaCommon.py | 14 | ||||
-rw-r--r-- | src/engine/SCons/Tool/JavaCommonTests.py | 69 | ||||
-rw-r--r-- | src/engine/SCons/Tool/__init__.py | 119 | ||||
-rw-r--r-- | src/engine/SCons/Tool/applelink.py | 3 | ||||
-rw-r--r-- | src/engine/SCons/Tool/dvips.py | 2 | ||||
-rw-r--r-- | src/engine/SCons/Tool/install.py | 25 | ||||
-rw-r--r-- | src/engine/SCons/Tool/msvc.py | 4 | ||||
-rw-r--r-- | src/engine/SCons/Tool/msvs.py | 2 | ||||
-rw-r--r-- | src/engine/SCons/Tool/qt.xml | 4 |
9 files changed, 183 insertions, 59 deletions
diff --git a/src/engine/SCons/Tool/JavaCommon.py b/src/engine/SCons/Tool/JavaCommon.py index 0991c37..d028a39 100644 --- a/src/engine/SCons/Tool/JavaCommon.py +++ b/src/engine/SCons/Tool/JavaCommon.py @@ -49,14 +49,16 @@ if java_parsing: # double-backslashes; # a single-line comment "//"; # single or double quotes preceeded by a backslash; - # single quotes, double quotes, open or close braces, semi-colons; + # single quotes, double quotes, open or close braces, semi-colons, + # periods, open or close parentheses; + # floating-point numbers; # any alphanumeric token (keyword, class name, specifier); + # any alphanumeric token surrounded by angle brackets (generics); # the multi-line comment begin and end tokens /* and */; - # array declarations "[]"; - # semi-colons; - # periods. + # array declarations "[]". _reToken = re.compile(r'(\n|\\\\|//|\\[\'"]|[\'"\{\}\;\.\(\)]|' + - r'[A-Za-z_][\w\$\.]*|/\*|\*/|\[\])') + r'\d*\.\d*|[A-Za-z_][\w\$\.]*|<[A-Za-z_]\w+>|' + + r'/\*|\*/|\[\])') class OuterState: """The initial state for parsing a Java file for classes, @@ -199,6 +201,8 @@ if java_parsing: return IgnoreState('*/', self) elif token == '\n': return self + elif token[0] == '<' and token[-1] == '>': + return self elif token == '(': self.brace_level = self.brace_level + 1 return self diff --git a/src/engine/SCons/Tool/JavaCommonTests.py b/src/engine/SCons/Tool/JavaCommonTests.py index 1675190..bffe09e 100644 --- a/src/engine/SCons/Tool/JavaCommonTests.py +++ b/src/engine/SCons/Tool/JavaCommonTests.py @@ -466,6 +466,75 @@ class test pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.5') assert expect == classes, (expect, classes) + def test_floating_point_numbers(self): + """Test floating-point numbers in the input stream""" + input = """ +// Broken.java +class Broken +{ + /** + * Detected. + */ + Object anonymousInnerOK = new Runnable() { public void run () {} }; + + /** + * Detected. + */ + class InnerOK { InnerOK () { } } + + { + System.out.println("a number: " + 1000.0 + ""); + } + + /** + * Not detected. + */ + Object anonymousInnerBAD = new Runnable() { public void run () {} }; + + /** + * Not detected. + */ + class InnerBAD { InnerBAD () { } } +} +""" + + expect = ['Broken$1', 'Broken$InnerOK', 'Broken$2', 'Broken$InnerBAD', 'Broken'] + + pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.4') + assert expect == classes, (expect, classes) + + pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.5') + assert expect == classes, (expect, classes) + + + def test_genercis(self): + """Test that generics don't interfere with detecting anonymous classes""" + + input = """\ +import java.util.Date; +import java.util.Comparator; + +public class Foo +{ + public void foo() + { + Comparator<Date> comp = new Comparator<Date>() + { + static final long serialVersionUID = 1L; + public int compare(Date lhs, Date rhs) + { + return 0; + } + }; + } +} +""" + + expect = [ 'Foo$1', 'Foo' ] + + pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.6') + assert expect == classes, (expect, classes) + if __name__ == "__main__": diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index d4e3815..1e69f1e 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -422,32 +422,33 @@ def CreateJavaFileBuilder(env): env['JAVASUFFIX'] = '.java' return java_file -class ToolInitializer: +class ToolInitializerMethod: """ - A class for delayed initialization of Tools modules. - - This is intended to be added to a construction environment in - place of the method(s) normally called for a Builder (env.Object, - env.StaticObject, etc.). When called, it searches the specified - list of tools, applies the first one that exists to the construction - environment, and calls whatever builder was (presumably) added the - construction environment in our place. + This is added to a construction environment in place of a + method(s) normally called for a Builder (env.Object, env.StaticObject, + etc.). When called, it has its associated ToolInitializer + object search the specified list of tools and apply the first + one that exists to the construction environment. It then calls + whatever builder was (presumably) added to the construction + environment in place of this particular instance. """ - def __init__(self, name, tools): + def __init__(self, name, initializer): """ Note: we store the tool name as __name__ so it can be used by the class that attaches this to a construction environment. """ self.__name__ = name - if not SCons.Util.is_List(tools): - tools = [tools] - self.tools = tools - def __call__(self, env, *args, **kw): - for t in self.tools: - tool = SCons.Tool.Tool(t) - if tool.exists(env): - env.Tool(tool) - break + self.initializer = initializer + + def get_builder(self, env): + """ + Returns the appropriate real Builder for this method name + after having the associated ToolInitializer object apply + the appropriate Tool module. + """ + builder = getattr(env, self.__name__) + + self.initializer.apply_tools(env) builder = getattr(env, self.__name__) if builder is self: @@ -455,21 +456,79 @@ class ToolInitializer: # for this name was found (or possibly there's a mismatch # between the name we were called by and the Builder name # added by the Tool module). - # - # (Eventually this is where we'll put a more informative - # error message about the inability to find that tool - # as cut over more Builders+Tools to using this. - return [], [] + return None + + self.initializer.remove_methods(env) + + return builder - # Let the construction environment remove the added method - # so we no longer copy and re-bind this method when the - # construction environment gets cloned. - env.RemoveMethod(self) + def __call__(self, env, *args, **kw): + """ + """ + builder = self.get_builder(env) + if builder is None: + return [], [] return apply(builder, args, kw) +class ToolInitializer: + """ + A class for delayed initialization of Tools modules. + + Instances of this class associate a list of Tool modules with + a list of Builder method names that will be added by those Tool + modules. As part of instantiating this object for a particular + construction environment, we also add the appropriate + ToolInitializerMethod objects for the various Builder methods + that we want to use to delay Tool searches until necessary. + """ + def __init__(self, env, tools, names): + if not SCons.Util.is_List(tools): + tools = [tools] + if not SCons.Util.is_List(names): + names = [names] + self.env = env + self.tools = tools + self.names = names + self.methods = {} + for name in names: + method = ToolInitializerMethod(name, self) + self.methods[name] = method + env.AddMethod(method) + + def remove_methods(self, env): + """ + Removes the methods that were added by the tool initialization + so we no longer copy and re-bind them when the construction + environment gets cloned. + """ + for method in self.methods.values(): + env.RemoveMethod(method) + + def apply_tools(self, env): + """ + Searches the list of associated Tool modules for one that + exists, and applies that to the construction environment. + """ + for t in self.tools: + tool = SCons.Tool.Tool(t) + if tool.exists(env): + env.Tool(tool) + return + + # If we fall through here, there was no tool module found. + # This is where we can put an informative error message + # about the inability to find the tool. We'll start doing + # this as we cut over more pre-defined Builder+Tools to use + # the ToolInitializer class. + def Initializers(env): - env.AddMethod(ToolInitializer('Install', 'install')) - env.AddMethod(ToolInitializer('InstallAs', 'install')) + ToolInitializer(env, ['install'], ['_InternalInstall', '_InternalInstallAs']) + def Install(self, *args, **kw): + return apply(self._InternalInstall, args, kw) + def InstallAs(self, *args, **kw): + return apply(self._InternalInstallAs, args, kw) + env.AddMethod(Install) + env.AddMethod(InstallAs) def FindTool(tools, env): for tool in tools: diff --git a/src/engine/SCons/Tool/applelink.py b/src/engine/SCons/Tool/applelink.py index 532301f..7500133 100644 --- a/src/engine/SCons/Tool/applelink.py +++ b/src/engine/SCons/Tool/applelink.py @@ -62,5 +62,4 @@ def generate(env): def exists(env): - import sys - return sys.platform == 'darwin' + return env['PLATFORM'] == 'darwin' diff --git a/src/engine/SCons/Tool/dvips.py b/src/engine/SCons/Tool/dvips.py index 9996fc2..ec95f16 100644 --- a/src/engine/SCons/Tool/dvips.py +++ b/src/engine/SCons/Tool/dvips.py @@ -58,7 +58,7 @@ def generate(env): env['DVIPS'] = 'dvips' env['DVIPSFLAGS'] = SCons.Util.CLVar('') - # I'm not quite sure I got the directories and filenames right for build_dir + # I'm not quite sure I got the directories and filenames right for variant_dir # We need to be in the correct directory for the sake of latex \includegraphics eps included files. env['PSCOM'] = 'cd ${TARGET.dir} && $DVIPS $DVIPSFLAGS -o ${TARGET.file} ${SOURCE.file}' env['PSPREFIX'] = '' diff --git a/src/engine/SCons/Tool/install.py b/src/engine/SCons/Tool/install.py index c7eee61..983fb12 100644 --- a/src/engine/SCons/Tool/install.py +++ b/src/engine/SCons/Tool/install.py @@ -75,7 +75,8 @@ def installFunc(target, source, env): except KeyError: raise SCons.Errors.UserError('Missing INSTALL construction variable.') - assert( len(target)==len(source) ) + assert len(target)==len(source), \ + "Installing source %s into target %s: target and source lists must have same length."%(map(str, source), map(str, target)) for t,s in zip(target,source): if install(t.get_path(),s.get_path(),env): return 1 @@ -131,8 +132,9 @@ installas_action = SCons.Action.Action(installFunc, stringFunc) BaseInstallBuilder = None -def InstallBuilderWrapper(env, target, source, dir=None): +def InstallBuilderWrapper(env, target=None, source=None, dir=None, **kw): if target and dir: + import SCons.Errors raise SCons.Errors.UserError, "Both target and dir defined for Install(), only one may be defined." if not dir: dir=target @@ -156,13 +158,15 @@ def InstallBuilderWrapper(env, target, source, dir=None): # '#' on the file name portion as meaning the Node should # be relative to the top-level SConstruct directory. target = env.fs.Entry('.'+os.sep+src.name, dnode) - tgt.extend(BaseInstallBuilder(env, target, src)) + #tgt.extend(BaseInstallBuilder(env, target, src, **kw)) + tgt.extend(apply(BaseInstallBuilder, (env, target, src), kw)) return tgt -def InstallAsBuilderWrapper(env, target, source): +def InstallAsBuilderWrapper(env, target=None, source=None, **kw): result = [] for src, tgt in map(lambda x, y: (x, y), source, target): - result.extend(BaseInstallBuilder(env, tgt, src)) + #result.extend(BaseInstallBuilder(env, tgt, src, **kw)) + result.extend(apply(BaseInstallBuilder, (env, tgt, src), kw)) return result added = None @@ -195,15 +199,8 @@ def generate(env): emitter = [ add_targets_to_INSTALLED_FILES, ], name = 'InstallBuilder') - try: - env['BUILDERS']['Install'] - except KeyError, e: - env['BUILDERS']['Install'] = InstallBuilderWrapper - - try: - env['BUILDERS']['InstallAs'] - except KeyError, e: - env['BUILDERS']['InstallAs'] = InstallAsBuilderWrapper + env['BUILDERS']['_InternalInstall'] = InstallBuilderWrapper + env['BUILDERS']['_InternalInstallAs'] = InstallAsBuilderWrapper # We'd like to initialize this doing something like the following, # but there isn't yet support for a ${SOURCE.type} expansion that diff --git a/src/engine/SCons/Tool/msvc.py b/src/engine/SCons/Tool/msvc.py index c6fe461..a1067c0 100644 --- a/src/engine/SCons/Tool/msvc.py +++ b/src/engine/SCons/Tool/msvc.py @@ -513,10 +513,6 @@ def _get_msvc8_default_paths(env, version, suite, use_mfc_dirs): include_paths.append( os.path.join( atlmfc_path, 'include' ) ) lib_paths.append( os.path.join( atlmfc_path, 'lib' ) ) - env_include_path = SCons.Util.get_environment_var('INCLUDE') - if env_include_path: - include_paths.append( env_include_path ) - if SCons.Util.can_read_reg and paths.has_key('FRAMEWORKSDKDIR'): fwdir = paths['FRAMEWORKSDKDIR'] include_paths.append( os.path.join( fwdir, 'include' ) ) diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py index d4efa74..ca1b5f6 100644 --- a/src/engine/SCons/Tool/msvs.py +++ b/src/engine/SCons/Tool/msvs.py @@ -1504,7 +1504,7 @@ def GenerateProject(target, source, env): builddspfile = target[0] dspfile = builddspfile.srcnode() - # this detects whether or not we're using a BuildDir + # this detects whether or not we're using a VariantDir if not dspfile is builddspfile: try: bdsp = open(str(builddspfile), "w+") diff --git a/src/engine/SCons/Tool/qt.xml b/src/engine/SCons/Tool/qt.xml index 66fe554..ea73698 100644 --- a/src/engine/SCons/Tool/qt.xml +++ b/src/engine/SCons/Tool/qt.xml @@ -112,7 +112,7 @@ As stated in the qt documentation, include the moc file at the end of the cxx file. Note that you have to include the file, which is generated by the transformation ${QT_MOCCXXPREFIX}<basename>${QT_MOCCXXSUFFIX}, by default <basename>.moc. A warning is generated after building the moc file, if you -do not include the correct file. If you are using BuildDir, you may +do not include the correct file. If you are using VariantDir, you may need to specify duplicate=1. You can turn off automatic moc file generation by setting QT_AUTOSCAN to 0. See also the corresponding &b-Moc; @@ -123,7 +123,7 @@ The implementation files generated from .ui files are handled much the same as yacc or lex files. Each .ui file given as a source of Program, Library or SharedLibrary will generate three files, the declaration file, the implementation file and a moc file. Because there are also generated headers, -you may need to specify duplicate=1 in calls to BuildDir. +you may need to specify duplicate=1 in calls to VariantDir. See also the corresponding &b-Uic; builder method. |