68 import com.sun.tools.javac.platform.PlatformDescription;
69 import com.sun.tools.javac.processing.*;
70 import com.sun.tools.javac.tree.*;
71 import com.sun.tools.javac.tree.JCTree.JCClassDecl;
72 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
73 import com.sun.tools.javac.tree.JCTree.JCExpression;
74 import com.sun.tools.javac.tree.JCTree.JCLambda;
75 import com.sun.tools.javac.tree.JCTree.JCMemberReference;
76 import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
77 import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
78 import com.sun.tools.javac.util.*;
79 import com.sun.tools.javac.util.Context.Key;
80 import com.sun.tools.javac.util.DefinedBy.Api;
81 import com.sun.tools.javac.util.JCDiagnostic.Factory;
82 import com.sun.tools.javac.util.Log.DiagnosticHandler;
83 import com.sun.tools.javac.util.Log.DiscardDiagnosticHandler;
84 import com.sun.tools.javac.util.Log.WriterKind;
85
86 import static com.sun.tools.javac.code.Kinds.Kind.*;
87
88 import com.sun.tools.javac.code.Lint;
89 import com.sun.tools.javac.code.Lint.LintCategory;
90 import com.sun.tools.javac.code.Symbol.ModuleSymbol;
91
92 import com.sun.tools.javac.resources.CompilerProperties.Errors;
93 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
94 import com.sun.tools.javac.resources.CompilerProperties.Notes;
95 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
96
97 import static com.sun.tools.javac.code.TypeTag.CLASS;
98 import static com.sun.tools.javac.main.Option.*;
99 import com.sun.tools.javac.tree.JCTree.JCBindingPattern;
100 import com.sun.tools.javac.tree.JCTree.JCInstanceOf;
101 import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
102
103 import static javax.tools.StandardLocation.CLASS_OUTPUT;
104 import static javax.tools.StandardLocation.ANNOTATION_PROCESSOR_PATH;
105
106 import com.sun.tools.javac.tree.JCTree.JCModuleDecl;
107 import com.sun.tools.javac.tree.JCTree.JCRecordPattern;
108 import com.sun.tools.javac.tree.JCTree.JCSwitch;
109 import com.sun.tools.javac.tree.JCTree.JCSwitchExpression;
1546 if (compileStates.isDone(env, CompileState.LOWER)) {
1547 results.addAll(desugaredEnvs.get(env));
1548 return;
1549 }
1550
1551 // Ensure the file has reached the WARN state
1552 if (!compileStates.isDone(env, CompileState.WARN))
1553 warn(env);
1554
1555 /**
1556 * Ensure that superclasses of C are desugared before C itself. This is
1557 * required for two reasons: (i) as erasure (TransTypes) destroys
1558 * information needed in flow analysis and (ii) as some checks carried
1559 * out during lowering require that all synthetic fields/methods have
1560 * already been added to C and its superclasses.
1561 */
1562 class ScanNested extends TreeScanner {
1563 Set<Env<AttrContext>> dependencies = new LinkedHashSet<>();
1564 protected boolean hasLambdas;
1565 protected boolean hasPatterns;
1566 @Override
1567 public void visitClassDef(JCClassDecl node) {
1568 Type st = types.supertype(node.sym.type);
1569 boolean envForSuperTypeFound = false;
1570 while (!envForSuperTypeFound && st.hasTag(CLASS)) {
1571 ClassSymbol c = st.tsym.outermostClass();
1572 Env<AttrContext> stEnv = enter.getEnv(c);
1573 if (stEnv != null && env != stEnv) {
1574 if (dependencies.add(stEnv)) {
1575 boolean prevHasLambdas = hasLambdas;
1576 boolean prevHasPatterns = hasPatterns;
1577 try {
1578 scan(stEnv.tree);
1579 } finally {
1580 /*
1581 * ignore any updates to hasLambdas and hasPatterns
1582 * made during the nested scan, this ensures an
1583 * initialized LambdaToMethod or TransPatterns is
1584 * available only to those classes that contain
1585 * lambdas or patterns, respectivelly
1586 */
1587 hasLambdas = prevHasLambdas;
1588 hasPatterns = prevHasPatterns;
1589 }
1590 }
1591 envForSuperTypeFound = true;
1592 }
1593 st = types.supertype(st);
1594 }
1595 super.visitClassDef(node);
1596 }
1597 @Override
1598 public void visitLambda(JCLambda tree) {
1599 hasLambdas = true;
1600 super.visitLambda(tree);
1601 }
1602 @Override
1603 public void visitReference(JCMemberReference tree) {
1604 hasLambdas = true;
1605 super.visitReference(tree);
1606 }
1607 @Override
1608 public void visitBindingPattern(JCBindingPattern tree) {
1609 hasPatterns = true;
1610 super.visitBindingPattern(tree);
1611 }
1612 @Override
1613 public void visitTypeTest(JCInstanceOf tree) {
1614 if (tree.pattern.type.isPrimitive()) {
1615 hasPatterns = true;
1616 }
1617 super.visitTypeTest(tree);
1618 }
1619 @Override
1620 public void visitRecordPattern(JCRecordPattern that) {
1621 hasPatterns = true;
1622 super.visitRecordPattern(that);
1623 }
1624 @Override
1625 public void visitSwitch(JCSwitch tree) {
1626 hasPatterns |= tree.patternSwitch;
1627 super.visitSwitch(tree);
1628 }
1629 @Override
1630 public void visitSwitchExpression(JCSwitchExpression tree) {
1631 hasPatterns |= tree.patternSwitch;
1632 super.visitSwitchExpression(tree);
1633 }
1634 }
1635 ScanNested scanner = new ScanNested();
1636 scanner.scan(env.tree);
1637 for (Env<AttrContext> dep: scanner.dependencies) {
1638 if (!compileStates.isDone(dep, CompileState.WARN))
1639 desugaredEnvs.put(dep, desugar(warn(flow(attribute(dep)))));
1640 }
1641
1642 //We need to check for error another time as more classes might
1643 //have been attributed and analyzed at this stage
1644 if (shouldStop(CompileState.TRANSTYPES))
1645 return;
1646
1647 if (verboseCompilePolicy)
1648 printNote("[desugar " + env.enclClass.sym + "]");
1649
1650 JavaFileObject prev = log.useSource(env.enclClass.sym.sourcefile != null ?
1651 env.enclClass.sym.sourcefile :
1652 env.toplevel.sourcefile);
1653 try {
1654 //save tree prior to rewriting
1655 JCTree untranslated = env.tree;
1656
1657 make.at(Position.FIRSTPOS);
1658 TreeMaker localMake = make.forToplevel(env.toplevel);
1659
1698 }
1699 return;
1700 }
1701
1702 //translate out inner classes
1703 List<JCTree> cdefs = lower.translateTopLevelClass(env, env.tree, localMake);
1704 compileStates.put(env, CompileState.LOWER);
1705
1706 if (shouldStop(CompileState.LOWER))
1707 return;
1708
1709 if (scanner.hasLambdas) {
1710 if (shouldStop(CompileState.UNLAMBDA))
1711 return;
1712
1713 for (JCTree def : cdefs) {
1714 LambdaToMethod.instance(context).translateTopLevelClass(env, def, localMake);
1715 }
1716 compileStates.put(env, CompileState.UNLAMBDA);
1717 }
1718
1719 //generate code for each class
1720 for (List<JCTree> l = cdefs; l.nonEmpty(); l = l.tail) {
1721 JCClassDecl cdef = (JCClassDecl)l.head;
1722 results.add(new Pair<>(env, cdef));
1723 }
1724 }
1725 finally {
1726 log.useSource(prev);
1727 }
1728
1729 }
1730
1731 /** Generates the source or class file for a list of classes.
1732 * The decision to generate a source file or a class file is
1733 * based upon the compiler's options.
1734 * Generation stops if an error occurs while writing files.
1735 */
1736 public void generate(Queue<Pair<Env<AttrContext>, JCClassDecl>> queue) {
1737 generate(queue, null);
|
68 import com.sun.tools.javac.platform.PlatformDescription;
69 import com.sun.tools.javac.processing.*;
70 import com.sun.tools.javac.tree.*;
71 import com.sun.tools.javac.tree.JCTree.JCClassDecl;
72 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
73 import com.sun.tools.javac.tree.JCTree.JCExpression;
74 import com.sun.tools.javac.tree.JCTree.JCLambda;
75 import com.sun.tools.javac.tree.JCTree.JCMemberReference;
76 import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
77 import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
78 import com.sun.tools.javac.util.*;
79 import com.sun.tools.javac.util.Context.Key;
80 import com.sun.tools.javac.util.DefinedBy.Api;
81 import com.sun.tools.javac.util.JCDiagnostic.Factory;
82 import com.sun.tools.javac.util.Log.DiagnosticHandler;
83 import com.sun.tools.javac.util.Log.DiscardDiagnosticHandler;
84 import com.sun.tools.javac.util.Log.WriterKind;
85
86 import static com.sun.tools.javac.code.Kinds.Kind.*;
87
88 import com.sun.tools.javac.code.Symbol.ModuleSymbol;
89
90 import com.sun.tools.javac.resources.CompilerProperties.Errors;
91 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
92 import com.sun.tools.javac.resources.CompilerProperties.Notes;
93 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
94
95 import static com.sun.tools.javac.code.TypeTag.CLASS;
96 import static com.sun.tools.javac.main.Option.*;
97 import com.sun.tools.javac.tree.JCTree.JCBindingPattern;
98 import com.sun.tools.javac.tree.JCTree.JCInstanceOf;
99 import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
100
101 import static javax.tools.StandardLocation.CLASS_OUTPUT;
102 import static javax.tools.StandardLocation.ANNOTATION_PROCESSOR_PATH;
103
104 import com.sun.tools.javac.tree.JCTree.JCModuleDecl;
105 import com.sun.tools.javac.tree.JCTree.JCRecordPattern;
106 import com.sun.tools.javac.tree.JCTree.JCSwitch;
107 import com.sun.tools.javac.tree.JCTree.JCSwitchExpression;
1544 if (compileStates.isDone(env, CompileState.LOWER)) {
1545 results.addAll(desugaredEnvs.get(env));
1546 return;
1547 }
1548
1549 // Ensure the file has reached the WARN state
1550 if (!compileStates.isDone(env, CompileState.WARN))
1551 warn(env);
1552
1553 /**
1554 * Ensure that superclasses of C are desugared before C itself. This is
1555 * required for two reasons: (i) as erasure (TransTypes) destroys
1556 * information needed in flow analysis and (ii) as some checks carried
1557 * out during lowering require that all synthetic fields/methods have
1558 * already been added to C and its superclasses.
1559 */
1560 class ScanNested extends TreeScanner {
1561 Set<Env<AttrContext>> dependencies = new LinkedHashSet<>();
1562 protected boolean hasLambdas;
1563 protected boolean hasPatterns;
1564 protected boolean hasValueClasses;
1565 protected boolean hasStrictFields;
1566 @Override
1567 public void visitClassDef(JCClassDecl node) {
1568 Type st = types.supertype(node.sym.type);
1569 boolean envForSuperTypeFound = false;
1570 while (!envForSuperTypeFound && st.hasTag(CLASS)) {
1571 ClassSymbol c = st.tsym.outermostClass();
1572 Env<AttrContext> stEnv = enter.getEnv(c);
1573 if (stEnv != null && env != stEnv) {
1574 if (dependencies.add(stEnv)) {
1575 boolean prevHasLambdas = hasLambdas;
1576 boolean prevHasPatterns = hasPatterns;
1577 boolean prevHasStrictFields = hasStrictFields;
1578 try {
1579 scan(stEnv.tree);
1580 } finally {
1581 /*
1582 * ignore any updates to hasLambdas and hasPatterns
1583 * made during the nested scan, this ensures an
1584 * initialized LambdaToMethod or TransPatterns is
1585 * available only to those classes that contain
1586 * lambdas or patterns, respectivelly
1587 */
1588 hasLambdas = prevHasLambdas;
1589 hasPatterns = prevHasPatterns;
1590 hasStrictFields = prevHasStrictFields;
1591 }
1592 }
1593 envForSuperTypeFound = true;
1594 }
1595 st = types.supertype(st);
1596 }
1597 hasValueClasses = node.sym.isValueClass();
1598 super.visitClassDef(node);
1599 }
1600 @Override
1601 public void visitLambda(JCLambda tree) {
1602 hasLambdas = true;
1603 super.visitLambda(tree);
1604 }
1605 @Override
1606 public void visitReference(JCMemberReference tree) {
1607 hasLambdas = true;
1608 super.visitReference(tree);
1609 }
1610 @Override
1611 public void visitBindingPattern(JCBindingPattern tree) {
1612 hasPatterns = true;
1613 super.visitBindingPattern(tree);
1614 }
1615 @Override
1616 public void visitTypeTest(JCInstanceOf tree) {
1617 if (tree.pattern.type.isPrimitive()) {
1618 hasPatterns = true;
1619 }
1620 super.visitTypeTest(tree);
1621 }
1622 @Override
1623 public void visitRecordPattern(JCRecordPattern that) {
1624 hasPatterns = true;
1625 super.visitRecordPattern(that);
1626 }
1627 @Override
1628 public void visitSwitch(JCSwitch tree) {
1629 hasPatterns |= tree.patternSwitch;
1630 super.visitSwitch(tree);
1631 }
1632 @Override
1633 public void visitSwitchExpression(JCSwitchExpression tree) {
1634 hasPatterns |= tree.patternSwitch;
1635 super.visitSwitchExpression(tree);
1636 }
1637
1638 @Override
1639 public void visitVarDef(JCVariableDecl tree) {
1640 hasStrictFields |= tree.sym.isStrict();
1641 super.visitVarDef(tree);
1642 }
1643 }
1644 ScanNested scanner = new ScanNested();
1645 scanner.scan(env.tree);
1646 for (Env<AttrContext> dep: scanner.dependencies) {
1647 if (!compileStates.isDone(dep, CompileState.WARN))
1648 desugaredEnvs.put(dep, desugar(warn(flow(attribute(dep)))));
1649 }
1650
1651 //We need to check for error another time as more classes might
1652 //have been attributed and analyzed at this stage
1653 if (shouldStop(CompileState.TRANSTYPES))
1654 return;
1655
1656 if (verboseCompilePolicy)
1657 printNote("[desugar " + env.enclClass.sym + "]");
1658
1659 JavaFileObject prev = log.useSource(env.enclClass.sym.sourcefile != null ?
1660 env.enclClass.sym.sourcefile :
1661 env.toplevel.sourcefile);
1662 try {
1663 //save tree prior to rewriting
1664 JCTree untranslated = env.tree;
1665
1666 make.at(Position.FIRSTPOS);
1667 TreeMaker localMake = make.forToplevel(env.toplevel);
1668
1707 }
1708 return;
1709 }
1710
1711 //translate out inner classes
1712 List<JCTree> cdefs = lower.translateTopLevelClass(env, env.tree, localMake);
1713 compileStates.put(env, CompileState.LOWER);
1714
1715 if (shouldStop(CompileState.LOWER))
1716 return;
1717
1718 if (scanner.hasLambdas) {
1719 if (shouldStop(CompileState.UNLAMBDA))
1720 return;
1721
1722 for (JCTree def : cdefs) {
1723 LambdaToMethod.instance(context).translateTopLevelClass(env, def, localMake);
1724 }
1725 compileStates.put(env, CompileState.UNLAMBDA);
1726 }
1727
1728 if (scanner.hasValueClasses || scanner.hasStrictFields) {
1729 if (shouldStop(CompileState.STRICT_FIELDS_PROXIES))
1730 return;
1731 for (JCTree def : cdefs) {
1732 LocalProxyVarsGen.instance(context).translateTopLevelClass(def, localMake);
1733 }
1734 compileStates.put(env, CompileState.STRICT_FIELDS_PROXIES);
1735 }
1736
1737 //generate code for each class
1738 for (List<JCTree> l = cdefs; l.nonEmpty(); l = l.tail) {
1739 JCClassDecl cdef = (JCClassDecl)l.head;
1740 results.add(new Pair<>(env, cdef));
1741 }
1742 }
1743 finally {
1744 log.useSource(prev);
1745 }
1746
1747 }
1748
1749 /** Generates the source or class file for a list of classes.
1750 * The decision to generate a source file or a class file is
1751 * based upon the compiler's options.
1752 * Generation stops if an error occurs while writing files.
1753 */
1754 public void generate(Queue<Pair<Env<AttrContext>, JCClassDecl>> queue) {
1755 generate(queue, null);
|