/* * This file is part of the X10 project (http://x10-lang.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.opensource.org/licenses/eclipse-1.0.php * * (C) Copyright IBM Corporation 2006-2010. */ package x10.ast; import polyglot.ast.Assign; import polyglot.ast.Assign_c; import polyglot.ast.Expr; import polyglot.ast.Field; import polyglot.ast.FieldAssign_c; import polyglot.ast.Id; import polyglot.ast.Node; import polyglot.ast.NodeFactory; import polyglot.ast.Receiver; import polyglot.ast.Special; import polyglot.ast.ConstructorDecl; import polyglot.ast.Assign.Operator; import polyglot.types.FieldInstance; import polyglot.types.SemanticException; import polyglot.types.Type; import polyglot.types.TypeSystem; import polyglot.util.InternalCompilerError; import polyglot.util.Position; import polyglot.visit.ContextVisitor; import x10.types.X10ClassType; import polyglot.types.Context; import polyglot.types.Flags; import polyglot.types.ConstructorDef; import x10.types.X10FieldInstance; import x10.types.checker.Checker; import x10.types.checker.PlaceChecker; import x10.visit.X10TypeChecker; import x10.errors.Errors; public class X10FieldAssign_c extends FieldAssign_c { public X10FieldAssign_c(NodeFactory nf, Position pos, Receiver target, Id name, Operator op, Expr right) { super(nf, pos, target, name, op, right); } @Override public Assign typeCheckLeft(ContextVisitor tc) { Context cxt = (Context) tc.context(); if (cxt.inDepType()) { SemanticException e = new Errors.NoAssignmentInDepType(this, this.position()); Errors.issue(tc.job(), e, this); } else { tc = tc.context(((Context) tc.context()).pushAssignment()); } Assign res = super.typeCheckLeft(tc); return res; } /** Type check the expression. */ public Node typeCheck(ContextVisitor tc) { TypeSystem ts = tc.typeSystem(); X10FieldAssign_c n = (X10FieldAssign_c) typeCheckLeft(tc); Type t = n.leftType(); // Check that the field being assigned to is not a property. // Such fields can only be set in a property() statement. X10FieldInstance fd = (X10FieldInstance) n.fieldInstance(); if (fd.isProperty()) { SemanticException e = new Errors.CannotAssignToProperty(fd, n.position()); Errors.issue(tc.job(), e, n); } // check that a static field is never assigned final Flags flags = fd.flags(); if (flags.isStatic()) { Errors.issue(tc.job(), new Errors.CannotAssignToStaticField(fd, n.position)); } // final instance fields can only be assigned via this in a ctor if (!flags.isStatic() && flags.isFinal()) { boolean isThis = target() instanceof Special && ((Special)target()).kind()==Special.THIS; if (!isThis || tc.context().getCtorIgnoringAsync()==null) Errors.issue(tc.job(), new Errors.CannotAssignValueToFinalField(fd,n.position)); } if (t == null) t = ts.unknownType(n.position()); X10Field_c target = (X10Field_c) n.left(); // Not needed in the orthogonal locality proposal. //try { // target = PlaceChecker.makeFieldAccessLocalIfNecessary(target, tc); //} catch (SemanticException e) { // Errors.issue(tc.job(), e, this); //} n = (X10FieldAssign_c) n.reconstruct(target.target(), n.name()); t = n.leftType(); n = (X10FieldAssign_c) n.type(t); return Checker.typeCheckAssign(n, tc); } }