Index: x10.compiler/src/x10/ast/AmbMacroTypeNode_c.java =================================================================== --- x10.compiler/src/x10/ast/AmbMacroTypeNode_c.java (revision 23318) +++ x10.compiler/src/x10/ast/AmbMacroTypeNode_c.java (working copy) @@ -345,10 +345,15 @@ } public Context enterChildScope(Node child, Context c) { + Context oldC = c; if (child != this.prefix) { TypeSystem ts = c.typeSystem(); c = c.pushDepType(Types.ref(ts.unknownType(this.position))); } + if (c == oldC && c.inAnnotation()) { + c = c.shallowCopy(); + } + c.clearAnnotation(); Context cc = super.enterChildScope(child, c); return cc; } Index: x10.compiler/src/x10/ast/X10MethodDecl_c.java =================================================================== --- x10.compiler/src/x10/ast/X10MethodDecl_c.java (revision 23318) +++ x10.compiler/src/x10/ast/X10MethodDecl_c.java (working copy) @@ -75,6 +75,7 @@ import polyglot.types.Types; import polyglot.util.CodeWriter; import polyglot.util.CollectionUtil; +import x10.util.AnnotationUtils; import x10.util.CollectionFactory; import polyglot.util.ErrorInfo; import polyglot.util.InternalCompilerError; @@ -1111,6 +1112,21 @@ nn = (X10MethodDecl) nn.returnType(nf.CanonicalTypeNode(nn.returnType().position(), t)); } + List bodyAnnotations = AnnotationUtils.annotationNodesMatching(nn.body(), xts.Throws()); + List rtypeAnnotations = AnnotationUtils.annotationNodesMatching(nn.returnType(), xts.Throws()); + if ((bodyAnnotations != null && !bodyAnnotations.isEmpty()) || + (rtypeAnnotations != null && !rtypeAnnotations.isEmpty())) + { + List> annotations = new ArrayList>(nn.methodDef().defAnnotations()); + for (AnnotationNode an : bodyAnnotations) { + annotations.add(an.annotationType().typeRef()); + } + for (AnnotationNode an : rtypeAnnotations) { + annotations.add(an.annotationType().typeRef()); + } + nn.methodDef().setDefAnnotations(annotations); + } + return nn; } Index: x10.compiler/src/x10/ast/X10AmbTypeNode_c.java =================================================================== --- x10.compiler/src/x10/ast/X10AmbTypeNode_c.java (revision 23318) +++ x10.compiler/src/x10/ast/X10AmbTypeNode_c.java (working copy) @@ -80,8 +80,7 @@ NodeFactory nf = (NodeFactory) tc.nodeFactory(); Context c = (Context) tc.context(); - if (! c.inAnnotation() || - (c.pop()!=null && c.pop().inAnnotation())) // To handle "@Throws2[Throwable]" (because Throwable is not an interface) see XTENLANG-2855 + if (! c.inAnnotation()) return null; SemanticException ex; Index: x10.compiler/src/x10/visit/X10PrettyPrinterVisitor.java =================================================================== --- x10.compiler/src/x10/visit/X10PrettyPrinterVisitor.java (revision 23318) +++ x10.compiler/src/x10/visit/X10PrettyPrinterVisitor.java (working copy) @@ -163,6 +163,7 @@ import x10.types.X10FieldInstance; import x10.types.X10ParsedClassType_c; import x10.types.constraints.SubtypeConstraint; +import x10.util.AnnotationUtils; import x10.util.CollectionFactory; import x10.util.HierarchyUtils; import x10c.ast.X10CBackingArrayAccessAssign_c; @@ -1354,7 +1355,16 @@ printConstructorFormals(n, true); - w.write(Emitter.printThrowsClause(n.constructorDef())); + boolean isFirst = true; + for (Type _throws : AnnotationUtils.getThrowsTypes(n)) { + if (isFirst) { + w.write(" throws "); + isFirst = false; + } else { + w.write(", "); + } + er.printType(_throws, 0); + } w.write("{"); w.begin(4); @@ -1410,8 +1420,18 @@ printConstructorFormals(n, true); - w.write(Emitter.printThrowsClause(n.constructorDef())); + boolean isFirst = true; + for (Type _throws : AnnotationUtils.getThrowsTypes(n)) { + if (isFirst) { + w.write(" throws "); + isFirst = false; + } else { + w.write(", "); + } + er.printType(_throws, 0); + } + w.write("{"); w.begin(4); @@ -1503,7 +1523,16 @@ List params = printConstructorFormals(n, false); - w.write(Emitter.printThrowsClause(n.constructorDef())); + boolean isFirst = true; + for (Type _throws : AnnotationUtils.getThrowsTypes(n)) { + if (isFirst) { + w.write(" throws "); + isFirst = false; + } else { + w.write(", "); + } + er.printType(_throws, 0); + } Block body = n.body(); if (body != null) { @@ -1578,7 +1607,16 @@ printConstructorFormals(n, false); - w.write(Emitter.printThrowsClause(n.constructorDef())); + isFirst = true; + for (Type _throws : AnnotationUtils.getThrowsTypes(n)) { + if (isFirst) { + w.write(" throws "); + isFirst = false; + } else { + w.write(", "); + } + er.printType(_throws, 0); + } w.write("{"); Index: x10.compiler/src/x10/visit/Lowerer.java =================================================================== --- x10.compiler/src/x10/visit/Lowerer.java (revision 23318) +++ x10.compiler/src/x10/visit/Lowerer.java (working copy) @@ -95,7 +95,6 @@ import x10.ast.X10Unary_c; import x10.constraint.XFailure; import x10.constraint.XVar; -import x10.emitter.Emitter; import x10.extension.X10Ext; import x10.extension.X10Ext_c; import x10.optimizations.ForLoopOptimizer; @@ -117,6 +116,7 @@ import x10.types.constraints.CConstraint; import x10.types.constraints.XConstrainedTerm; import x10.util.AltSynthesizer; +import x10.util.AnnotationUtils; import x10.util.ClosureSynthesizer; import x10.util.Synthesizer; import x10.util.synthesizer.InstanceCallSynth; @@ -526,7 +526,7 @@ List clocks = clocks(a.clocked(), a.clocks()); Position pos = a.position(); X10Ext ext = (X10Ext) a.ext(); - List refs = Emitter.annotationsNamed(ts, a, REF); + List refs = AnnotationUtils.annotationsNamed(a, REF); List> env = a.asyncDef().capturedEnvironment(); if (a.clocked()) { env = new ArrayList>(env); @@ -548,7 +548,7 @@ private Stmt visitAsyncPlace(Async a, Expr place, Stmt body, List> env) throws SemanticException { List clocks = clocks(a.clocked(), a.clocks()); Position pos = a.position(); - List refs = Emitter.annotationsNamed(ts, a, REF); + List refs = AnnotationUtils.annotationsNamed(a, REF); if (a.clocked()) { env = new ArrayList>(env); env.add(clockStack.peek().localInstance()); @@ -570,7 +570,7 @@ } public static boolean isUncountedAsync(TypeSystem ts, Async a) { - return Emitter.hasAnnotation(ts, a, UNCOUNTED); + return AnnotationUtils.hasAnnotation(ts, a, UNCOUNTED); } /** @@ -588,7 +588,7 @@ * TODO: move into a separate pass! */ private Stmt specializeAsync(Async a, Expr p, Stmt body) throws SemanticException { - if (!Emitter.hasAnnotation(ts, a, IMMEDIATE)) + if (!AnnotationUtils.hasAnnotation(ts, a, IMMEDIATE)) return null; if (a.clocks().size() != 0) return null; @@ -839,7 +839,7 @@ * TODO: move into a separate pass! */ private Stmt specializeFinish(Finish f) throws SemanticException { - if (!Emitter.hasAnnotation(ts, f, IMMEDIATE)) + if (!AnnotationUtils.hasAnnotation(ts, f, IMMEDIATE)) return null; Position pos = f.position(); ClassType target = (ClassType) ts.forName(REMOTE_OPERATION); Index: x10.compiler/src/x10/emitter/Emitter.java =================================================================== --- x10.compiler/src/x10/emitter/Emitter.java (revision 23318) +++ x10.compiler/src/x10/emitter/Emitter.java (working copy) @@ -51,7 +51,6 @@ import polyglot.types.Flags; import polyglot.types.MethodDef; import polyglot.types.Name; -import polyglot.types.NoClassException; import polyglot.types.NullType; import polyglot.types.QName; import polyglot.types.Ref; @@ -99,6 +98,7 @@ import x10.types.X10ParsedClassType_c; import x10.types.constants.ConstantValue; import x10.types.constants.StringValue; +import x10.util.AnnotationUtils; import x10.util.CollectionFactory; import x10.util.HierarchyUtils; import x10.visit.ChangePositionVisitor; @@ -1066,27 +1066,7 @@ this.dumpRegex("Native", components, tr, pat); } - // def is X10MethodDef or X10ConstructorDef - // @Throws[java.lang.Throwable] => throws java.lang.Throwable - public static String printThrowsClause(X10Def def) { - Type throwsType = def.typeSystem().Throws(); - List _throwss = def.annotationsNamed(throwsType.fullName()); - StringBuilder sb = new StringBuilder(); - boolean isFirst = true; - for (Type _throws : _throwss) { - if (isFirst) { - sb.append(" throws "); - isFirst = false; - } else { - sb.append(", "); - } - sb.append(_throws.toClass().typeArguments().get(0).fullName().toString()); - } - return sb.toString(); - } - - public void generateMethodDecl(X10MethodDecl_c n, boolean boxPrimitives) { - + public void generateMethodDecl(X10MethodDecl_c n, boolean boxPrimitives) { Flags flags = n.flags().flags(); Context c = tr.context(); @@ -1230,7 +1210,16 @@ } */ - w.write(printThrowsClause(n.methodDef())); + boolean isFirst = true; + for (Type _throws : AnnotationUtils.getThrowsTypes(n)) { + if (isFirst) { + w.write(" throws "); + isFirst = false; + } else { + w.write(", "); + } + printType(_throws, 0); + } w.end(); @@ -2004,8 +1993,6 @@ w.end(); w.write(")"); - w.write(printThrowsClause(def)); - /* Remove throw types support if (!impl.throwTypes().isEmpty()) { w.allowBreak(6); @@ -2020,6 +2007,18 @@ } } */ + + boolean isFirst = true; + for (Type _throws : AnnotationUtils.getThrowsTypes(impl.def())) { + if (isFirst) { + w.write(" throws "); + isFirst = false; + } else { + w.write(", "); + } + printType(_throws, 0); + } + w.write("{"); if (!impl.returnType().isVoid()) { w.write("return "); @@ -2124,9 +2123,7 @@ w.end(); w.write(")"); - w.write(printThrowsClause(def)); - - /** Remove throw types support. + /* Remove throw types support. if (!mi.throwTypes().isEmpty()) { w.allowBreak(6); w.write("throws "); @@ -2140,6 +2137,18 @@ } } */ + + boolean isFirst = true; + for (Type _throws : AnnotationUtils.getThrowsTypes(mi.def())) { + if (isFirst) { + w.write(" throws "); + isFirst = false; + } else { + w.write(", "); + } + printType(_throws, 0); + } + w.write("{"); if (!mi.returnType().isVoid()) { w.write("return "); @@ -2832,46 +2841,6 @@ } } - public static X10ClassType annotationNamed(TypeSystem ts, Node o, QName name) - throws SemanticException { - // Nate's code. This one. - if (o.ext() instanceof X10Ext) { - X10Ext ext = (X10Ext) o.ext(); - Type baseType = ts.systemResolver().findOne(name); - List ats = ext.annotationMatching(baseType); - if (ats.size() > 1) { - throw new SemanticException("Expression has more than one "+ name + " annotation.", o.position()); - } - if (!ats.isEmpty()) { - X10ClassType at = ats.get(0); - return at; - } - } - return null; - } - - public static List annotationsNamed(TypeSystem ts, Node o, QName fullName) { - if (o.ext() instanceof X10Ext) { - X10Ext ext = (X10Ext) o.ext(); - return ext.annotationNamed(fullName); - } - return null; - } - - public static boolean hasAnnotation(TypeSystem ts, Node dec, QName name) { - try { - if (annotationNamed(ts, dec, name) != null) - return true; - } catch (NoClassException e) { - if (!e.getClassName().equals(name.toString())) - throw new InternalCompilerError( - "Something went terribly wrong", e); - } catch (SemanticException e) { - throw new InternalCompilerError("Something is terribly wrong", e); - } - return false; - } - public boolean hasEffects(Receiver e) { if (e instanceof TypeNode) return false; @@ -3955,31 +3924,33 @@ throwsClause = new Join(er, "", "throws ", new Join(er, ", ", l)); }*/ - String throwsClause = printThrowsClause(n.methodDef()); + Expander throwsClause = new Inline(this, ""); + List throwsTypes = AnnotationUtils.getThrowsTypes(n); + if (throwsTypes.size() > 0) { + List l = new ArrayList(throwsTypes.size()); + for (Type _throws : throwsTypes) { + l.add(new TypeExpander(this, _throws, 0)); + } + throwsClause = new Join(this, "", "throws ", new Join(this, ", ", l)); + } - // SYNOPSIS: #2.main(#0) #1 #0=args #1=body #2=mainclass + // SYNOPSIS: #2.main(#0) #1 #0=args #1=body #2=mainclass #3=throws String regex = "public static class " + X10PrettyPrinterVisitor.MAIN_CLASS + " extends x10.runtime.impl.java.Runtime {\n" + "private static final long serialVersionUID = 1L;\n" + - "public static void main(java.lang.String[] args)" + - throwsClause + - " {\n" + + "public static void main(java.lang.String[] args) #throws {\n" + "// start native runtime\n" + "new " + X10PrettyPrinterVisitor.MAIN_CLASS + "().start(args);\n" + "}\n" + "\n" + "// called by native runtime inside main x10 thread\n" + - "public void runtimeCallback(final x10.array.Array args)" + - throwsClause + - " {\n" + + "public void runtimeCallback(final x10.array.Array args) #throws {\n" + "// call the original app-main method\n" + "#mainclass.main(args);\n" + "}\n" + "}\n" + "\n" + "// the original app-main method\n" + - "public static void main(#args)" + - throwsClause + - " #body"; + "public static void main(#args) #throws #body"; Map components = new HashMap(); Object component; int i = 0; @@ -3992,6 +3963,9 @@ component = tr.context().currentClass().name(); // components.put(String.valueOf(i++), component); components.put("mainclass", component); + component = throwsClause; +// components.put(String.valueOf(i++), component); + components.put("throws", component); dumpRegex(X10PrettyPrinterVisitor.MAIN_CLASS, components, tr, regex); return true; Index: x10.compiler/src/x10/util/AnnotationUtils.java =================================================================== --- x10.compiler/src/x10/util/AnnotationUtils.java (revision 23318) +++ x10.compiler/src/x10/util/AnnotationUtils.java (working copy) @@ -15,15 +15,20 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import polyglot.ast.Node; +import polyglot.ast.ProcedureDecl; import polyglot.frontend.Job; +import polyglot.types.NoClassException; +import polyglot.types.ProcedureDef; import polyglot.types.QName; import polyglot.types.SemanticException; import polyglot.types.Type; import polyglot.types.TypeSystem; import polyglot.util.InternalCompilerError; +import x10.ast.AnnotationNode; import x10.extension.X10Ext; import x10.types.X10ClassType; import x10.types.X10Def; @@ -75,6 +80,7 @@ * @param node * @param type * @return + * TODO [IP]: same as annotationsMatching() below. */ public static List getAnnotations(Node node, Type type) { assert node.ext() instanceof X10Ext; @@ -90,6 +96,159 @@ return ((X10Ext) node.ext()).annotationTypes(); } + /** + * @param ts + * @param o + * @param name + * @return + * @throws SemanticException + */ + public static X10ClassType annotationNamed(TypeSystem ts, Node o, QName name) + throws SemanticException { + // Nate's code. This one. + if (o.ext() instanceof X10Ext) { + X10Ext ext = (X10Ext) o.ext(); + Type baseType = ts.systemResolver().findOne(name); + List ats = ext.annotationMatching(baseType); + if (ats.size() > 1) { + throw new SemanticException("Expression has more than one "+ name + " annotation.", o.position()); + } + if (!ats.isEmpty()) { + X10ClassType at = ats.get(0); + return at; + } + } + return null; + } + + /** + * @param o + * @param name + * @return + */ + public static List annotationNodesNamed(Node o, QName name) { + if (o != null && o.ext() instanceof X10Ext) { + X10Ext ext = (X10Ext) o.ext(); + List l = new ArrayList(); + for (AnnotationNode an : ext.annotations()) { + X10ClassType ct = an.annotationInterface(); + if (name.equals(ct.fullName())) { + l.add(an); + } + } + return l; + } + return null; + } + + /** + * @param o + * @param annotationType + * @return + */ + public static List annotationsMatching(Node o, Type annotationType) { + if (o != null && o.ext() instanceof X10Ext) { + X10Ext ext = (X10Ext) o.ext(); + return ext.annotationMatching(annotationType); + } + return null; + } + + /** + * @param o + * @param annotationType + * @return + */ + public static List annotationNodesMatching(Node o, Type annotationType) { + if (o != null && o.ext() instanceof X10Ext) { + X10Ext ext = (X10Ext) o.ext(); + List l = new ArrayList(); + for (AnnotationNode an : ext.annotations()) { + X10ClassType ct = an.annotationInterface(); + if (ct.isSubtype(annotationType, annotationType.typeSystem().emptyContext())) { + l.add(an); + } + } + return l; + } + return null; + } + + /** + * @param ts + * @param dec + * @param name + * @return + */ + public static boolean hasAnnotation(TypeSystem ts, Node dec, QName name) { + try { + if (AnnotationUtils.annotationNamed(ts, dec, name) != null) + return true; + } catch (NoClassException e) { + if (!e.getClassName().equals(name.toString())) + throw new InternalCompilerError( + "Something went terribly wrong", e); + } catch (SemanticException e) { + throw new InternalCompilerError("Something is terribly wrong", e); + } + return false; + } + + /** + * @param o + * @param fullName + * @return + */ + public static List annotationsNamed(Node o, QName fullName) { + if (o != null && o.ext() instanceof X10Ext) { + X10Ext ext = (X10Ext) o.ext(); + return ext.annotationNamed(fullName); + } + return null; + } + + /** + * @param d + * @return + */ + public static List getThrowsTypes(ProcedureDecl d) { + Type throwsType = d.procedureInstance().typeSystem().Throws(); + // Cannot use annotationsMatching, because that requires an exact type match. + List _throwss = annotationsNamed(d.returnType(), throwsType.fullName()); + if (_throwss == null || _throwss.size()==0) { + _throwss = annotationsNamed(d.body(), throwsType.fullName()); + } + if (_throwss == null) { + _throwss = Collections.emptyList(); + } + List result = new ArrayList(_throwss.size()); + for (X10ClassType _throws : _throwss) { + assert (_throws.typeArguments().size() == 1); + result.add(_throws.typeArguments().get(0)); + } + return result; + } + + /** + * @param pd + * @return + */ + public static List getThrowsTypes(ProcedureDef pd) { + Type throwsType = pd.typeSystem().Throws(); + // Cannot use annotationsMatching, because that requires an exact type match. + List _throwss = pd.annotationsNamed(throwsType.fullName()); + if (_throwss == null) { + _throwss = Collections.emptyList(); + } + List result = new ArrayList(_throwss.size()); + for (Type t : _throwss) { + X10ClassType _throws = (X10ClassType) t; + assert (_throws.typeArguments().size() == 1); + result.add(_throws.typeArguments().get(0)); + } + return result; + } + private static final List javaNativeStrings = Arrays.asList("java"); private static final List cudaNativeStrings = Arrays.asList("c++", "cuda"); private static final List cppNativeStrings = Arrays.asList("c++"); Index: x10.compiler/src/polyglot/types/TypeSystem_c.java =================================================================== --- x10.compiler/src/polyglot/types/TypeSystem_c.java (revision 23318) +++ x10.compiler/src/polyglot/types/TypeSystem_c.java (working copy) @@ -799,8 +799,7 @@ **/ public boolean isThrowable(Type type) { assert_(type); - return emptyContextSubtype(type,Throwable()) - || emptyContextSubtype(type, JavaThrowable()); + return emptyContextSubtype(type,Throwable()); } @@ -809,7 +808,7 @@ * uncheckedExceptions(). */ public boolean isUncheckedException(Type type) { - return isThrowable(type); + return isThrowable(type) || isJavaUncheckedException(type); } /** * Returns a list of the Throwable types that need not be declared @@ -818,6 +817,8 @@ public Collection uncheckedExceptions() { List l = new ArrayList(1); l.add(Throwable()); + l.add(JavaRuntimeException()); + l.add(JavaError()); return l; } @@ -2103,34 +2104,23 @@ return forName(name); } - protected Type OBJECT_; + protected X10ClassType OBJECT_; protected Type CLASS_; - protected Type STRING_; - protected Type THROWABLE_; - protected Type JLTHROWABLE_; + protected X10ClassType STRING_; + protected X10ClassType THROWABLE_; + protected X10ClassType JLTHROWABLE_; - public Type JavaObject() { - if (OBJECT_ != null) - return OBJECT_; - return OBJECT_ = load("java.lang.Object"); - } public Type JavaClass() { if (CLASS_ != null) return CLASS_; return CLASS_ = load("java.lang.Class"); } - public Type JavaString() { - if (STRING_ != null) return STRING_; - return STRING_ = load("java.lang.String"); - } public X10ClassType JavaThrowable() { - if (JLTHROWABLE_ != null) return (X10ClassType) JLTHROWABLE_; - X10ClassType t = load("java.lang.Throwable"); - JLTHROWABLE_ = t; - return t; + if (JLTHROWABLE_ != null) return JLTHROWABLE_; + return JLTHROWABLE_ = load("java.lang.Throwable"); } - public Type JavaError() { return load("java.lang.Error"); } - public Type JavaException() { return load("java.lang.Exception"); } - public Type javaRuntimeException() { return load("java.lang.RuntimeException"); } + public X10ClassType JavaError() { return load("java.lang.Error"); } + public X10ClassType JavaException() { return load("java.lang.Exception"); } + public X10ClassType JavaRuntimeException() { return load("java.lang.RuntimeException"); } public Type Cloneable() { return load("java.lang.Cloneable"); } public Type Serializable() { return load("java.io.Serializable"); } public Type JavaNullPointerException() { return load("java.lang.NullPointerException"); } @@ -2949,7 +2939,18 @@ "x10.lang.Float".equals(arrayType) || "x10.lang.Long".equals(arrayType); } + + public boolean isJavaThrowable(Type type) { + assert_(type); + return emptyContextSubtype(type,JavaThrowable()); + } + public boolean isJavaUncheckedException(Type type) { + assert_(type); + return emptyContextSubtype(type,JavaRuntimeException()) || + emptyContextSubtype(type, JavaError()); + } + public Type arrayOf(Ref type, int dims) { return arrayOf(null, type, dims); } Index: x10.compiler/src/polyglot/types/TypeSystem.java =================================================================== --- x10.compiler/src/polyglot/types/TypeSystem.java (revision 23318) +++ x10.compiler/src/polyglot/types/TypeSystem.java (working copy) @@ -1274,4 +1274,6 @@ X10ClassType JavaArray(); boolean isJavaArray(Type me); boolean isPrimitiveJavaArray(Type type); + X10ClassType JavaThrowable(); + boolean isJavaThrowable(Type me); } Index: x10.compiler/src/polyglot/ast/Catch_c.java =================================================================== --- x10.compiler/src/polyglot/ast/Catch_c.java (revision 23318) +++ x10.compiler/src/polyglot/ast/Catch_c.java (working copy) @@ -88,7 +88,7 @@ public Node typeCheck(ContextVisitor tc) { TypeSystem ts = tc.typeSystem(); - if (! catchType().isThrowable()) { + if (! catchType().isThrowable() && !ts.isJavaThrowable(catchType())) { Errors.issue(tc.job(), new SemanticException("Can only throw subclasses of \"" +ts.Throwable() + "\".", formal.position()), this); Index: x10.compiler/src/polyglot/ast/ProcedureDecl.java =================================================================== --- x10.compiler/src/polyglot/ast/ProcedureDecl.java (revision 23318) +++ x10.compiler/src/polyglot/ast/ProcedureDecl.java (working copy) @@ -23,7 +23,8 @@ /** The procedure's flags. */ FlagsNode flags(); - /** The procedure's formal parameters. + /** + * The procedure's formal parameters. * @return A list of {@link polyglot.ast.Formal Formal}. */ List formals(); @@ -33,4 +34,7 @@ * after signature disambiguation. */ ProcedureDef procedureInstance(); + + /** The procedure's return type. */ + TypeNode returnType(); } Index: x10.runtime/src-x10/x10/interop/java/Throws.x10 =================================================================== --- x10.runtime/src-x10/x10/interop/java/Throws.x10 (revision 23318) +++ x10.runtime/src-x10/x10/interop/java/Throws.x10 (working copy) @@ -11,9 +11,15 @@ package x10.interop.java; -import x10.lang.annotations.MethodAnnotation; +import x10.lang.annotations.StatementAnnotation; +import x10.lang.annotations.TypeAnnotation; /** * This annotation is used to declare a method or a constructor which throws java checked exception. + * T is the class of the checked exception. For readability, the annotation is actually on the body + * or the return type of the method/constructor. + * Usage: + * def m(a:Int) @Throws[java.io.IOException] { ... } + * def r(b:Double):Boolean @Throws[java.io.IOException] { ... } */ -public interface Throws[T]{T <: java.lang.Throwable} extends MethodAnnotation { } +public interface Throws[T]{T<:java.lang.Throwable} extends StatementAnnotation, TypeAnnotation { }