langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
changeset 12078 7470e05d486b
parent 12013 fdcc73079b81
child 12080 23101f54df44
equal deleted inserted replaced
12077:2038f4fe956e 12078:7470e05d486b
  1625         }
  1625         }
  1626 
  1626 
  1627         // Attribute clazz expression and store
  1627         // Attribute clazz expression and store
  1628         // symbol + type back into the attributed tree.
  1628         // symbol + type back into the attributed tree.
  1629         Type clazztype = attribType(clazz, env);
  1629         Type clazztype = attribType(clazz, env);
  1630         Pair<Scope,Scope> mapping = getSyntheticScopeMapping(clazztype);
       
  1631         clazztype = chk.checkDiamond(tree, clazztype);
  1630         clazztype = chk.checkDiamond(tree, clazztype);
  1632         chk.validate(clazz, localEnv);
  1631         chk.validate(clazz, localEnv);
  1633         if (tree.encl != null) {
  1632         if (tree.encl != null) {
  1634             // We have to work in this case to store
  1633             // We have to work in this case to store
  1635             // symbol + type back into the attributed tree.
  1634             // symbol + type back into the attributed tree.
  1652         // Attribute constructor arguments.
  1651         // Attribute constructor arguments.
  1653         List<Type> argtypes = attribArgs(tree.args, localEnv);
  1652         List<Type> argtypes = attribArgs(tree.args, localEnv);
  1654         List<Type> typeargtypes = attribTypes(tree.typeargs, localEnv);
  1653         List<Type> typeargtypes = attribTypes(tree.typeargs, localEnv);
  1655 
  1654 
  1656         if (TreeInfo.isDiamond(tree) && !clazztype.isErroneous()) {
  1655         if (TreeInfo.isDiamond(tree) && !clazztype.isErroneous()) {
  1657             clazztype = attribDiamond(localEnv, tree, clazztype, mapping, argtypes, typeargtypes);
  1656             clazztype = attribDiamond(localEnv, tree, clazztype, argtypes, typeargtypes);
  1658             clazz.type = clazztype;
  1657             clazz.type = clazztype;
  1659         } else if (allowDiamondFinder &&
  1658         } else if (allowDiamondFinder &&
  1660                 tree.def == null &&
  1659                 tree.def == null &&
  1661                 !clazztype.isErroneous() &&
  1660                 !clazztype.isErroneous() &&
  1662                 clazztype.getTypeArguments().nonEmpty() &&
  1661                 clazztype.getTypeArguments().nonEmpty() &&
  1669                 log.deferDiagnostics = true;
  1668                 log.deferDiagnostics = true;
  1670                 log.deferredDiagnostics = ListBuffer.lb();
  1669                 log.deferredDiagnostics = ListBuffer.lb();
  1671                 inferred = attribDiamond(localEnv,
  1670                 inferred = attribDiamond(localEnv,
  1672                         tree,
  1671                         tree,
  1673                         clazztype,
  1672                         clazztype,
  1674                         mapping,
       
  1675                         argtypes,
  1673                         argtypes,
  1676                         typeargtypes);
  1674                         typeargtypes);
  1677             }
  1675             }
  1678             finally {
  1676             finally {
  1679                 log.deferDiagnostics = prevDeferDiags;
  1677                 log.deferDiagnostics = prevDeferDiags;
  1825     }
  1823     }
  1826 
  1824 
  1827     Type attribDiamond(Env<AttrContext> env,
  1825     Type attribDiamond(Env<AttrContext> env,
  1828                         JCNewClass tree,
  1826                         JCNewClass tree,
  1829                         Type clazztype,
  1827                         Type clazztype,
  1830                         Pair<Scope, Scope> mapping,
       
  1831                         List<Type> argtypes,
  1828                         List<Type> argtypes,
  1832                         List<Type> typeargtypes) {
  1829                         List<Type> typeargtypes) {
  1833         if (clazztype.isErroneous() ||
  1830         if (clazztype.isErroneous() ||
  1834                 clazztype.isInterface() ||
  1831                 clazztype.isInterface()) {
  1835                 mapping == erroneousMapping) {
       
  1836             //if the type of the instance creation expression is erroneous,
  1832             //if the type of the instance creation expression is erroneous,
  1837             //or if it's an interface, or if something prevented us to form a valid
  1833             //or if it's an interface, or if something prevented us to form a valid
  1838             //mapping, return the (possibly erroneous) type unchanged
  1834             //mapping, return the (possibly erroneous) type unchanged
  1839             return clazztype;
  1835             return clazztype;
  1840         }
  1836         }
  1841 
  1837 
  1842         //dup attribution environment and augment the set of inference variables
  1838         //dup attribution environment and augment the set of inference variables
  1843         Env<AttrContext> localEnv = env.dup(tree);
  1839         Env<AttrContext> localEnv = env.dup(tree);
  1844         localEnv.info.tvars = clazztype.tsym.type.getTypeArguments();
  1840 
       
  1841         ClassType site = new ClassType(clazztype.getEnclosingType(),
       
  1842                     clazztype.tsym.type.getTypeArguments(),
       
  1843                     clazztype.tsym);
  1845 
  1844 
  1846         //if the type of the instance creation expression is a class type
  1845         //if the type of the instance creation expression is a class type
  1847         //apply method resolution inference (JLS 15.12.2.7). The return type
  1846         //apply method resolution inference (JLS 15.12.2.7). The return type
  1848         //of the resolved constructor will be a partially instantiated type
  1847         //of the resolved constructor will be a partially instantiated type
  1849         ((ClassSymbol) clazztype.tsym).members_field = mapping.snd;
  1848         Symbol constructor = rs.resolveDiamond(tree.pos(),
  1850         Symbol constructor;
       
  1851         try {
       
  1852             constructor = rs.resolveDiamond(tree.pos(),
       
  1853                     localEnv,
  1849                     localEnv,
  1854                     clazztype,
  1850                     site,
  1855                     argtypes,
  1851                     argtypes,
  1856                     typeargtypes);
  1852                     typeargtypes);
  1857         } finally {
  1853 
  1858             ((ClassSymbol) clazztype.tsym).members_field = mapping.fst;
       
  1859         }
       
  1860         if (constructor.kind == MTH) {
  1854         if (constructor.kind == MTH) {
  1861             ClassType ct = new ClassType(clazztype.getEnclosingType(),
  1855             clazztype = checkMethod(site,
  1862                     clazztype.tsym.type.getTypeArguments(),
       
  1863                     clazztype.tsym);
       
  1864             clazztype = checkMethod(ct,
       
  1865                     constructor,
  1856                     constructor,
  1866                     localEnv,
  1857                     localEnv,
  1867                     tree.args,
  1858                     tree.args,
  1868                     argtypes,
  1859                     argtypes,
  1869                     typeargtypes,
  1860                     typeargtypes,
  1890         }
  1881         }
  1891         return chk.checkClassType(tree.clazz.pos(),
  1882         return chk.checkClassType(tree.clazz.pos(),
  1892                 clazztype,
  1883                 clazztype,
  1893                 true);
  1884                 true);
  1894     }
  1885     }
  1895 
       
  1896     /** Creates a synthetic scope containing fake generic constructors.
       
  1897      *  Assuming that the original scope contains a constructor of the kind:
       
  1898      *  Foo(X x, Y y), where X,Y are class type-variables declared in Foo,
       
  1899      *  the synthetic scope is added a generic constructor of the kind:
       
  1900      *  <X,Y>Foo<X,Y>(X x, Y y). This is crucial in order to enable diamond
       
  1901      *  inference. The inferred return type of the synthetic constructor IS
       
  1902      *  the inferred type for the diamond operator.
       
  1903      */
       
  1904     private Pair<Scope, Scope> getSyntheticScopeMapping(Type ctype) {
       
  1905         if (ctype.tag != CLASS) {
       
  1906             return erroneousMapping;
       
  1907         }
       
  1908 
       
  1909         Pair<Scope, Scope> mapping =
       
  1910                 new Pair<Scope, Scope>(ctype.tsym.members(), new Scope(ctype.tsym));
       
  1911 
       
  1912         //for each constructor in the original scope, create a synthetic constructor
       
  1913         //whose return type is the type of the class in which the constructor is
       
  1914         //declared, and insert it into the new scope.
       
  1915         for (Scope.Entry e = mapping.fst.lookup(names.init);
       
  1916                 e.scope != null;
       
  1917                 e = e.next()) {
       
  1918             Type synthRestype = new ClassType(ctype.getEnclosingType(),
       
  1919                         ctype.tsym.type.getTypeArguments(),
       
  1920                         ctype.tsym);
       
  1921             MethodSymbol synhConstr = new MethodSymbol(e.sym.flags(),
       
  1922                     names.init,
       
  1923                     types.createMethodTypeWithReturn(e.sym.type, synthRestype),
       
  1924                     e.sym.owner);
       
  1925             mapping.snd.enter(synhConstr);
       
  1926         }
       
  1927         return mapping;
       
  1928     }
       
  1929 
       
  1930     private final Pair<Scope,Scope> erroneousMapping = new Pair<Scope,Scope>(null, null);
       
  1931 
  1886 
  1932     /** Make an attributed null check tree.
  1887     /** Make an attributed null check tree.
  1933      */
  1888      */
  1934     public JCExpression makeNullCheck(JCExpression arg) {
  1889     public JCExpression makeNullCheck(JCExpression arg) {
  1935         // optimization: X.this is never null; skip null check
  1890         // optimization: X.this is never null; skip null check