Fix issues parsing multiple anonymous specs (#4199)

* fix parser
* Removed xfails
* cleaned up debug print statements
* make use of these changes in gcc
* Added comment explaining unreachable line, line left for added protection
This commit is contained in:
becker33 2017-05-24 17:13:18 -07:00 committed by Todd Gamblin
parent c1cea7ebcf
commit 12ab882eba
3 changed files with 32 additions and 29 deletions

View file

@ -2958,16 +2958,23 @@ def do_parse(self):
# We're parsing an anonymous spec beginning with a # We're parsing an anonymous spec beginning with a
# key-value pair. # key-value pair.
if not specs: if not specs:
self.push_tokens([self.previous, self.token])
self.previous = None
specs.append(self.spec(None)) specs.append(self.spec(None))
self.expect(VAL) else:
# Raise an error if the previous spec is already if specs[-1].concrete:
# concrete (assigned by hash) # Trying to add k-v pair to spec from hash
if specs[-1]._hash: raise RedundantSpecError(specs[-1],
raise RedundantSpecError(specs[-1], 'key-value pair')
'key-value pair') # We should never end up here.
specs[-1]._add_flag( # This requires starting a new spec with ID, EQ
self.previous.value, self.token.value) # After another spec that is not concrete
self.previous = None # If the previous spec is not concrete, this is
# handled in the spec parsing loop
# If it is concrete, see the if statement above
# If there is no previous spec, we don't land in
# this else case.
self.unexpected_token()
else: else:
# We're parsing a new spec by name # We're parsing a new spec by name
self.previous = None self.previous = None
@ -3151,7 +3158,11 @@ def version(self):
if self.accept(COLON): if self.accept(COLON):
if self.accept(ID): if self.accept(ID):
end = self.token.value if self.next and self.next.type is EQ:
# This is a start: range followed by a key=value pair
self.push_tokens([self.token])
else:
end = self.token.value
elif start: elif start:
# No colon, but there was a version. # No colon, but there was a version.
return Version(start) return Version(start)

View file

@ -140,10 +140,9 @@ def test_anonymous_specs(self):
self.check_parse("arch=test-None-None", "platform=test") self.check_parse("arch=test-None-None", "platform=test")
self.check_parse('@2.7:') self.check_parse('@2.7:')
@pytest.mark.xfail()
def test_anonymous_specs_with_multiple_parts(self): def test_anonymous_specs_with_multiple_parts(self):
# Parse anonymous spec with multiple tokens # Parse anonymous spec with multiple tokens
self.check_parse('languages=go @4.2:') self.check_parse('@4.2: languages=go', 'languages=go @4.2:')
self.check_parse('@4.2: languages=go') self.check_parse('@4.2: languages=go')
def test_simple_dependence(self): def test_simple_dependence(self):
@ -551,12 +550,8 @@ def test_kv_with_spaces(self):
@pytest.mark.parametrize('spec,anon_spec,spec_name', [ @pytest.mark.parametrize('spec,anon_spec,spec_name', [
('openmpi languages=go', 'languages=go', 'openmpi'), ('openmpi languages=go', 'languages=go', 'openmpi'),
('openmpi @4.6:', '@4.6:', 'openmpi'), ('openmpi @4.6:', '@4.6:', 'openmpi'),
pytest.mark.xfail( ('openmpi languages=go @4.6:', 'languages=go @4.6:', 'openmpi'),
('openmpi languages=go @4.6:', 'languages=go @4.6:', 'openmpi') ('openmpi @4.6: languages=go', '@4.6: languages=go', 'openmpi'),
),
pytest.mark.xfail(
('openmpi @4.6: languages=go', '@4.6: languages=go', 'openmpi')
),
]) ])
def test_parse_anonymous_specs(spec, anon_spec, spec_name): def test_parse_anonymous_specs(spec, anon_spec, spec_name):

View file

@ -97,17 +97,14 @@ class Gcc(AutotoolsPackage):
# depends_on('guile@1.4.1:', type='test') # depends_on('guile@1.4.1:', type='test')
# See https://golang.org/doc/install/gccgo#Releases # See https://golang.org/doc/install/gccgo#Releases
provides('golang', when='languages=go') provides('golang', when='languages=go @4.6:')
# 'when' does not currently support multiple parts of a spec. provides('golang@:1', when='languages=go @4.7.1:')
# See https://github.com/LLNL/spack/pull/4151 provides('golang@:1.1', when='languages=go @4.8:')
# provides('golang', when='languages=go @4.6:') provides('golang@:1.1.2', when='languages=go @4.8.2:')
# provides('golang@:1', when='languages=go @4.7.1:') provides('golang@:1.2', when='languages=go @4.9:')
# provides('golang@:1.1', when='languages=go @4.8:') provides('golang@:1.4', when='languages=go @5:')
# provides('golang@:1.1.2', when='languages=go @4.8.2:') provides('golang@:1.6.1', when='languages=go @6:')
# provides('golang@:1.2', when='languages=go @4.9:') provides('golang@:1.8', when='languages=go @7:')
# provides('golang@:1.4', when='languages=go @5:')
# provides('golang@:1.6.1', when='languages=go @6:')
# provides('golang@:1.8', when='languages=go @7:')
# For a list of valid languages for a specific release, # For a list of valid languages for a specific release,
# run the following command in the GCC source directory: # run the following command in the GCC source directory: