01: // (C) Copyright 2001 Samuele Pedroni
02:
03: package org.python.compiler;
04:
05: import org.python.parser.*;
06: import org.python.parser.ast.*;
07: import org.python.parser.ast.Module;
08:
09: public class Future extends Object implements
10: PythonGrammarTreeConstants {
11:
12: private boolean division;
13: private boolean generators;
14:
15: private static final String FUTURE = "__future__";
16:
17: private boolean check(ImportFrom cand) throws Exception {
18: if (!cand.module.equals(FUTURE))
19: return false;
20: int n = cand.names.length;
21: if (n == 0) {
22: throw new ParseException(
23: "future statement does not support import *", cand);
24: }
25: for (int i = 0; i < n; i++) {
26: String feature = cand.names[i].name;
27: // *known* features
28: if (feature.equals("nested_scopes")) {
29: continue;
30: }
31: if (feature.equals("division")) {
32: division = true;
33: continue;
34: }
35: if (feature.equals("generators")) {
36: generators = true;
37: continue;
38: }
39: throw new ParseException("future feature " + feature
40: + " is not defined", cand);
41: }
42: return true;
43: }
44:
45: public void preprocessFutures(modType node,
46: org.python.core.CompilerFlags cflags) throws Exception {
47: if (cflags != null) {
48: division = cflags.division;
49: }
50: int beg = 0;
51: stmtType[] suite = null;
52: if (node instanceof Module) {
53: suite = ((Module) node).body;
54: if (suite.length > 0 && suite[0] instanceof Expr
55: && ((Expr) suite[0]).value instanceof Str) {
56: beg++;
57: }
58: } else if (node instanceof Interactive) {
59: suite = ((Interactive) node).body;
60: } else {
61: return;
62: }
63:
64: for (int i = beg; i < suite.length; i++) {
65: stmtType stmt = suite[i];
66: if (!(stmt instanceof ImportFrom))
67: break;
68: stmt.from_future_checked = true;
69: if (!check((ImportFrom) stmt))
70: break;
71: }
72:
73: if (cflags != null) {
74: cflags.division = cflags.division || division;
75: }
76: if (cflags != null) {
77: cflags.generator_allowed = cflags.generator_allowed
78: || generators;
79: }
80: }
81:
82: public static void checkFromFuture(ImportFrom node)
83: throws Exception {
84: if (node.from_future_checked)
85: return;
86: if (node.module.equals(FUTURE)) {
87: throw new ParseException(
88: "from __future__ imports must occur "
89: + "at the beginning of the file", node);
90: }
91: node.from_future_checked = true;
92: }
93:
94: public boolean areDivisionOn() {
95: return division;
96: }
97:
98: }
|