langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
changeset 12080 23101f54df44
parent 12078 7470e05d486b
child 12081 42f541476d14
equal deleted inserted replaced
12079:e1739a771470 12080:23101f54df44
     1 /*
     1 /*
     2  * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
  1516             // whose formal argument types is exactly the list of actual
  1516             // whose formal argument types is exactly the list of actual
  1517             // arguments (this will also set the method symbol).
  1517             // arguments (this will also set the method symbol).
  1518             Type mpt = newMethTemplate(argtypes, typeargtypes);
  1518             Type mpt = newMethTemplate(argtypes, typeargtypes);
  1519             localEnv.info.varArgs = false;
  1519             localEnv.info.varArgs = false;
  1520             Type mtype = attribExpr(tree.meth, localEnv, mpt);
  1520             Type mtype = attribExpr(tree.meth, localEnv, mpt);
  1521             if (localEnv.info.varArgs)
       
  1522                 Assert.check(mtype.isErroneous() || tree.varargsElement != null);
       
  1523 
  1521 
  1524             // Compute the result type.
  1522             // Compute the result type.
  1525             Type restype = mtype.getReturnType();
  1523             Type restype = mtype.getReturnType();
  1526             if (restype.tag == WILDCARD)
  1524             if (restype.tag == WILDCARD)
  1527                 throw new AssertionError(mtype);
  1525                 throw new AssertionError(mtype);
  1551             chk.checkRefTypes(tree.typeargs, typeargtypes);
  1549             chk.checkRefTypes(tree.typeargs, typeargtypes);
  1552 
  1550 
  1553             // Check that value of resulting type is admissible in the
  1551             // Check that value of resulting type is admissible in the
  1554             // current context.  Also, capture the return type
  1552             // current context.  Also, capture the return type
  1555             result = check(tree, capture(restype), VAL, pkind, pt);
  1553             result = check(tree, capture(restype), VAL, pkind, pt);
       
  1554 
       
  1555             if (localEnv.info.varArgs)
       
  1556                 Assert.check(result.isErroneous() || tree.varargsElement != null);
  1556         }
  1557         }
  1557         chk.validate(tree.typeargs, localEnv);
  1558         chk.validate(tree.typeargs, localEnv);
  1558     }
  1559     }
  1559     //where
  1560     //where
  1560         /** Check that given application node appears as first statement
  1561         /** Check that given application node appears as first statement
  1728                 rsEnv.info.varArgs = false;
  1729                 rsEnv.info.varArgs = false;
  1729                 tree.constructor = rs.resolveConstructor(
  1730                 tree.constructor = rs.resolveConstructor(
  1730                     tree.pos(), rsEnv, clazztype, argtypes, typeargtypes);
  1731                     tree.pos(), rsEnv, clazztype, argtypes, typeargtypes);
  1731                 tree.constructorType = tree.constructor.type.isErroneous() ?
  1732                 tree.constructorType = tree.constructor.type.isErroneous() ?
  1732                     syms.errType :
  1733                     syms.errType :
  1733                     checkMethod(clazztype,
  1734                     checkConstructor(clazztype,
  1734                         tree.constructor,
  1735                         tree.constructor,
  1735                         rsEnv,
  1736                         rsEnv,
  1736                         tree.args,
  1737                         tree.args,
  1737                         argtypes,
  1738                         argtypes,
  1738                         typeargtypes,
  1739                         typeargtypes,
  1803                 tree.constructor = sym;
  1804                 tree.constructor = sym;
  1804                 if (tree.constructor.kind > ERRONEOUS) {
  1805                 if (tree.constructor.kind > ERRONEOUS) {
  1805                     tree.constructorType =  syms.errType;
  1806                     tree.constructorType =  syms.errType;
  1806                 }
  1807                 }
  1807                 else {
  1808                 else {
  1808                     tree.constructorType = checkMethod(clazztype,
  1809                     tree.constructorType = checkConstructor(clazztype,
  1809                             tree.constructor,
  1810                             tree.constructor,
  1810                             localEnv,
  1811                             localEnv,
  1811                             tree.args,
  1812                             tree.args,
  1812                             argtypes,
  1813                             argtypes,
  1813                             typeargtypes,
  1814                             typeargtypes,
  2673         }
  2674         }
  2674 
  2675 
  2675     Warner noteWarner = new Warner();
  2676     Warner noteWarner = new Warner();
  2676 
  2677 
  2677     /**
  2678     /**
  2678      * Check that method arguments conform to its instantation.
  2679      * Check that method arguments conform to its instantiation.
  2679      **/
  2680      **/
  2680     public Type checkMethod(Type site,
  2681     public Type checkMethod(Type site,
  2681                             Symbol sym,
  2682                             Symbol sym,
  2682                             Env<AttrContext> env,
  2683                             Env<AttrContext> env,
  2683                             final List<JCExpression> argtrees,
  2684                             final List<JCExpression> argtrees,
  2710                                       argtypes,
  2711                                       argtypes,
  2711                                       typeargtypes,
  2712                                       typeargtypes,
  2712                                       true,
  2713                                       true,
  2713                                       useVarargs,
  2714                                       useVarargs,
  2714                                       noteWarner);
  2715                                       noteWarner);
  2715         boolean warned = noteWarner.hasNonSilentLint(LintCategory.UNCHECKED);
       
  2716 
  2716 
  2717         // If this fails, something went wrong; we should not have
  2717         // If this fails, something went wrong; we should not have
  2718         // found the identifier in the first place.
  2718         // found the identifier in the first place.
  2719         if (owntype == null) {
  2719         if (owntype == null) {
  2720             if (!pt.isErroneous())
  2720             if (!pt.isErroneous())
  2721                 log.error(env.tree.pos(),
  2721                 log.error(env.tree.pos(),
  2722                           "internal.error.cant.instantiate",
  2722                            "internal.error.cant.instantiate",
  2723                           sym, site,
  2723                            sym, site,
  2724                           Type.toString(pt.getParameterTypes()));
  2724                           Type.toString(pt.getParameterTypes()));
  2725             owntype = types.createErrorType(site);
  2725             owntype = types.createErrorType(site);
       
  2726             return types.createErrorType(site);
       
  2727         } else if (owntype.getReturnType().tag == FORALL) {
       
  2728             return owntype;
  2726         } else {
  2729         } else {
  2727             // System.out.println("call   : " + env.tree);
  2730             return chk.checkMethod(owntype, sym, env, argtrees, argtypes, useVarargs);
  2728             // System.out.println("method : " + owntype);
  2731         }
  2729             // System.out.println("actuals: " + argtypes);
  2732     }
  2730             List<Type> formals = owntype.getParameterTypes();
  2733 
  2731             Type last = useVarargs ? formals.last() : null;
  2734     /**
  2732             if (sym.name==names.init &&
  2735      * Check that constructor arguments conform to its instantiation.
  2733                 sym.owner == syms.enumSym)
  2736      **/
  2734                 formals = formals.tail.tail;
  2737     public Type checkConstructor(Type site,
  2735             List<JCExpression> args = argtrees;
  2738                             Symbol sym,
  2736             while (formals.head != last) {
  2739                             Env<AttrContext> env,
  2737                 JCTree arg = args.head;
  2740                             final List<JCExpression> argtrees,
  2738                 Warner warn = chk.convertWarner(arg.pos(), arg.type, formals.head);
  2741                             List<Type> argtypes,
  2739                 assertConvertible(arg, arg.type, formals.head, warn);
  2742                             List<Type> typeargtypes,
  2740                 warned |= warn.hasNonSilentLint(LintCategory.UNCHECKED);
  2743                             boolean useVarargs) {
  2741                 args = args.tail;
  2744         Type owntype = checkMethod(site, sym, env, argtrees, argtypes, typeargtypes, useVarargs);
  2742                 formals = formals.tail;
  2745         chk.checkType(env.tree.pos(), owntype.getReturnType(), syms.voidType);
  2743             }
       
  2744             if (useVarargs) {
       
  2745                 Type varArg = types.elemtype(last);
       
  2746                 while (args.tail != null) {
       
  2747                     JCTree arg = args.head;
       
  2748                     Warner warn = chk.convertWarner(arg.pos(), arg.type, varArg);
       
  2749                     assertConvertible(arg, arg.type, varArg, warn);
       
  2750                     warned |= warn.hasNonSilentLint(LintCategory.UNCHECKED);
       
  2751                     args = args.tail;
       
  2752                 }
       
  2753             } else if ((sym.flags() & VARARGS) != 0 && allowVarargs) {
       
  2754                 // non-varargs call to varargs method
       
  2755                 Type varParam = owntype.getParameterTypes().last();
       
  2756                 Type lastArg = argtypes.last();
       
  2757                 if (types.isSubtypeUnchecked(lastArg, types.elemtype(varParam)) &&
       
  2758                     !types.isSameType(types.erasure(varParam), types.erasure(lastArg)))
       
  2759                     log.warning(argtrees.last().pos(), "inexact.non-varargs.call",
       
  2760                                 types.elemtype(varParam),
       
  2761                                 varParam);
       
  2762             }
       
  2763 
       
  2764             if (warned && sym.type.tag == FORALL) {
       
  2765                 chk.warnUnchecked(env.tree.pos(),
       
  2766                                   "unchecked.meth.invocation.applied",
       
  2767                                   kindName(sym),
       
  2768                                   sym.name,
       
  2769                                   rs.methodArguments(sym.type.getParameterTypes()),
       
  2770                                   rs.methodArguments(argtypes),
       
  2771                                   kindName(sym.location()),
       
  2772                                   sym.location());
       
  2773                 owntype = new MethodType(owntype.getParameterTypes(),
       
  2774                                          types.erasure(owntype.getReturnType()),
       
  2775                                          types.erasure(owntype.getThrownTypes()),
       
  2776                                          syms.methodClass);
       
  2777             }
       
  2778             if (useVarargs) {
       
  2779                 JCTree tree = env.tree;
       
  2780                 Type argtype = owntype.getParameterTypes().last();
       
  2781                 if (owntype.getReturnType().tag != FORALL || warned) {
       
  2782                     chk.checkVararg(env.tree.pos(), owntype.getParameterTypes(), sym);
       
  2783                 }
       
  2784                 Type elemtype = types.elemtype(argtype);
       
  2785                 switch (tree.getTag()) {
       
  2786                 case APPLY:
       
  2787                     ((JCMethodInvocation) tree).varargsElement = elemtype;
       
  2788                     break;
       
  2789                 case NEWCLASS:
       
  2790                     ((JCNewClass) tree).varargsElement = elemtype;
       
  2791                     break;
       
  2792                 default:
       
  2793                     throw new AssertionError(""+tree);
       
  2794                 }
       
  2795             }
       
  2796         }
       
  2797         return owntype;
  2746         return owntype;
  2798     }
       
  2799 
       
  2800     private void assertConvertible(JCTree tree, Type actual, Type formal, Warner warn) {
       
  2801         if (types.isConvertible(actual, formal, warn))
       
  2802             return;
       
  2803 
       
  2804         if (formal.isCompound()
       
  2805             && types.isSubtype(actual, types.supertype(formal))
       
  2806             && types.isSubtypeUnchecked(actual, types.interfaces(formal), warn))
       
  2807             return;
       
  2808 
       
  2809         if (false) {
       
  2810             // TODO: make assertConvertible work
       
  2811             chk.typeError(tree.pos(), diags.fragment("incompatible.types"), actual, formal);
       
  2812             throw new AssertionError("Tree: " + tree
       
  2813                                      + " actual:" + actual
       
  2814                                      + " formal: " + formal);
       
  2815         }
       
  2816     }
  2747     }
  2817 
  2748 
  2818     public void visitLiteral(JCLiteral tree) {
  2749     public void visitLiteral(JCLiteral tree) {
  2819         result = check(
  2750         result = check(
  2820             tree, litType(tree.typetag).constType(tree.value), VAL, pkind, pt);
  2751             tree, litType(tree.typetag).constType(tree.value), VAL, pkind, pt);