1578 } |
1578 } |
1579 |
1579 |
1580 // Attribute clazz expression and store |
1580 // Attribute clazz expression and store |
1581 // symbol + type back into the attributed tree. |
1581 // symbol + type back into the attributed tree. |
1582 Type clazztype = attribType(clazz, env); |
1582 Type clazztype = attribType(clazz, env); |
1583 Pair<Scope,Scope> mapping = getSyntheticScopeMapping(clazztype, cdef != null); |
1583 Pair<Scope,Scope> mapping = getSyntheticScopeMapping(clazztype); |
1584 clazztype = chk.checkDiamond(tree, clazztype); |
1584 clazztype = chk.checkDiamond(tree, clazztype); |
1585 chk.validate(clazz, localEnv); |
1585 chk.validate(clazz, localEnv); |
1586 if (tree.encl != null) { |
1586 if (tree.encl != null) { |
1587 // We have to work in this case to store |
1587 // We have to work in this case to store |
1588 // symbol + type back into the attributed tree. |
1588 // symbol + type back into the attributed tree. |
1776 JCNewClass tree, |
1776 JCNewClass tree, |
1777 Type clazztype, |
1777 Type clazztype, |
1778 Pair<Scope, Scope> mapping, |
1778 Pair<Scope, Scope> mapping, |
1779 List<Type> argtypes, |
1779 List<Type> argtypes, |
1780 List<Type> typeargtypes) { |
1780 List<Type> typeargtypes) { |
1781 if (clazztype.isErroneous() || mapping == erroneousMapping) { |
1781 if (clazztype.isErroneous() || |
|
1782 clazztype.isInterface() || |
|
1783 mapping == erroneousMapping) { |
1782 //if the type of the instance creation expression is erroneous, |
1784 //if the type of the instance creation expression is erroneous, |
1783 //or something prevented us to form a valid mapping, return the |
1785 //or if it's an interface, or if something prevented us to form a valid |
1784 //(possibly erroneous) type unchanged |
1786 //mapping, return the (possibly erroneous) type unchanged |
1785 return clazztype; |
1787 return clazztype; |
1786 } |
1788 } |
1787 else if (clazztype.isInterface()) { |
1789 |
1788 //if the type of the instance creation expression is an interface |
1790 //dup attribution environment and augment the set of inference variables |
1789 //skip the method resolution step (JLS 15.12.2.7). The type to be |
1791 Env<AttrContext> localEnv = env.dup(tree); |
1790 //inferred is of the kind <X1,X2, ... Xn>C<X1,X2, ... Xn> |
1792 localEnv.info.tvars = clazztype.tsym.type.getTypeArguments(); |
1791 clazztype = new ForAll(clazztype.tsym.type.allparams(), clazztype.tsym.type) { |
1793 |
1792 @Override |
1794 //if the type of the instance creation expression is a class type |
1793 public List<Type> getConstraints(TypeVar tv, ConstraintKind ck) { |
1795 //apply method resolution inference (JLS 15.12.2.7). The return type |
1794 switch (ck) { |
1796 //of the resolved constructor will be a partially instantiated type |
1795 case EXTENDS: return types.getBounds(tv); |
1797 ((ClassSymbol) clazztype.tsym).members_field = mapping.snd; |
1796 default: return List.nil(); |
1798 Symbol constructor; |
1797 } |
1799 try { |
1798 } |
1800 constructor = rs.resolveDiamond(tree.pos(), |
1799 @Override |
1801 localEnv, |
1800 public Type inst(List<Type> inferred, Types types) throws Infer.NoInstanceException { |
1802 clazztype.tsym.type, |
1801 // check that inferred bounds conform to their bounds |
1803 argtypes, |
1802 infer.checkWithinBounds(tvars, |
1804 typeargtypes); |
1803 types.subst(tvars, tvars, inferred), Warner.noWarnings); |
1805 } finally { |
1804 return super.inst(inferred, types); |
1806 ((ClassSymbol) clazztype.tsym).members_field = mapping.fst; |
1805 } |
1807 } |
1806 }; |
1808 if (constructor.kind == MTH) { |
|
1809 ClassType ct = new ClassType(clazztype.getEnclosingType(), |
|
1810 clazztype.tsym.type.getTypeArguments(), |
|
1811 clazztype.tsym); |
|
1812 clazztype = checkMethod(ct, |
|
1813 constructor, |
|
1814 localEnv, |
|
1815 tree.args, |
|
1816 argtypes, |
|
1817 typeargtypes, |
|
1818 localEnv.info.varArgs).getReturnType(); |
1807 } else { |
1819 } else { |
1808 //if the type of the instance creation expression is a class type |
1820 clazztype = syms.errType; |
1809 //apply method resolution inference (JLS 15.12.2.7). The return type |
1821 } |
1810 //of the resolved constructor will be a partially instantiated type |
1822 |
1811 ((ClassSymbol) clazztype.tsym).members_field = mapping.snd; |
|
1812 Symbol constructor; |
|
1813 try { |
|
1814 constructor = rs.resolveDiamond(tree.pos(), |
|
1815 env, |
|
1816 clazztype.tsym.type, |
|
1817 argtypes, |
|
1818 typeargtypes); |
|
1819 } finally { |
|
1820 ((ClassSymbol) clazztype.tsym).members_field = mapping.fst; |
|
1821 } |
|
1822 if (constructor.kind == MTH) { |
|
1823 ClassType ct = new ClassType(clazztype.getEnclosingType(), |
|
1824 clazztype.tsym.type.getTypeArguments(), |
|
1825 clazztype.tsym); |
|
1826 clazztype = checkMethod(ct, |
|
1827 constructor, |
|
1828 env, |
|
1829 tree.args, |
|
1830 argtypes, |
|
1831 typeargtypes, |
|
1832 env.info.varArgs).getReturnType(); |
|
1833 } else { |
|
1834 clazztype = syms.errType; |
|
1835 } |
|
1836 } |
|
1837 if (clazztype.tag == FORALL && !pt.isErroneous()) { |
1823 if (clazztype.tag == FORALL && !pt.isErroneous()) { |
1838 //if the resolved constructor's return type has some uninferred |
1824 //if the resolved constructor's return type has some uninferred |
1839 //type-variables, infer them using the expected type and declared |
1825 //type-variables, infer them using the expected type and declared |
1840 //bounds (JLS 15.12.2.8). |
1826 //bounds (JLS 15.12.2.8). |
1841 try { |
1827 try { |
1861 * the synthetic scope is added a generic constructor of the kind: |
1847 * the synthetic scope is added a generic constructor of the kind: |
1862 * <X,Y>Foo<X,Y>(X x, Y y). This is crucial in order to enable diamond |
1848 * <X,Y>Foo<X,Y>(X x, Y y). This is crucial in order to enable diamond |
1863 * inference. The inferred return type of the synthetic constructor IS |
1849 * inference. The inferred return type of the synthetic constructor IS |
1864 * the inferred type for the diamond operator. |
1850 * the inferred type for the diamond operator. |
1865 */ |
1851 */ |
1866 private Pair<Scope, Scope> getSyntheticScopeMapping(Type ctype, boolean overrideProtectedAccess) { |
1852 private Pair<Scope, Scope> getSyntheticScopeMapping(Type ctype) { |
1867 if (ctype.tag != CLASS) { |
1853 if (ctype.tag != CLASS) { |
1868 return erroneousMapping; |
1854 return erroneousMapping; |
1869 } |
1855 } |
|
1856 |
1870 Pair<Scope, Scope> mapping = |
1857 Pair<Scope, Scope> mapping = |
1871 new Pair<Scope, Scope>(ctype.tsym.members(), new Scope(ctype.tsym)); |
1858 new Pair<Scope, Scope>(ctype.tsym.members(), new Scope(ctype.tsym)); |
1872 List<Type> typevars = ctype.tsym.type.getTypeArguments(); |
1859 |
|
1860 //for each constructor in the original scope, create a synthetic constructor |
|
1861 //whose return type is the type of the class in which the constructor is |
|
1862 //declared, and insert it into the new scope. |
1873 for (Scope.Entry e = mapping.fst.lookup(names.init); |
1863 for (Scope.Entry e = mapping.fst.lookup(names.init); |
1874 e.scope != null; |
1864 e.scope != null; |
1875 e = e.next()) { |
1865 e = e.next()) { |
1876 MethodSymbol newConstr = (MethodSymbol) e.sym.clone(ctype.tsym); |
1866 Type synthRestype = new ClassType(ctype.getEnclosingType(), |
1877 if (overrideProtectedAccess && (newConstr.flags() & PROTECTED) != 0) { |
1867 ctype.tsym.type.getTypeArguments(), |
1878 //make protected constructor public (this is required for |
1868 ctype.tsym); |
1879 //anonymous inner class creation expressions using diamond) |
1869 MethodSymbol synhConstr = new MethodSymbol(e.sym.flags(), |
1880 newConstr.flags_field |= PUBLIC; |
1870 names.init, |
1881 newConstr.flags_field &= ~PROTECTED; |
1871 types.createMethodTypeWithReturn(e.sym.type, synthRestype), |
1882 } |
1872 e.sym.owner); |
1883 newConstr.name = names.init; |
1873 mapping.snd.enter(synhConstr); |
1884 List<Type> oldTypeargs = List.nil(); |
|
1885 if (newConstr.type.tag == FORALL) { |
|
1886 oldTypeargs = ((ForAll) newConstr.type).tvars; |
|
1887 } |
|
1888 newConstr.type = new MethodType(newConstr.type.getParameterTypes(), |
|
1889 new ClassType(ctype.getEnclosingType(), ctype.tsym.type.getTypeArguments(), ctype.tsym), |
|
1890 newConstr.type.getThrownTypes(), |
|
1891 syms.methodClass); |
|
1892 newConstr.type = new ForAll(typevars.prependList(oldTypeargs), newConstr.type); |
|
1893 mapping.snd.enter(newConstr); |
|
1894 } |
1874 } |
1895 return mapping; |
1875 return mapping; |
1896 } |
1876 } |
1897 |
1877 |
1898 private final Pair<Scope,Scope> erroneousMapping = new Pair<Scope,Scope>(null, null); |
1878 private final Pair<Scope,Scope> erroneousMapping = new Pair<Scope,Scope>(null, null); |