Make package parsing code consume annotations
The code previously assumed an annotation meant there was no package declaration, but package declarations can be annotated. Update the code to consume any leading annotations. Bug: 151360309 Test: jar_test.go (& manual verification on full bootclasspath srcs) Change-Id: I3de5a2a675363fc3627a278103dd2cabe80a2d80
This commit is contained in:
parent
370e34172f
commit
2863e4535e
2 changed files with 26 additions and 6 deletions
18
jar/jar.go
18
jar/jar.go
|
@ -166,10 +166,23 @@ func JavaPackage(r io.Reader, src string) (string, error) {
|
||||||
}
|
}
|
||||||
s.IsIdentRune = javaIdentRune
|
s.IsIdentRune = javaIdentRune
|
||||||
|
|
||||||
tok := s.Scan()
|
var tok rune
|
||||||
|
for {
|
||||||
|
tok = s.Scan()
|
||||||
if sErr != nil {
|
if sErr != nil {
|
||||||
return "", sErr
|
return "", sErr
|
||||||
}
|
}
|
||||||
|
// If the first token is an annotation, it could be annotating a package declaration, so consume them.
|
||||||
|
// Note that this does not support "complex" annotations with attributes, e.g. @Foo(x=y).
|
||||||
|
if tok != '@' {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
tok = s.Scan()
|
||||||
|
if tok != scanner.Ident || sErr != nil {
|
||||||
|
return "", fmt.Errorf("expected annotation identifier, got @%v", tok)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if tok == scanner.Ident {
|
if tok == scanner.Ident {
|
||||||
switch s.TokenText() {
|
switch s.TokenText() {
|
||||||
case "package":
|
case "package":
|
||||||
|
@ -189,9 +202,6 @@ func JavaPackage(r io.Reader, src string) (string, error) {
|
||||||
default:
|
default:
|
||||||
return "", fmt.Errorf(`expected first token of java file to be "package", got %q`, s.TokenText())
|
return "", fmt.Errorf(`expected first token of java file to be "package", got %q`, s.TokenText())
|
||||||
}
|
}
|
||||||
} else if tok == '@' {
|
|
||||||
// File has no package statement, first token is an annotation
|
|
||||||
return "", nil
|
|
||||||
} else if tok == scanner.EOF {
|
} else if tok == scanner.EOF {
|
||||||
// File no package statement, it has no non-whitespace non-comment tokens
|
// File no package statement, it has no non-whitespace non-comment tokens
|
||||||
return "", nil
|
return "", nil
|
||||||
|
|
|
@ -61,6 +61,16 @@ func TestGetJavaPackage(t *testing.T) {
|
||||||
in: "package 0foo.bar;",
|
in: "package 0foo.bar;",
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "annotations",
|
||||||
|
in: "@NonNullApi\n@X\npackage foo.bar;",
|
||||||
|
want: "foo.bar",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "complex annotation",
|
||||||
|
in: "@Foo(x=y)\n@package foo.bar;",
|
||||||
|
wantErr: true, // Complex annotation not supported yet.
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
|
Loading…
Reference in a new issue