/*
 * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package com.apple.internal.jobjc.generator;

import java.util.List;

import com.apple.internal.jobjc.generator.model.Clazz;
import com.apple.internal.jobjc.generator.model.Framework;
import com.apple.internal.jobjc.generator.model.Function;
import com.apple.internal.jobjc.generator.model.types.TypeCache;

public class MethodDisambiguator {
    static void disambiguateMethodNames() {
        // link all subclassers off their parents
        for (final Clazz clazz : TypeCache.inst().getAllClasses()) {
            final Clazz superClazz = clazz.superClass;
            if (superClazz != null) superClazz.subClassers.add(clazz);
        }

        // recursively call all subclassers, starting from NSObject on down
        disambiguateMethodNamesFor(TypeCache.inst().getClassForName("NSObject"));

        // NSProxy does not appear to subclass from NSObject, but it is still a real full class...?
        disambiguateMethodNamesFor(TypeCache.inst().getClassForName("NSProxy"));
    }

    static void disambiguateMethodNamesFor(final Clazz clazz) {
        clazz.disambiguateMethods();
        for (final Clazz subClazz : clazz.subClassers) {
            disambiguateMethodNamesFor(subClazz);
        }
    }

    public static void disambiguateFunctionsIn(final List<Framework> frameworks) {
        for (final Framework framework : frameworks) {
            disambiguateFunctionsInFramework(framework);
        }
    }

    static void disambiguateFunctionsInFramework(final Framework framework) {
        for (final Function fxn : framework.functions)
            fxn.disambiguateArgs();
    }
}
