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

changeset 950
f5b5112ee1cc
parent 949
ddec8c712e85
child 951
de1c65ecfec2
equal deleted inserted replaced
949:ddec8c712e85 950:f5b5112ee1cc
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);

mercurial