Java Code Examples for org.mozilla.javascript.ast.PropertyGet#getTarget()

The following examples show how to use org.mozilla.javascript.ast.PropertyGet#getTarget() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: ConstraintGenUtil.java    From SJS with Apache License 2.0 6 votes vote down vote up
@Override
public boolean visit(AstNode node) {
	if (node instanceof PropertyGet){
		PropertyGet pg = (PropertyGet)node;
		AstNode target = pg.getTarget();
		String propName = pg.getProperty().getIdentifier();
		if (target instanceof KeywordLiteral && ConstraintGenUtil.isThis(target)){
			if (node.getParent() instanceof Assignment){
				Assignment a = (Assignment)node.getParent();
				if (a.getLeft() == node){
					writtenProperties.add(propName);
				} else {
					readProperties.add(propName);
				}
			} else {
				readProperties.add(propName);
			}
			readProperties.removeAll(writtenProperties); // if something is read and written, it should only be in the written set
		}
	} else if (node instanceof FunctionNode) {
	    // don't recurse into nested function body
	    return false;
	}
	return true;
}
 
Example 2
Source File: ConstraintVisitor.java    From SJS with Apache License 2.0 5 votes vote down vote up
/**
 * assignment to an object property
 */
private void processAssignToProperty(Assignment a, AstNode left, AstNode right, ITypeTerm expTerm) throws Error {

	PropertyGet pg = (PropertyGet)left;
	AstNode base = pg.getTarget();
	Name prop = pg.getProperty();
	ITypeTerm pgTerm = findOrCreateExpressionTerm(pg);

	ITypeTerm baseTerm;
	if (base instanceof KeywordLiteral && ConstraintGenUtil.isThis(base)){
		baseTerm = findOrCreateThisTerm(base);
	} else {
		baseTerm = generateReceiverConstraints(pg);
	}

	int assignLineNo = a.getLineno();
	// detect assignments of the form C.prototype.foo = ...
	if (base instanceof PropertyGet) {
		PropertyGet basePG = (PropertyGet) base;
		String baseProp = basePG.getProperty().getIdentifier();
		if (baseProp.equals("prototype")) {
			checkForValidProtoPropAssign(a, pg, assignLineNo, basePG);
		}
	}
	ITypeTerm leftTerm = findOrCreatePropertyAccessTerm(baseTerm, prop.getIdentifier(), null);
	ITypeTerm rightTerm = processExpression(right);
	addTypeEqualityConstraint(pgTerm, leftTerm, assignLineNo, (solution) ->
			typeEqualityError("incompatible types",
					solution.typeOfTerm(leftTerm), solution.typeOfTerm(pgTerm), locationOf(pg)));
	addTypeEqualityConstraint(expTerm, leftTerm, assignLineNo, (solution) ->
			typeEqualityError("incompatible types",
					solution.typeOfTerm(leftTerm), solution.typeOfTerm(expTerm), locationOf(a)));
	processCopy(right, rightTerm, leftTerm, assignLineNo,
			(solution) -> badPropertyWrite(pg, solution.typeOfTerm(baseTerm), hasType(leftTerm, solution) ? solution.typeOfTerm(leftTerm) : null, solution.typeOfTerm(rightTerm)));
}
 
Example 3
Source File: ConstraintVisitor.java    From SJS with Apache License 2.0 5 votes vote down vote up
/**
 * Generate constraints for the (possibly nested) receiver of a property-get expression.
 */
private ITypeTerm generateReceiverConstraints(PropertyGet pg) throws Error {
	AstNode base = pg.getTarget();
	ITypeTerm baseTerm = findOrCreateExpressionTerm(base); // make term for expression
	if (base instanceof Name) {
		Name name = (Name)base;
		ITypeTerm nameTerm = findOrCreateNameDeclarationTerm(name); // find unique representative for referenced Name
		addTypeEqualityConstraint(baseTerm, nameTerm, base.getLineno(), null);
	} else if (base instanceof PropertyGet) {
		PropertyGet basePG = (PropertyGet)base;
		ITypeTerm bbaseTerm = generateReceiverConstraints(basePG);
		String baseProperty = basePG.getProperty().getIdentifier();
		ITypeTerm basePATerm;
		if (basePG.getProperty().getIdentifier().equals("prototype")){
			basePATerm = findOrCreateProtoTerm(bbaseTerm, pg.getLineno());
		} else {
			basePATerm = findOrCreatePropertyAccessTerm(bbaseTerm, baseProperty, basePG);
		}
		addTypeEqualityConstraint(baseTerm, basePATerm, basePG.getLineno(), null);
	} else if (base instanceof KeywordLiteral && ConstraintGenUtil.isThis(base)){
		processExpression(base);
		//error("unsupported property get with base this: "+pg.toSource());
	} else if (base instanceof ElementGet) {
	    ElementGet baseEGet = (ElementGet) base;
	    processElementGet(baseEGet);
	} else {
		System.err.println("base = " + base.toSource() + ", type = " + base.getClass().getName() );
		error("unsupported property get: " + pg.toSource(), pg);
	}
	return baseTerm;
}
 
Example 4
Source File: ConstraintGenUtil.java    From SJS with Apache License 2.0 4 votes vote down vote up
/**
 * For a {@link FunctionNode} representing a constructor, if the constructor C is
 * followed by a sequence of assignments of the form C.prototype.a = ...;, return
 * a set of all the properties written on the prototype.  If the assignments do not
 * fit that form, return the empty set.
 * @param consNode
 * @return
 */
public static Set<String> getWrittenPrototypeProps(FunctionNode consNode) {
    Set<String> result = HashSetFactory.make();
    AstNode parent = consNode.getParent();
    boolean found = false;
    for (Node child: parent) {
        if (child instanceof EmptyStatement) {
            continue;
        }
        if (child.equals(consNode)) {
            found = true;
        } else if (found) {
            // looking for a statement of the form C.prototype.a = ...;
            boolean foundAssign = false;
            if (child instanceof ExpressionStatement) {
                AstNode expression = ((ExpressionStatement)child).getExpression();
                if (expression instanceof Assignment) {
                    Assignment assign = (Assignment) expression;
                    AstNode lhs = assign.getLeft();
                    if (lhs instanceof PropertyGet) {
                        PropertyGet pg = (PropertyGet) lhs;
                        AstNode pgTarget = pg.getTarget();
                        if (pgTarget instanceof PropertyGet) {
                            PropertyGet basePG = (PropertyGet) pgTarget;
                            if (basePG.getProperty().getIdentifier().equals("prototype")) {
                                // BINGO
                                result.add(pg.getProperty().getIdentifier());
                                foundAssign = true;
                            }
                        }
                    }
                }
            }
            if (!foundAssign) {
                // stop looking for more assignments
                break;
            }
        }
    }
    return result;
}
 
Example 5
Source File: ConstraintVisitor.java    From SJS with Apache License 2.0 4 votes vote down vote up
/**
 * assignment to the "prototype" property
 */
private void processAssignToPrototype(Assignment a, AstNode left, AstNode right, ITypeTerm expTerm) throws Error {
	PropertyGet pg = (PropertyGet)left;
	AstNode base = pg.getTarget();
	ITypeTerm pgTerm = findOrCreateExpressionTerm(pg);
	if (base instanceof Name){
		Name name = (Name)base;
		if (!validRHSForAssignToPrototype(right)) {
			error(
					"expression "
							+ right.toSource()
							+ " cannot be assigned to a constructor prototype (line "
							+ right.getLineno() + ")", a);
		}
		// can only write to prototype immediately after declaration of
		// constructor of the same name
		AstNode parent = a.getParent();
		if (!(parent instanceof ExpressionStatement)) {
			error(
					"assignment to prototype property not allowed here (line "
							+ a.getLineno() + ")", a);
			return;
		}
		Node prev = getPredecessorNode(parent);
		if (!(prev instanceof FunctionNode)) {
			error(
					"assignment to prototype property only allowed after constructor declaration (line "
							+ a.getLineno() + ")", a);
			return;
		}
		FunctionNode fn = (FunctionNode) prev;
		String functionName = fn.getName();
		String identifier = name.getIdentifier();
		if (!functionName.equals(identifier)) {
			error(
					"can only assign to prototype of function "
							+ functionName + " here (line " + a.getLineno()
							+ ")", a);
			return;
		}
		ITypeTerm baseTerm = findOrCreateExpressionTerm(base); // make term for expression
		ITypeTerm nameTerm = findOrCreateNameDeclarationTerm(name); // find unique representative for referenced Name
		addTypeEqualityConstraint(baseTerm, nameTerm, a.getLineno(), null); // equate them
		ITypeTerm protoTerm = findOrCreateProtoTerm(baseTerm, pg.getLineno());
		ITypeTerm rightTerm = processExpression(right);
		addTypeEqualityConstraint(pgTerm, protoTerm, a.getLineno(), null);
		addTypeEqualityConstraint(rightTerm, protoTerm, a.getLineno(), null);
		addTypeEqualityConstraint(expTerm, protoTerm, a.getLineno(), null);
	} else {
		error("processAssignToPrototype: unsupported case for receiver expression: " + base.getClass().getName(), base);
	}
}
 
Example 6
Source File: ConstraintVisitor.java    From SJS with Apache License 2.0 4 votes vote down vote up
private void checkForValidProtoPropAssign(Assignment a, PropertyGet pg,
		int assignLineNo, PropertyGet basePG) {
	AstNode baseTarget = basePG.getTarget();
	if (!(baseTarget instanceof Name)) {
		error("assignment to property of prototype not valid (line " + assignLineNo + ")", a);
		return;
	}
	Name baseName = (Name) baseTarget;
	AstNode parent = a.getParent();
	if (!(parent instanceof ExpressionStatement)) {
		error("assignment to property of prototype not valid (line " + assignLineNo + ")", a);
		return;
	}
	Node prev = getPredecessorNode(parent);
	if (prev instanceof FunctionNode) {
		FunctionNode fn = (FunctionNode) prev;
		String functionName = fn.getName();
		String identifier = baseName.getIdentifier();
		if (!functionName.equals(identifier)) {
			error("can only assign to prototype of function " + functionName + " here (line " + assignLineNo + ")", a);
			return;
		}

	} else if (prev instanceof ExpressionStatement) {
		// it needs to be an assignment either to C.prototype or C.prototype.foo
		// TODO clean up this gross code
		AstNode expression = ((ExpressionStatement)prev).getExpression();
		if (!(expression instanceof Assignment)) {
			error("assignment to property of prototype not valid (line " + assignLineNo + ")", a);
			return;
		}
		Assignment prevAssign = (Assignment) expression;
		AstNode prevLeft = prevAssign.getLeft();
		if (!(prevLeft instanceof PropertyGet)) {
			error("assignment to property of prototype not valid (line " + assignLineNo + ")", a);
			return;
		}
		PropertyGet prevPG = (PropertyGet) prevLeft;
		AstNode prevPGTarget = prevPG.getTarget();
		if (prevPG.getProperty().getIdentifier().equals("prototype")) {
			checkForSameName(assignLineNo, baseName, prevPGTarget);
		} else if (prevPGTarget instanceof PropertyGet) {
			PropertyGet prevPGBasePG = (PropertyGet) prevPGTarget;
			if (!prevPGBasePG.getProperty().getIdentifier().equals("prototype")) {
				error("assignment to property of prototype not valid (line " + assignLineNo + ")", a);
				return;
			}
			checkForSameName(assignLineNo, baseName, prevPGBasePG.getTarget());
		} else {
			error("assignment to property of prototype not valid (line " + assignLineNo + ")", a);
			return;
		}
	} else {
		error("assignment to property of prototype not valid (line " + assignLineNo + ")", a);
		return;
	}
}