org.mozilla.javascript.ast.PropertyGet Java Examples

The following examples show how to use org.mozilla.javascript.ast.PropertyGet. 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: TypeErrorMessage.java    From SJS with Apache License 2.0 6 votes vote down vote up
public static TypeErrorMessage badPropertyWrite(PropertyGet node, Type baseType, Type fieldType, Type expType) {
    SourceLocation location = locationOf(node);
    String fieldName = node.getProperty().getIdentifier();
    if (fieldType != null) {
        if (baseType instanceof PrimitiveType) {
            return genericTypeError("cannot assign to property '" + fieldName + "' on primitive type " + describeType(baseType),
                    location);
        }
        if (expType instanceof CodeType && fieldType instanceof DefaultType) {
            return genericTypeError("cannot attach method to field '" + fieldName + "'", location)
                    .withNote("methods may only be attached to object literals, 'this', and constructor prototypes");
        }
        assert !Types.isSubtype(fieldType, expType) || isReadOnly(baseType, fieldName) :
                "I don't know how to explain this failure";
        if (!Types.isSubtype(fieldType, expType)) {
            return subtypeError("bad assignment to property '" + fieldName + "'",
                    expType, fieldType, location);
        } else {
            return genericTypeError("cannot assign to read-only field '" + fieldName + "'",
                    location);
        }
    } else {
        return genericTypeError(shortSrc(node) + " has no property '" + fieldName + "'", location)
                .withNote("type is " + describeType(baseType));
    }
}
 
Example #2
Source File: ConstraintVisitor.java    From SJS with Apache License 2.0 6 votes vote down vote up
/**
 * generate constraints for assignments
 */
private void processAssignment(Assignment a) throws Error {
	AstNode left = a.getLeft();
	AstNode right = a.getRight();
	ITypeTerm expTerm = findOrCreateExpressionTerm(a);
	if (left instanceof Name){
		processAssignToVariable(a, left, right, expTerm);
	} else if (left instanceof PropertyGet) {
		PropertyGet pg = (PropertyGet)left;
		if (pg.getProperty().getIdentifier().equals("prototype")){
			processAssignToPrototype(a, left, right, expTerm);
		} else {
			processAssignToProperty(a, left, right, expTerm);
		}
		processExpression(pg.getTarget()); // TEST
	} else if (left instanceof ElementGet){
		processIndexedAssignment(a, left, right, expTerm);
	} else {
		error("unsupported LHS type in Assignment: " + left.getClass().getName(), left);
	}
}
 
Example #3
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 #4
Source File: ClassDefScanner.java    From nexus-public with Eclipse Public License 1.0 5 votes vote down vote up
/**
 * Find the textual name of the given node.
 */
@Nullable
private String nameOf(final AstNode node) {
  if (node instanceof Name) {
    return ((Name) node).getIdentifier();
  }
  else if (node instanceof PropertyGet) {
    PropertyGet prop = (PropertyGet) node;
    return String.format("%s.%s", nameOf(prop.getTarget()), nameOf(prop.getProperty()));
  }
  else if (node instanceof StringLiteral) {
    return ((StringLiteral) node).getValue();
  }
  return null;
}
 
Example #5
Source File: IRFactory.java    From JsDroidCmd with Mozilla Public License 2.0 5 votes vote down vote up
private Node transformPropertyGet(PropertyGet node) {
    Node target = transform(node.getTarget());
    String name = node.getProperty().getIdentifier();
    decompiler.addToken(Token.DOT);
    decompiler.addName(name);
    return createPropertyGet(target, null, name, 0);
}
 
Example #6
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 #7
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 #8
Source File: ConstraintVisitor.java    From SJS with Apache License 2.0 5 votes vote down vote up
/**
 * is right a valid expression to assign into the prototype field of a
 * constructor?  currently we allow object literals, constructor calls, and
 * expressions of the form B.prototype
 *
 * @param right
 * @return
 */
private boolean validRHSForAssignToPrototype(AstNode right) {
    if (right instanceof ObjectLiteral || right instanceof NewExpression) {
        return true;
    }
    if (right instanceof PropertyGet) {
        PropertyGet pg = (PropertyGet) right;
        if (pg.getProperty().getIdentifier().equals("prototype")) {
            return true;
        }
    }
    return false;
}
 
Example #9
Source File: ConstraintFactory.java    From SJS with Apache License 2.0 5 votes vote down vote up
/**
 * Find or create a term representing a property access
 */
public PropertyAccessTerm findOrCreatePropertyAccessTerm(ITypeTerm base, String property, PropertyGet pgNode){
    if (!propertyAccessTerms.containsKey(base)){
        propertyAccessTerms.put(base, new LinkedHashMap<String,PropertyAccessTerm>());
    }
    Map<String,PropertyAccessTerm> map = propertyAccessTerms.get(base);
    if (!map.containsKey(property)){
        map.put(property, new PropertyAccessTerm(base, property, pgNode));
    }
    return map.get(property);
}
 
Example #10
Source File: Parser.java    From JsDroidCmd with Mozilla Public License 2.0 5 votes vote down vote up
private void checkCallRequiresActivation(AstNode pn) {
    if ((pn.getType() == Token.NAME
         && "eval".equals(((Name)pn).getIdentifier()))
        || (pn.getType() == Token.GETPROP &&
            "eval".equals(((PropertyGet)pn).getProperty().getIdentifier())))
        setRequiresActivation();
}
 
Example #11
Source File: IRFactory.java    From JsDroidCmd with Mozilla Public License 2.0 5 votes vote down vote up
void decompile(AstNode node) {
    switch (node.getType()) {
      case Token.ARRAYLIT:
          decompileArrayLiteral((ArrayLiteral)node);
          break;
      case Token.OBJECTLIT:
          decompileObjectLiteral((ObjectLiteral)node);
          break;
      case Token.STRING:
          decompiler.addString(((StringLiteral)node).getValue());
          break;
      case Token.NAME:
          decompiler.addName(((Name)node).getIdentifier());
          break;
      case Token.NUMBER:
          decompiler.addNumber(((NumberLiteral)node).getNumber());
          break;
      case Token.GETPROP:
          decompilePropertyGet((PropertyGet)node);
          break;
      case Token.EMPTY:
          break;
      case Token.GETELEM:
          decompileElementGet((ElementGet) node);
          break;
      case Token.THIS:
          decompiler.addToken(node.getType());
          break;
      default:
          Kit.codeBug("unexpected token: "
                      + Token.typeToName(node.getType()));
    }
}
 
Example #12
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 #13
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 #14
Source File: PropertyAccessTerm.java    From SJS with Apache License 2.0 4 votes vote down vote up
public PropertyAccessTerm(ITypeTerm base, String property, PropertyGet pgNode){
	super(pgNode);
	this.base = base;
	this.property = property;
}
 
Example #15
Source File: Parser.java    From JsDroidCmd with Mozilla Public License 2.0 4 votes vote down vote up
protected Node simpleAssignment(Node left, Node right) {
    int nodeType = left.getType();
    switch (nodeType) {
      case Token.NAME:
          String name = ((Name) left).getIdentifier();
          if (inUseStrictDirective &&
              ("eval".equals(name) || "arguments".equals(name)))
          {
              reportError("msg.bad.id.strict", name);
          }
          left.setType(Token.BINDNAME);
          return new Node(Token.SETNAME, left, right);

      case Token.GETPROP:
      case Token.GETELEM: {
          Node obj, id;
          // If it's a PropertyGet or ElementGet, we're in the parse pass.
          // We could alternately have PropertyGet and ElementGet
          // override getFirstChild/getLastChild and return the appropriate
          // field, but that seems just as ugly as this casting.
          if (left instanceof PropertyGet) {
              obj = ((PropertyGet)left).getTarget();
              id = ((PropertyGet)left).getProperty();
          } else if (left instanceof ElementGet) {
              obj = ((ElementGet)left).getTarget();
              id = ((ElementGet)left).getElement();
          } else {
              // This branch is called during IRFactory transform pass.
              obj = left.getFirstChild();
              id = left.getLastChild();
          }
          int type;
          if (nodeType == Token.GETPROP) {
              type = Token.SETPROP;
              // TODO(stevey) - see https://bugzilla.mozilla.org/show_bug.cgi?id=492036
              // The new AST code generates NAME tokens for GETPROP ids where the old parser
              // generated STRING nodes. If we don't set the type to STRING below, this will
              // cause java.lang.VerifyError in codegen for code like
              // "var obj={p:3};[obj.p]=[9];"
              id.setType(Token.STRING);
          } else {
              type = Token.SETELEM;
          }
          return new Node(type, obj, id, right);
      }
      case Token.GET_REF: {
          Node ref = left.getFirstChild();
          checkMutableReference(ref);
          return new Node(Token.SET_REF, ref, right);
      }
    }

    throw codeBug();
}
 
Example #16
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;
	}
}
 
Example #17
Source File: ConstraintVisitor.java    From SJS with Apache License 2.0 4 votes vote down vote up
private ITypeTerm findOrCreatePropertyAccessTerm(ITypeTerm term, String name, PropertyGet pgNode){
	PropertyAccessTerm t = factory.findOrCreatePropertyAccessTerm(term, name, pgNode);
	generator.addTermLineNumber(t, pgNode != null ? pgNode.getLineno() : -1);
	return t;
}
 
Example #18
Source File: IRFactory.java    From JsDroidCmd with Mozilla Public License 2.0 4 votes vote down vote up
void decompilePropertyGet(PropertyGet node) {
    decompile(node.getTarget());
    decompiler.addToken(Token.DOT);
    decompile(node.getProperty());
}