in internal/importers/java/java.go [851:947]
func (j *Importer) scanClassDecl(name string, decl string) (*Class, error) {
isRoot := name == "java.lang.Object"
cls := &Class{
Name: name,
funcMap: make(map[string]*FuncSet),
methodMap: make(map[string]*FuncSet),
HasNoArgCon: isRoot,
}
const (
stMod = iota
stName
stExt
stImpl
)
superClsDecl := isRoot
st := stMod
var w []byte
// if > 0, we're inside a generics declaration
gennest := 0
for i := 0; i < len(decl); i++ {
c := decl[i]
switch c {
default:
if gennest == 0 {
w = append(w, c)
}
case '>':
gennest--
case '<':
gennest++
case '{':
if !superClsDecl && !cls.Interface {
cls.Supers = append(cls.Supers, "java.lang.Object")
}
return cls, nil
case ' ', ',':
if gennest > 0 {
break
}
switch w := string(w); w {
default:
switch st {
case stName:
if strings.Replace(w, "$", ".", -1) != strings.Replace(name, "$", ".", -1) {
return nil, fmt.Errorf("unexpected name %q in class declaration: %q", w, decl)
}
cls.FindName = w
case stExt:
superClsDecl = true
cls.Supers = append(cls.Supers, w)
case stImpl:
if !cls.Interface {
cls.Supers = append(cls.Supers, w)
}
default:
return nil, fmt.Errorf("unexpected %q in class declaration: %q", w, decl)
}
case "":
// skip
case "public":
if st != stMod {
return nil, fmt.Errorf("unexpected %q in class declaration: %q", w, decl)
}
case "abstract":
if st != stMod {
return nil, fmt.Errorf("unexpected %q in class declaration: %q", w, decl)
}
cls.Abstract = true
case "final":
if st != stMod {
return nil, fmt.Errorf("unexpected %q in class declaration: %q", w, decl)
}
cls.Final = true
case "interface":
cls.Interface = true
fallthrough
case "class":
if st != stMod {
return nil, fmt.Errorf("unexpected %q in class declaration: %q", w, decl)
}
st = stName
case "extends":
if st != stName {
return nil, fmt.Errorf("unexpected %q in class declaration: %q", w, decl)
}
st = stExt
case "implements":
if st != stName && st != stExt {
return nil, fmt.Errorf("unexpected %q in class declaration: %q", w, decl)
}
st = stImpl
}
w = w[:0]
}
}
return nil, fmt.Errorf("missing ending { in class declaration: %q", decl)
}