func()

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)
}