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;
1531 if (compileStates.isDone(env, CompileState.LOWER)) {
1532 results.addAll(desugaredEnvs.get(env));
1533 return;
1534 }
1535
1536 // Ensure the file has reached the WARN state
1537 if (!compileStates.isDone(env, CompileState.WARN))
1538 warn(env);
1539
1540 /**
1541 * Ensure that superclasses of C are desugared before C itself. This is
1542 * required for two reasons: (i) as erasure (TransTypes) destroys
1543 * information needed in flow analysis and (ii) as some checks carried
1544 * out during lowering require that all synthetic fields/methods have
1545 * already been added to C and its superclasses.
1546 */
1547 class ScanNested extends TreeScanner {
1548 Set<Env<AttrContext>> dependencies = new LinkedHashSet<>();
1549 protected boolean hasLambdas;
1550 protected boolean hasPatterns;
1551 @Override
1552 public void visitClassDef(JCClassDecl node) {
1553 Type st = types.supertype(node.sym.type);
1554 boolean envForSuperTypeFound = false;
1555 while (!envForSuperTypeFound && st.hasTag(CLASS)) {
1556 ClassSymbol c = st.tsym.outermostClass();
1557 Env<AttrContext> stEnv = enter.getEnv(c);
1558 if (stEnv != null && env != stEnv) {
1559 if (dependencies.add(stEnv)) {
1560 boolean prevHasLambdas = hasLambdas;
1561 boolean prevHasPatterns = hasPatterns;
1562 try {
1563 scan(stEnv.tree);
1564 } finally {
1565 /*
1566 * ignore any updates to hasLambdas and hasPatterns
1567 * made during the nested scan, this ensures an
1568 * initialized LambdaToMethod or TransPatterns is
1569 * available only to those classes that contain
1570 * lambdas or patterns, respectivelly
1571 */
1572 hasLambdas = prevHasLambdas;
1573 hasPatterns = prevHasPatterns;
1574 }
1575 }
1576 envForSuperTypeFound = true;
1577 }
1578 st = types.supertype(st);
1579 }
1580 super.visitClassDef(node);
1581 }
1582 @Override
1583 public void visitLambda(JCLambda tree) {
1584 hasLambdas = true;
1585 super.visitLambda(tree);
1586 }
1587 @Override
1588 public void visitReference(JCMemberReference tree) {
1589 hasLambdas = true;
1590 super.visitReference(tree);
1591 }
1592 @Override
1593 public void visitBindingPattern(JCBindingPattern tree) {
1594 hasPatterns = true;
1595 super.visitBindingPattern(tree);
1596 }
1597 @Override
1598 public void visitTypeTest(JCInstanceOf tree) {
1599 if (tree.pattern.type.isPrimitive()) {
1600 hasPatterns = true;
1601 }
1602 super.visitTypeTest(tree);
1603 }
1604 @Override
1605 public void visitRecordPattern(JCRecordPattern that) {
1606 hasPatterns = true;
1607 super.visitRecordPattern(that);
1608 }
1609 @Override
1610 public void visitSwitch(JCSwitch tree) {
1611 hasPatterns |= tree.patternSwitch;
1612 super.visitSwitch(tree);
1613 }
1614 @Override
1615 public void visitSwitchExpression(JCSwitchExpression tree) {
1616 hasPatterns |= tree.patternSwitch;
1617 super.visitSwitchExpression(tree);
1618 }
1619 }
1620 ScanNested scanner = new ScanNested();
1621 scanner.scan(env.tree);
1622 for (Env<AttrContext> dep: scanner.dependencies) {
1623 if (!compileStates.isDone(dep, CompileState.WARN))
1624 desugaredEnvs.put(dep, desugar(warn(flow(attribute(dep)))));
1625 }
1626
1627 //We need to check for error another time as more classes might
1628 //have been attributed and analyzed at this stage
1629 if (shouldStop(CompileState.TRANSTYPES))
1630 return;
1631
1632 if (verboseCompilePolicy)
1633 printNote("[desugar " + env.enclClass.sym + "]");
1634
1635 JavaFileObject prev = log.useSource(env.enclClass.sym.sourcefile != null ?
1636 env.enclClass.sym.sourcefile :
1637 env.toplevel.sourcefile);
1638 try {
1639 //save tree prior to rewriting
1640 JCTree untranslated = env.tree;
1641
1642 make.at(Position.FIRSTPOS);
1643 TreeMaker localMake = make.forToplevel(env.toplevel);
1644
1683 }
1684 return;
1685 }
1686
1687 //translate out inner classes
1688 List<JCTree> cdefs = lower.translateTopLevelClass(env, env.tree, localMake);
1689 compileStates.put(env, CompileState.LOWER);
1690
1691 if (shouldStop(CompileState.LOWER))
1692 return;
1693
1694 if (scanner.hasLambdas) {
1695 if (shouldStop(CompileState.UNLAMBDA))
1696 return;
1697
1698 for (JCTree def : cdefs) {
1699 LambdaToMethod.instance(context).translateTopLevelClass(env, def, localMake);
1700 }
1701 compileStates.put(env, CompileState.UNLAMBDA);
1702 }
1703
1704 //generate code for each class
1705 for (List<JCTree> l = cdefs; l.nonEmpty(); l = l.tail) {
1706 JCClassDecl cdef = (JCClassDecl)l.head;
1707 results.add(new Pair<>(env, cdef));
1708 }
1709 }
1710 finally {
1711 log.useSource(prev);
1712 }
1713
1714 }
1715
1716 /** Generates the source or class file for a list of classes.
1717 * The decision to generate a source file or a class file is
1718 * based upon the compiler's options.
1719 * Generation stops if an error occurs while writing files.
1720 */
1721 public void generate(Queue<Pair<Env<AttrContext>, JCClassDecl>> queue) {
1722 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;
1529 if (compileStates.isDone(env, CompileState.LOWER)) {
1530 results.addAll(desugaredEnvs.get(env));
1531 return;
1532 }
1533
1534 // Ensure the file has reached the WARN state
1535 if (!compileStates.isDone(env, CompileState.WARN))
1536 warn(env);
1537
1538 /**
1539 * Ensure that superclasses of C are desugared before C itself. This is
1540 * required for two reasons: (i) as erasure (TransTypes) destroys
1541 * information needed in flow analysis and (ii) as some checks carried
1542 * out during lowering require that all synthetic fields/methods have
1543 * already been added to C and its superclasses.
1544 */
1545 class ScanNested extends TreeScanner {
1546 Set<Env<AttrContext>> dependencies = new LinkedHashSet<>();
1547 protected boolean hasLambdas;
1548 protected boolean hasPatterns;
1549 protected boolean hasValueClasses;
1550 protected boolean hasStrictFields;
1551 @Override
1552 public void visitClassDef(JCClassDecl node) {
1553 Type st = types.supertype(node.sym.type);
1554 boolean envForSuperTypeFound = false;
1555 while (!envForSuperTypeFound && st.hasTag(CLASS)) {
1556 ClassSymbol c = st.tsym.outermostClass();
1557 Env<AttrContext> stEnv = enter.getEnv(c);
1558 if (stEnv != null && env != stEnv) {
1559 if (dependencies.add(stEnv)) {
1560 boolean prevHasLambdas = hasLambdas;
1561 boolean prevHasPatterns = hasPatterns;
1562 boolean prevHasStrictFields = hasStrictFields;
1563 try {
1564 scan(stEnv.tree);
1565 } finally {
1566 /*
1567 * ignore any updates to hasLambdas and hasPatterns
1568 * made during the nested scan, this ensures an
1569 * initialized LambdaToMethod or TransPatterns is
1570 * available only to those classes that contain
1571 * lambdas or patterns, respectivelly
1572 */
1573 hasLambdas = prevHasLambdas;
1574 hasPatterns = prevHasPatterns;
1575 hasStrictFields = prevHasStrictFields;
1576 }
1577 }
1578 envForSuperTypeFound = true;
1579 }
1580 st = types.supertype(st);
1581 }
1582 hasValueClasses = node.sym.isValueClass();
1583 super.visitClassDef(node);
1584 }
1585 @Override
1586 public void visitLambda(JCLambda tree) {
1587 hasLambdas = true;
1588 super.visitLambda(tree);
1589 }
1590 @Override
1591 public void visitReference(JCMemberReference tree) {
1592 hasLambdas = true;
1593 super.visitReference(tree);
1594 }
1595 @Override
1596 public void visitBindingPattern(JCBindingPattern tree) {
1597 hasPatterns = true;
1598 super.visitBindingPattern(tree);
1599 }
1600 @Override
1601 public void visitTypeTest(JCInstanceOf tree) {
1602 if (tree.pattern.type.isPrimitive()) {
1603 hasPatterns = true;
1604 }
1605 super.visitTypeTest(tree);
1606 }
1607 @Override
1608 public void visitRecordPattern(JCRecordPattern that) {
1609 hasPatterns = true;
1610 super.visitRecordPattern(that);
1611 }
1612 @Override
1613 public void visitSwitch(JCSwitch tree) {
1614 hasPatterns |= tree.patternSwitch;
1615 super.visitSwitch(tree);
1616 }
1617 @Override
1618 public void visitSwitchExpression(JCSwitchExpression tree) {
1619 hasPatterns |= tree.patternSwitch;
1620 super.visitSwitchExpression(tree);
1621 }
1622
1623 @Override
1624 public void visitVarDef(JCVariableDecl tree) {
1625 hasStrictFields |= tree.sym.isStrict();
1626 super.visitVarDef(tree);
1627 }
1628 }
1629 ScanNested scanner = new ScanNested();
1630 scanner.scan(env.tree);
1631 for (Env<AttrContext> dep: scanner.dependencies) {
1632 if (!compileStates.isDone(dep, CompileState.WARN))
1633 desugaredEnvs.put(dep, desugar(warn(flow(attribute(dep)))));
1634 }
1635
1636 //We need to check for error another time as more classes might
1637 //have been attributed and analyzed at this stage
1638 if (shouldStop(CompileState.TRANSTYPES))
1639 return;
1640
1641 if (verboseCompilePolicy)
1642 printNote("[desugar " + env.enclClass.sym + "]");
1643
1644 JavaFileObject prev = log.useSource(env.enclClass.sym.sourcefile != null ?
1645 env.enclClass.sym.sourcefile :
1646 env.toplevel.sourcefile);
1647 try {
1648 //save tree prior to rewriting
1649 JCTree untranslated = env.tree;
1650
1651 make.at(Position.FIRSTPOS);
1652 TreeMaker localMake = make.forToplevel(env.toplevel);
1653
1692 }
1693 return;
1694 }
1695
1696 //translate out inner classes
1697 List<JCTree> cdefs = lower.translateTopLevelClass(env, env.tree, localMake);
1698 compileStates.put(env, CompileState.LOWER);
1699
1700 if (shouldStop(CompileState.LOWER))
1701 return;
1702
1703 if (scanner.hasLambdas) {
1704 if (shouldStop(CompileState.UNLAMBDA))
1705 return;
1706
1707 for (JCTree def : cdefs) {
1708 LambdaToMethod.instance(context).translateTopLevelClass(env, def, localMake);
1709 }
1710 compileStates.put(env, CompileState.UNLAMBDA);
1711 }
1712
1713 if (scanner.hasValueClasses || scanner.hasStrictFields) {
1714 if (shouldStop(CompileState.STRICT_FIELDS_PROXIES))
1715 return;
1716 for (JCTree def : cdefs) {
1717 LocalProxyVarsGen.instance(context).translateTopLevelClass(def, localMake);
1718 }
1719 compileStates.put(env, CompileState.STRICT_FIELDS_PROXIES);
1720 }
1721
1722 //generate code for each class
1723 for (List<JCTree> l = cdefs; l.nonEmpty(); l = l.tail) {
1724 JCClassDecl cdef = (JCClassDecl)l.head;
1725 results.add(new Pair<>(env, cdef));
1726 }
1727 }
1728 finally {
1729 log.useSource(prev);
1730 }
1731
1732 }
1733
1734 /** Generates the source or class file for a list of classes.
1735 * The decision to generate a source file or a class file is
1736 * based upon the compiler's options.
1737 * Generation stops if an error occurs while writing files.
1738 */
1739 public void generate(Queue<Pair<Env<AttrContext>, JCClassDecl>> queue) {
1740 generate(queue, null);
|