@@ -167,6 +167,77 @@ private Iterable<Type> checkTypeNameList(Iterable<? extends TypeName> l) {
167167 return new TypeNameChecker (context , opt ).checkList (l );
168168 }
169169
170+ /**
171+ * Handle a valid constructor call: one that appears as the first line of a constructor.
172+ * ConstructorCalls handled via {@link #check(Expression)} will always be treated as errors.
173+ */
174+ public void checkConstructorCall (ConstructorCall node ) {
175+ if (node .getExpression () != null ) {
176+ throw new ExecutionError ("not.implemented" , node );
177+ }
178+
179+ Iterable <? extends Expression > args = node .getArguments ();
180+ checkList (args );
181+
182+ // TODO: implement explicit type arguments in constructor calls
183+ Iterable <Type > targs = IterUtil .empty ();
184+
185+ Type type ;
186+ if (node .isSuper ()) { type = context .getSuperType (ts ); }
187+ else { type = SymbolUtil .thisType (context .getThis ()); }
188+ if (type == null ) {
189+ throw new IllegalArgumentException ("Can't check a ConstructorCall in this context" );
190+ }
191+
192+ try {
193+ ConstructorInvocation inv = ts .lookupConstructor (type , targs , args , Option .<Type >none ());
194+
195+ // TODO: Check accessibility of constructor
196+ // Note that super constructor calls *have to* be accessible, even if accessibility
197+ // checking is turned off -- a call to a private constructor cannot be compiled
198+ // in a way that it will run successfully (since constructor calls are the only code
199+ // that is directly compiled rather than being interpreted, we don't have this problem
200+ // elsewhere)
201+ checkThrownExceptions (inv .thrown (), node );
202+ node .setArguments (CollectUtil .makeList (inv .args ()));
203+ setConstructor (node , inv .constructor ());
204+ setType (node , type );
205+ }
206+ catch (InvalidTypeArgumentException e ) {
207+ throw new ExecutionError ("type.argument" , node );
208+ }
209+ catch (TypeSystemException e ) {
210+ setErrorStrings (node , ts .userRepresentation (type ), nodeTypesString (args ));
211+ throw new ExecutionError ("no.such.constructor" , node );
212+ }
213+ }
214+
215+ /** Verify that the thrown exceptions are expected in this context. */
216+ private void checkThrownExceptions (Iterable <? extends Type > thrownTypes , Node node ) {
217+ Iterable <Type > allowed = IterUtil .compose (TypeSystem .RUNTIME_EXCEPTION ,
218+ context .getDeclaredThrownTypes ());
219+ for (Type thrown : thrownTypes ) {
220+ if (ts .isAssignable (TypeSystem .EXCEPTION , thrown )) {
221+ boolean valid = false ;
222+ for (Type t : allowed ) {
223+ if (ts .isAssignable (t , thrown )) { valid = true ; break ; }
224+ }
225+ if (!valid ) {
226+ setErrorStrings (node , ts .userRepresentation (thrown ));
227+ throw new ExecutionError ("uncaught.exception" , node );
228+ }
229+ }
230+ }
231+ }
232+
233+ private String nodeTypesString (Iterable <? extends Node > nodes ) {
234+ Lambda <Node , String > typeString = new Lambda <Node , String >() {
235+ public String value (Node n ) { return ts .userRepresentation (getType (n )); }
236+ };
237+ return IterUtil .toString (IterUtil .map (nodes , typeString ), "" , ", " , "" );
238+ }
239+
240+
170241
171242 private class ExpressionVisitor extends AbstractVisitor <Type > implements Lambda <Expression , Type > {
172243
@@ -177,13 +248,6 @@ private class ExpressionVisitor extends AbstractVisitor<Type> implements Lambda<
177248
178249 public Type value (Expression e ) { return e .acceptVisitor (this ); }
179250
180- private String nodeTypesString (Iterable <? extends Node > nodes ) {
181- Lambda <Node , String > typeString = new Lambda <Node , String >() {
182- public String value (Node n ) { return ts .userRepresentation (getType (n )); }
183- };
184- return IterUtil .toString (IterUtil .map (nodes , typeString ), "" , ", " , "" );
185- }
186-
187251
188252 @ Override public Type visit (AmbiguousName node ) {
189253 Node resolved = resolveAmbiguousName (node );
@@ -387,20 +451,6 @@ else if (ts.containsClass(classType, memberName.image())) {
387451 */
388452 @ Override public Type visit (ObjectFieldAccess node ) {
389453 Expression receiver = node .getExpression ();
390- if (receiver instanceof AmbiguousName ) {
391- Node resolved = resolveAmbiguousName ((AmbiguousName ) receiver );
392- if (resolved instanceof ReferenceTypeName ) {
393- // this is actually a StaticFieldAccess
394- Expression translation =
395- new StaticFieldAccess ((ReferenceTypeName ) resolved , node .getFieldName (), node .getSourceInfo ());
396- translation .acceptVisitor (this );
397- setTranslation (node , translation );
398- setVariableType (node , getVariableType (translation ));
399- return setType (node , getType (translation ));
400- }
401- else { receiver = (Expression ) resolved ; }
402- }
403-
404454 Type receiverT = check (receiver );
405455 try {
406456 ObjectFieldReference ref = ts .lookupField (receiver , node .getFieldName ());
@@ -471,8 +521,8 @@ else if (ts.containsClass(classType, memberName.image())) {
471521 * @return The type of the expression
472522 */
473523 @ Override public Type visit (SimpleMethodCall node ) {
474- Iterable <? extends Expression > args = IterUtil . empty ();
475- if ( node . getArguments () != null ) { args = node . getArguments (); checkList (args ); }
524+ Iterable <? extends Expression > args = node . getArguments ();
525+ checkList (args );
476526
477527 Iterable <Type > targs = IterUtil .empty ();
478528
@@ -554,8 +604,8 @@ else if (ts.containsClass(classType, memberName.image())) {
554604
555605 Type receiverT = check (receiver );
556606
557- Iterable <? extends Expression > args = IterUtil . empty ();
558- if ( node . getArguments () != null ) { args = node . getArguments (); checkList (args ); }
607+ Iterable <? extends Expression > args = node . getArguments ();
608+ checkList (args );
559609
560610 Iterable <Type > targs = IterUtil .empty ();
561611 if (node instanceof PolymorphicObjectMethodCall ) {
@@ -594,8 +644,8 @@ else if (ts.containsClass(classType, memberName.image())) {
594644 throw new ExecutionError ("super.undefined" , node );
595645 }
596646
597- Iterable <? extends Expression > args = IterUtil . empty ();
598- if ( node . getArguments () != null ) { args = node . getArguments (); checkList (args ); }
647+ Iterable <? extends Expression > args = node . getArguments ();
648+ checkList (args );
599649
600650 Iterable <Type > targs = IterUtil .empty ();
601651 if (node instanceof PolymorphicSuperMethodCall ) {
@@ -632,8 +682,8 @@ else if (ts.containsClass(classType, memberName.image())) {
632682 @ Override public Type visit (StaticMethodCall node ) {
633683 Type t = checkTypeName (node .getMethodType ());
634684
635- Iterable <? extends Expression > args = IterUtil . empty ();
636- if ( node . getArguments () != null ) { args = node . getArguments (); checkList (args ); }
685+ Iterable <? extends Expression > args = node . getArguments ();
686+ checkList (args );
637687
638688 Iterable <Type > targs = IterUtil .empty ();
639689 if (node instanceof PolymorphicStaticMethodCall ) {
@@ -747,8 +797,8 @@ private void addRuntimeCheck(Node node, Type expectedType, Type declaredActualTy
747797 throw new ExecutionError ("allocation.type" , node );
748798 }
749799
750- Iterable <? extends Expression > args = IterUtil . empty ();
751- if ( node . getArguments () != null ) { args = node . getArguments (); checkList (args ); }
800+ Iterable <? extends Expression > args = node . getArguments ();
801+ checkList (args );
752802
753803 Iterable <Type > targs = IterUtil .empty ();
754804 if (node instanceof PolymorphicSimpleAllocation ) {
@@ -783,8 +833,8 @@ private void addRuntimeCheck(Node node, Type expectedType, Type declaredActualTy
783833 throw new ExecutionError ("allocation.type" , node );
784834 }
785835
786- Iterable <? extends Expression > args = IterUtil . empty ();
787- if ( node . getArguments () != null ) { args = node . getArguments (); checkList (args ); }
836+ Iterable <? extends Expression > args = node . getArguments ();
837+ checkList (args );
788838
789839 Iterable <Type > targs = IterUtil .empty ();
790840 if (node instanceof PolymorphicAnonymousAllocation ) {
@@ -838,8 +888,8 @@ private void addRuntimeCheck(Node node, Type expectedType, Type declaredActualTy
838888 throw new ExecutionError ("allocation.type" , node );
839889 }
840890
841- Iterable <? extends Expression > args = IterUtil . empty ();
842- if ( node . getArguments () != null ) { args = node . getArguments (); checkList (args ); }
891+ Iterable <? extends Expression > args = node . getArguments ();
892+ checkList (args );
843893
844894 Iterable <Type > targs = IterUtil .empty ();
845895 if (node instanceof PolymorphicInnerAllocation ) {
@@ -891,8 +941,8 @@ private void addRuntimeCheck(Node node, Type expectedType, Type declaredActualTy
891941 }
892942 setSuperType (node , t );
893943
894- Iterable <? extends Expression > args = IterUtil . empty ();
895- if ( node . getArguments () != null ) { args = node . getArguments (); checkList (args ); }
944+ Iterable <? extends Expression > args = node . getArguments ();
945+ checkList (args );
896946
897947 Iterable <Type > targs = IterUtil .empty ();
898948 if (node instanceof PolymorphicAnonymousInnerAllocation ) {
@@ -932,71 +982,11 @@ private void addRuntimeCheck(Node node, Type expectedType, Type declaredActualTy
932982 return setType (node , ts .makeClassType (c ));
933983 }
934984
935- /**
936- * Visits a ConstructorCall.
937- * @return The type of this or super.
938- */
939985 @ Override public Type visit (ConstructorCall node ) {
940- if (node .getExpression () != null ) {
941- throw new ExecutionError ("not.implemented" , node );
942- }
943-
944- Iterable <? extends Expression > args = IterUtil .empty ();
945- if (node .getArguments () != null ) { args = node .getArguments (); checkList (args ); }
946-
947- // TODO: implement explict type arguments in constructor calls
948- Iterable <Type > targs = IterUtil .empty ();
949-
950- Type result ;
951- if (node .isSuper ()) { result = context .getSuperType (ts ); }
952- else { result = SymbolUtil .thisType (context .getThis ()); }
953- if (result == null ) {
954- throw new IllegalArgumentException ("Can't check a ConstructorCall in this context" );
955- }
956-
957- try {
958- ConstructorInvocation inv = ts .lookupConstructor (result , targs , args , expected );
959-
960- // TODO: Check accessibility of constructor
961- // Note that super constructor calls *have to* be accessible, even if accessibility
962- // checking is turned off -- a call to a private constructor cannot be compiled
963- // in a way that it will run successfully (since constructor calls are the only code
964- // that is directly compiled rather than being interpreted, we don't have this problem
965- // elsewhere)
966- checkThrownExceptions (inv .thrown (), node );
967- node .setArguments (CollectUtil .makeList (inv .args ()));
968- setConstructor (node , inv .constructor ());
969- return setType (node , result );
970- }
971- catch (InvalidTypeArgumentException e ) {
972- throw new ExecutionError ("type.argument" , node );
973- }
974- catch (TypeSystemException e ) {
975- setErrorStrings (node , ts .userRepresentation (result ), nodeTypesString (args ));
976- throw new ExecutionError ("no.such.constructor" , node );
977- }
978- }
979-
980- /** Verify that the thrown exceptions are expected in this context. */
981- private void checkThrownExceptions (Iterable <? extends Type > thrownTypes , Node node ) {
982- Iterable <Type > allowed = IterUtil .compose (TypeSystem .RUNTIME_EXCEPTION ,
983- context .getDeclaredThrownTypes ());
984- for (Type thrown : thrownTypes ) {
985- if (ts .isAssignable (TypeSystem .EXCEPTION , thrown )) {
986- boolean valid = false ;
987- for (Type t : allowed ) {
988- if (ts .isAssignable (t , thrown )) { valid = true ; break ; }
989- }
990- if (!valid ) {
991- setErrorStrings (node , ts .userRepresentation (thrown ));
992- throw new ExecutionError ("uncaught.exception" , node );
993- }
994- }
995- }
986+ throw new ExecutionError ("constructor.call" , node );
996987 }
997988
998-
999-
989+
1000990 /**
1001991 * Visits an ArrayAccess. JLS 15.13.
1002992 * @return The type of the expression
0 commit comments