Commits

Artem Melentyev  committed ec60166

#4: boxing overloading via #valueOf

  • Participants
  • Parent commits ee56b92

Comments (0)

Files changed (4)

File src/share/classes/com/sun/tools/javac/comp/Attr.java

 package com.sun.tools.javac.comp;
 
 import java.util.*;
-import java.util.Set;
 import javax.lang.model.element.ElementKind;
 import javax.tools.JavaFileObject;
 
     Type check(JCTree tree, Type owntype, int ownkind, int pkind, Type pt) {
         if (owntype.tag != ERROR && pt.tag != METHOD && pt.tag != FORALL) {
             if ((ownkind & ~pkind) == 0) {
-                owntype = chk.checkType(tree.pos(), owntype, pt, errKey);
+            	if (quietCheckType(tree.pos(), owntype, pt, errKey).isErroneous()) { // if not ok
+            		// try boxing via #valueOf
+            		JCExpression t = make.Select(make.Ident(pt.tsym), names.fromString("valueOf"));
+            		t = make.Apply(null, t, List.of((JCExpression)(tree.translate==null ? tree.clone() : tree.translate)));
+            		t.type = attribTree(t, env, pkind, pt);
+	            	if (!t.type.isErroneous()) {
+	            		owntype = t.type;
+	            		tree.translate = t;
+	            	} else
+	            		owntype = chk.checkType(tree.pos(), owntype, pt, errKey);
+            	} else
+            		owntype = chk.checkType(tree.pos(), owntype, pt, errKey);
             } else {
                 log.error(tree.pos(), "unexpected.type",
                           kindNames(pkind),
         tree.type = owntype;
         return owntype;
     }
+    /// quiet version of chk.checkType
+    Type quietCheckType(DiagnosticPosition pos, Type found, Type req, String errKey) {
+        if (req.tag == ERROR)
+            return req;
+        if (found.tag == FORALL)
+            return chk.instantiatePoly(pos, (ForAll)found, req, new Warner());
+        if (req.tag == NONE)
+            return found;
+        if (types.isAssignable(found, req, new Warner()))
+            return found;
+        if (found.tag <= DOUBLE && req.tag <= DOUBLE)
+            return types.createErrorType(found);
+        if (found.isSuperBound()) {
+            log.error(pos, "assignment.from.super-bound", found);
+            return types.createErrorType(found);
+        }
+        if (req.isExtendsBound()) {
+            log.error(pos, "assignment.to.extends-bound", req);
+            return types.createErrorType(found);
+        }
+        return types.createErrorType(found);
+    }
 
     /** Is given blank final variable assignable, i.e. in a scope where it
      *  may be assigned to even though it is final?

File src/share/classes/com/sun/tools/javac/comp/Lower.java

                 Integer endPos = endPositions.remove(tree);
                 if (endPos != null) endPositions.put(result, endPos);
             }
+            if (result.translate!=null) {
+            	T t = (T) result.translate;
+            	result.translate = null;
+            	return translate(t);
+            }
             return result;
         }
     }

File src/share/classes/com/sun/tools/javac/tree/JCTree.java

     /* The type of this node.
      */
     public Type type;
+    
+    public JCExpression translate;
 
     /* The tag of this node -- one of the constants declared above.
      */

File src/test/JCOOTest.java

 
 public class JCOOTest {
     public static void main(String[] args) throws Exception {
+        compile("ValueOf");
         compile("Math");
         compile("Cmp");
         compile("ListIndexGet");