#
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
#
# Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
#
# The contents of this file are subject to the terms of either the GNU
# General Public License Version 2 only ("GPL") or the Common Development
# and Distribution License("CDDL") (collectively, the "License").  You
# may not use this file except in compliance with the License.  You can
# obtain a copy of the License at
# https://oss.oracle.com/licenses/CDDL+GPL-1.1
# or LICENSE.txt.  See the License for the specific
# language governing permissions and limitations under the License.
#
# When distributing the software, include this License Header Notice in each
# file and include the License file at LICENSE.txt.
#
# GPL Classpath Exception:
# Oracle designates this particular file as subject to the "Classpath"
# exception as provided by Oracle in the GPL Version 2 section of the License
# file that accompanied this code.
#
# Modifications:
# If applicable, add the following below the License Header, with the fields
# enclosed by brackets [] replaced by your own identifying information:
# "Portions Copyright [year] [name of copyright owner]"
#
# Contributor(s):
# If you wish your version of this file to be governed by only the CDDL or
# only the GPL Version 2, indicate your decision by adding "[Contributor]
# elects to include this software in this distribution under the [CDDL or GPL
# Version 2] license."  If you don't indicate a single choice of license, a
# recipient has the option to distribute your version of this file under
# either the CDDL, the GPL Version 2 or to extend the choice of license to
# its licensees as provided above.  However, if you add GPL Version 2 code
# and therefore, elected the GPL Version 2 license, then the option applies
# only if the new code is made subject to such option by the copyright
# holder.
#

Method Overload Resolution for codegen

MOR is a rather complex aspect of the Java language.  It has
gone from complex in Java 1.4 to baroque in Java 5 due to
the addition of generics, varargs, and autoboxing. 
Since codegen is really only intended to support a
Java 1.4 level language, we will ignore the newer MOR 
algorithm.

We should implement most/all of Java 1.4 MOR for codegen.
Here are the relevant definitions:

From JLS 5.3

A method invocation conversion is applied to each argument of
a method on a method call.  method invocation conversion allows:

1. Identity conversion (5.1.1)
    This is what it sounds like: converting a type to itself
2. Widening primitive conversion (5.1.2)
    The following are permitted:
    byte    -> short, int, long, float, double
    short   -> int, long, float, double
    char    -> int, long, float, double
    int	    -> long, float, double
    long    -> float, double
    float   -> double
3. Widening reference conversion (5.1.4)
    class S	-> class T if S is a subclass of T
    class S	-> interface K if S implements K
    null type	-> any class, interface, array
    interface J	-> interface K if J is a subinterface of K
    interface J	-> Object
    array A[]	-> Object
    array A[]	-> Cloneable
    array A[]	-> array B[] if A, B ref types and there is a
		   widening reference conversion from A to B

MOR is defined in 3 steps:

1. (15.12.1) Determine class or interface to search (as adapted for the 
   Wrapper syntax):

    Form: MethodName
	Expr.identifier: the type to search is the type of Expr
	Type.identifier: the type to search is the type named Type
	super.identifier: the type to search is the superClass of the
	    current ClassGenerator
	this.identifier: the type to search is the class of the current
	    ClassGenerator.

Given a member reference, define the access type as follows:

member access:
StaticFieldAccessExpression x:	    x.targetType() 
NonStaticFieldAccessExpression x:   x.targetType() 
StaticCallExpression x:		    x.target()
NonStaticCallExpression x:	    x.target().type()
SuperCallExpression x:		    x.getContainingClass().superType()

constructor access:
NewObjExpression x:		    x.type()
NewArrExpression x:		    x.ctype()
SuperObjExpression x:		    x.getContainingClass().superType (super( ) in cons)
ThisObjExpression x:		    x.getContainingClass().thisType() (this( ) in cons)

2. (15.12.2) Determine method signatures
    A method declaration is applicable to a method invocation iff:
    1. The number of parameters in the declaration equals the number
       of argument expressions in the method invocation.
    2. The type of each actual argument can be converted by method
       invocation conversion to the type of the corresponding parameter.

    The method must also be accessible (6.6) :
	1. Public class or interface is always accessible
	2. Array type is accessible iff its component type is accessible
	3. A member (field or method) of a reference (class, interface, or array)
	   or a constructor of a class type is accessible iff:
	   1. The member or constructor is declared public
	   2. Otherwise, if declared protected, accessible iff:
	      1. The access occurs in the same package as where the member or constructor 
		 is declared, OR
	      2. Let C be a class declaring protected member m with identifier id. 
	         Let S be the class containing the reference to m.
		 Let K be the accessor type 
	   3. Otherwise, if declared private, accessible iff accessed from same class.
	   4. Otherwise, we have default access, accessible iff accessed from same package.

    3. Choose the most specific method
	Let m be a name.  Suppose we have m defined in two places:
	    T.m( T1, ..., Tn ) (mu)
	    U.m( U1, ..., Un ) (mt)

	Then mu is more specific than mt iff
	1. T can be converted to U by method invocation conversion
	2. For each i, Ti can be converted to U1 by method invocation conversion

	A method is maximally specific if it is applicable and accessible and no
	other method is more specific.

	If there is only one maximally specific method, go to step 3.
	Otherwise (we will simplify here and declare this to be ambiguous,
	ignoring 15.12.2.2 discussion about methods with the same signature).

3. (15.12.3) Is the chosen method appropriate?
    (basically static vs. non-static)
    1. If we have an invocation expr.ident in a static context, this is an error.
    2. If we have an invocation type.ident, the chosen method must be static,
       or an error occurs.
    3. If the invocation is super.ident,
	- if the method is abstract, error.
	- if the invocation is in a static context, error.
    4. If the result type is void, the expr must be in a statement context (in codegen)

    If the method is appropriate, then the invocation mode is determined as follows:
    1. If the method has the static modifier, mode is static
       (invokestatic).
    2. Otherwise, if the method has the private modifier, mode is nonvirtual
       (invokespecial).
    3. Otherwise, if the method invocation is super.ident, mode is super
       (invokespecial).
    4. Otherwise, if the method is declared in an interface, mode is interface
       (invokeinterface).
    5. Otherwise, mode is virtual
       (invokevirtual).
	
    
