// Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.geocities.com/kpdus/jad.html
// Decompiler options: packimports(3) deadcode 
// Source File Name:   SeeTagImpl.java

package com.sun.tools.javadoc;

import com.sun.javadoc.*;
import com.sun.tools.javac.v8.util.LayoutCharacters;
import com.sun.tools.javac.v8.util.ListBuffer;

// Referenced classes of package com.sun.tools.javadoc:
//            TagImpl, ClassDocImpl, DocEnv, DocImpl

class SeeTagImpl extends TagImpl
    implements SeeTag, LayoutCharacters
{
    class ParameterParseMachine
    {

        void addTypeToParamList()
        {
            if(typeId.length() > 0)
            {
                paramList.append(typeId.toString());
                typeId.setLength(0);
            }
        }

        public String[] parseParameters()
        {
            if(parameters.equals("()"))
                return new String[0];
            int i = 0;
            int j = 0;
            parameters = parameters.substring(1, parameters.length() - 1);
            char ac[] = parameters.toCharArray();
            for(int k = 0; k < ac.length; k++)
            {
                char c = ac[k];
                switch(i)
                {
                default:
                    break;

                case 0: // '\0'
                    if(Character.isJavaIdentifierStart(c))
                    {
                        typeId.append(c);
                        i = 1;
                    }
                    j = 0;
                    break;

                case 1: // '\001'
                    if(Character.isJavaIdentifierPart(c) || c == '.')
                        typeId.append(c);
                    else
                    if(c == '[')
                    {
                        typeId.append(c);
                        i = 4;
                    } else
                    if(Character.isWhitespace(c))
                        i = 3;
                    else
                    if(c == ',')
                    {
                        addTypeToParamList();
                        i = 0;
                    }
                    j = 1;
                    break;

                case 3: // '\003'
                    if(Character.isJavaIdentifierStart(c))
                    {
                        if(j == 4)
                        {
                            docenv().warning(holder, "tag.missing_comma_space", name, "(" + parameters + ")");
                            return (String[])null;
                        }
                        addTypeToParamList();
                        i = 2;
                    } else
                    if(c == '[')
                    {
                        typeId.append(c);
                        i = 4;
                    } else
                    if(c == ',')
                    {
                        addTypeToParamList();
                        i = 0;
                    }
                    j = 3;
                    break;

                case 4: // '\004'
                    if(c == ']')
                    {
                        typeId.append(c);
                        i = 3;
                    } else
                    if(!Character.isWhitespace(c))
                    {
                        docenv().warning(holder, "tag.illegal_char_in_arr_dim", name, "(" + parameters + ")");
                        return (String[])null;
                    }
                    j = 4;
                    break;

                case 2: // '\002'
                    if(c == ',')
                        i = 0;
                    j = 2;
                    break;
                }
            }

            if(i == 4 || i == 0 && j == 3)
                docenv().warning(holder, "tag.illegal_see_tag", "(" + parameters + ")");
            if(typeId.length() > 0)
                paramList.append(typeId.toString());
            return (String[])paramList.toArray(new String[paramList.length()]);
        }

        final int START = 0;
        final int TYPE = 1;
        final int NAME = 2;
        final int TNSPACE = 3;
        final int ARRAYDECORATION = 4;
        final int ARRAYSPACE = 5;
        String parameters;
        StringBuffer typeId;
        ListBuffer paramList;

        ParameterParseMachine(String s)
        {
            Object();
            parameters = s;
            paramList = new ListBuffer();
            typeId = new StringBuffer();
        }
    }


    private void parseSeeString()
    {
        int i = text.length();
        if(i == 0)
            return;
        switch(text.charAt(0))
        {
        case 60: // '<'
            if(text.charAt(i - 1) != '>')
                docenv().warning(holder, "tag.see.no_close_bracket_on_url", name, text);
            return;

        case 34: // '"'
            if(i == 1 || text.charAt(i - 1) != '"')
                docenv().warning(holder, "tag.see.no_close_quote", name, text);
            return;
        }
        int j = 0;
        int k = 0;
        int l = 0;
        for(int i1 = l; i1 < i; i1++)
        {
            char c = text.charAt(i1);
            switch(c)
            {
            case 35: // '#'
            case 46: // '.'
            case 91: // '['
            case 93: // ']'
                break;

            case 40: // '('
                j++;
                break;

            case 41: // ')'
                j--;
                break;

            case 44: // ','
                if(j <= 0)
                {
                    docenv().warning(holder, "tag.see.malformed_see_tag", name, text);
                    return;
                }
                break;

            case 9: // '\t'
            case 10: // '\n'
            case 13: // '\r'
            case 32: // ' '
                if(j == 0)
                {
                    k = i1;
                    i1 = i;
                }
                break;

            default:
                if(!Character.isJavaIdentifierPart(c))
                {
                    docenv().warning(holder, "tag.see.illegal_character", name, "" + c, text);
                    return;
                }
                break;
            }
        }

        if(j != 0)
        {
            docenv().warning(holder, "tag.see.malformed_see_tag", name, text);
            return;
        }
        String s = "";
        String s1 = "";
        if(k > 0)
        {
            s = text.substring(l, k);
            String s2 = text.substring(k + 1);
            int j1 = 0;
            do
            {
                if(j1 >= s2.length())
                    break;
                char c1 = s2.charAt(j1);
                if(c1 != ' ' && c1 != '\t' && c1 != '\n')
                {
                    label = s2.substring(j1);
                    break;
                }
                j1++;
            } while(true);
        } else
        {
            s = text;
            label = "";
        }
        int k1 = s.indexOf('#');
        if(k1 >= 0)
        {
            where = s.substring(0, k1);
            what = s.substring(k1 + 1);
        } else
        if(s.indexOf('(') >= 0)
        {
            docenv().warning(holder, "tag.see.missing_sharp", name, text);
            where = "";
            what = s;
        } else
        {
            where = s;
            what = null;
        }
    }

    public ClassDoc referencedClass()
    {
        return referencedClass;
    }

    public MemberDoc referencedMember()
    {
        return referencedMember;
    }

    public PackageDoc referencedPackage()
    {
        return referencedPackage;
    }

    private void findReferenced(ClassDocImpl classdocimpl)
    {
        if(where.length() > 0)
        {
            if(classdocimpl != null)
                referencedClass = classdocimpl.findClass(where);
            else
                referencedClass = docenv().lookupClass(where);
            if(referencedClass == null)
            {
                referencedPackage = docenv().lookupPackage(where);
                return;
            }
        } else
        {
            if(classdocimpl == null)
            {
                docenv().warning(holder, "tag.see.class_not_specified", name, text);
                return;
            }
            referencedClass = classdocimpl;
        }
        where = referencedClass.qualifiedName();
        if(what == null)
            return;
        int i = what.indexOf('(');
        String s = i < 0 ? what : what.substring(0, i);
        if(i > 0)
        {
            String as[] = (new ParameterParseMachine(what.substring(i, what.length()))).parseParameters();
            if(as != null)
                referencedMember = findExecutableMember(s, as, referencedClass);
            else
                referencedMember = null;
        } else
        {
            referencedMember = findExecutableMember(s, null, referencedClass);
            FieldDoc fielddoc = ((ClassDocImpl)referencedClass).findField(s);
            if(referencedMember == null || fielddoc != null && fielddoc.containingClass().subclassOf(referencedMember.containingClass()))
                referencedMember = fielddoc;
        }
        if(referencedMember == null)
            docenv().warning(holder, "tag.see.can_not_find_member", name, what, where);
    }

    public String kind()
    {
        return "@see";
    }

    public String label()
    {
        return label;
    }

    public String referencedClassName()
    {
        return where;
    }

    public String referencedMemberName()
    {
        return what;
    }

    SeeTagImpl(DocImpl docimpl, String s, String s1)
    {
        TagImpl(docimpl, s, s1);
        label = "";
        parseSeeString();
        if(where != null)
        {
            ClassDocImpl classdocimpl = null;
            if(docimpl instanceof MemberDoc)
                classdocimpl = (ClassDocImpl)((ProgramElementDoc)docimpl).containingClass();
            else
            if(docimpl instanceof ClassDoc)
                classdocimpl = (ClassDocImpl)docimpl;
            findReferenced(classdocimpl);
        }
    }

    private MemberDoc findExecutableMember(String s, String as[], ClassDoc classdoc)
    {
        if(s.equals(classdoc.name()))
            return ((ClassDocImpl)classdoc).findConstructor(s, as);
        else
            return ((ClassDocImpl)classdoc).findMethod(s, as);
    }

    private MemberDoc findReferencedMethod(String s, String as[], ClassDoc classdoc)
    {
        MemberDoc memberdoc = findExecutableMember(s, as, classdoc);
        ClassDoc aclassdoc[] = classdoc.innerClasses();
        if(memberdoc == null)
        {
            for(int i = 0; i < aclassdoc.length; i++)
            {
                MemberDoc memberdoc1 = findReferencedMethod(s, as, aclassdoc[i]);
                if(memberdoc1 != null)
                    return memberdoc1;
            }

        }
        return null;
    }

    private String where;
    private String what;
    private PackageDoc referencedPackage;
    private ClassDoc referencedClass;
    private MemberDoc referencedMember;
    String label;
}
