Package com.google.caja.parser.js

Examples of com.google.caja.parser.js.Reference


      isSynthetic = true;
    } else if (n instanceof Identifier) {
      Identifier ident = (Identifier) n;
      isSynthetic = ident.getName() != null && ident.getName().endsWith("__");
    } else if (n instanceof Reference) {
      Reference ref = (Reference) n;
      isSynthetic = ref.getIdentifierName().endsWith("__");
    }

    // StringLiteral values are the raw text, so compare by decoded value.
    QuasiNode.Equivalence cmp = (n instanceof StringLiteral)
        ? QuasiNode.EQUAL_UNESCAPED : QuasiNode.SAFE_EQUALS;
View Full Code Here


            continue;
          }
        }
        QuasiNode keyQuasi = build(
            keyIdent != null
            ? new Reference(new Identifier(FilePosition.UNKNOWN, keyIdent))
            : key);
        propQuasis.add(new SinglePropertyQuasi(keyQuasi, build(value)));
      } else {
        // TODO: support getters and setters in object quasis
        throw new UnsupportedOperationException(prop.getClass().getName());
View Full Code Here

    }
    return n;
  }

  public static Reference newReference(FilePosition pos, String name) {
    return new Reference(s(new Identifier(pos, name)));
  }
View Full Code Here

        lhs, (Expression) rewriter.expand(lhs, scope));
  }

  private ReadAssignOperands sideEffectingReadAssignOperand(
      Expression uncajoledObject, Expression uncajoledKey, Scope scope) {
    Reference object;  // The object that contains the field to assign.
    Expression key;  // Identifies the field to assign.
    List<Expression> temporaries = Lists.newArrayList();

    // Don't cajole the operands.  We return a simple assignment operator that
    // can then itself be cajoled, so that a rewriter can use context to treat
    // the LHS differently from the RHS.

    // a[b] += 2
    //   =>
    // var x___ = a;
    // var x0___ = b;

    // If the right is simple then we can assume it does not modify the
    // left, but otherwise the left has to be put into a temporary so that
    // it's evaluated before the right can muck with it.
    boolean isKeySimple = (uncajoledKey instanceof Literal
                           || isLocalReference(uncajoledKey, scope));

    // If the left is simple and the right does not need a temporary variable
    // then don't introduce one.
    if (isKeySimple && (isLocalReference(uncajoledObject, scope)
                        || isImportsReference(uncajoledObject))) {
      object = (Reference) uncajoledObject;
    } else {
      Reference tmpVar = scope.declareStartOfScopeTemp();
      temporaries.add((Expression) QuasiBuilder.substV(
          "@tmpVar = @left;",
          "tmpVar", tmpVar,
          "left", rewriter.expand(uncajoledObject, scope)));
      object = tmpVar;
    }

    // Don't bother to generate a temporary for a simple value like 'foo'
    if (isKeySimple) {
      key = uncajoledKey;
    } else {
      ParseTreeNode rightExpanded = rewriter.expand(uncajoledKey, scope);
      Reference tmpVar = scope.declareStartOfScopeTemp();
      key = tmpVar;
      if (QuasiBuilder.match("@s&(-1>>>1)", rightExpanded)) {
        // TODO(metaweta): Figure out a way to leave key alone and
        // protect propertyAccess from rewriting instead.
        key = (Expression) QuasiBuilder.substV("@key&(-1>>>1)", "key", key);
      }
      temporaries.add((Expression) QuasiBuilder.substV(
          "@tmpVar = @right;",
          "tmpVar", tmpVar,
          "right", rightExpanded));
    }

    Operation propertyAccess = null;
    if (key instanceof StringLiteral) {
      // Make sure that cases like
      //   arr.length -= 1
      // optimize arr.length in the right-hand-side usage.
      // See the array length case in testSetReadModifyWriteLocalVar.
      String keyText = ((StringLiteral) key).getUnquotedValue();
      if (ParserBase.isJavascriptIdentifier(keyText)
          && Keyword.fromString(keyText) == null) {
        Reference ident = new Reference(
            new Identifier(key.getFilePosition(), keyText));
        propertyAccess = Operation.create(
            FilePosition.span(object.getFilePosition(), key.getFilePosition()),
            Operator.MEMBER_ACCESS, object, ident);
      }
View Full Code Here

      return new ParseTreeNodeContainer(
          Arrays.asList(Arrays.copyOfRange(refs, i, refs.length)));
    }

    private void makeTemp(int i, Expression value) {
      Reference temp = scope.declareStartOfScopeTemp();
      refs[i] = temp;
      inits[i] = (Expression) QuasiBuilder.substV(
          "@temp = @value",
          "temp", temp,
          "value", value);
View Full Code Here

        "id", id));
    return id;
  }

  public Reference declareStartOfScopeTemp() {
    return new Reference(declareStartOfScopeTempVariable());
  }
View Full Code Here

          matches="/* synthetic */ @ref",
          matchNode=Reference.class,
          substitutes="<expanded>")
      public ParseTreeNode fire(ParseTreeNode node, Scope scope) {
        if (node instanceof Reference) {
          Reference ref = (Reference) node;
          if (isSynthetic(ref.getIdentifier())) {
            // noexpand needed since node itself may not be synthetic
            // even though we now know it contains a synthetic identifier.
            return rw.noexpand((Reference) node);
          }
        }
        return NONE;
      }
    },

    new Rule() {
      @Override
      @RuleDescription(
          name="syntheticCalls",
          synopsis="Pass through calls where the function name is synthetic.",
          reason="A synthetic method may not be marked callable.",
          matches="/* synthetic */ @f(@as*)",
          substitutes="<expanded>")
      public ParseTreeNode fire(ParseTreeNode node, Scope scope) {
        Map<String, ParseTreeNode> bindings = this.match(node);
        if (bindings != null) {
          Expression f = (Expression) bindings.get("f");
          if (f instanceof Reference && isSynthetic((Reference) f)) {
            return expandAll(node, scope);
          }
        }
        return NONE;
      }
    },

    new Rule() {
      @Override
      @RuleDescription(
          name="syntheticMethodCalls",
          synopsis="Pass through calls where the method name is synthetic.",
          reason="A synthetic method may not be marked callable.",
          matches="/* synthetic */ @o.@m(@as*)",
          substitutes="<expanded>")
      public ParseTreeNode fire(ParseTreeNode node, Scope scope) {
        Map<String, ParseTreeNode> bindings = this.match(node);
        if (bindings != null && isSynthetic((Reference) bindings.get("m"))) {
          return expandAll(node, scope);
        }
        return NONE;
      }
    },

    new Rule() {
      @Override
      @RuleDescription(
          name="syntheticDeletes",
          synopsis="Pass through deletes of synthetic members.",
          reason="A synthetic member may not be marked deletable.",
          matches="/* synthetic */ delete @o.@m",
          substitutes="<expanded>")
      public ParseTreeNode fire(ParseTreeNode node, Scope scope) {
        Map<String, ParseTreeNode> bindings = this.match(node);
        if (bindings != null && isSynthetic((Reference) bindings.get("m"))) {
          return expandAll(node, scope);
        }
        return NONE;
      }
    },

    new Rule() {
      @Override
      @RuleDescription(
          name="syntheticReads",
          synopsis="Pass through reads of synthetic members.",
          reason="A synthetic member may not be marked readable.",
          matches="/* synthetic */ @o.@m",
          substitutes="<expanded>")
      public ParseTreeNode fire(ParseTreeNode node, Scope scope) {
        Map<String, ParseTreeNode> bindings = this.match(node);
        if (bindings != null && isSynthetic((Reference) bindings.get("m"))) {
          return expandAll(node, scope);
        }
        return NONE;
      }
    },

    new Rule() {
      @Override
      @RuleDescription(
          name="syntheticSetMember",
          synopsis="Pass through sets of synthetic members.",
          reason="A synthetic member may not be marked writable.",
          matches="/* synthetic */ @o.@m = @v",
          substitutes="<expanded>")
      public ParseTreeNode fire(ParseTreeNode node, Scope scope) {
        Map<String, ParseTreeNode> bindings = this.match(node);
        if (bindings != null && isSynthetic((Reference) bindings.get("m"))) {
          return expandAll(node, scope);
        }
        return NONE;
      }
    },

    new Rule() {
      @Override
      @RuleDescription(
          name="syntheticSetVar",
          synopsis="Pass through set of synthetic vars.",
          reason="A local variable might not be mentionable otherwise.",
          matches="/* synthetic */ @lhs = @rhs",
          substitutes="<expanded>")
      public ParseTreeNode fire(ParseTreeNode node, Scope scope) {
        Map<String, ParseTreeNode> bindings = this.match(node);
        if (bindings != null && bindings.get("lhs") instanceof Reference) {
          if (isSynthetic((Reference) bindings.get("lhs"))) {
            return expandAll(node, scope);
          }
        }
        return NONE;
      }
    },

    new Rule() {
      @Override
      @RuleDescription(
          name="syntheticDeclaration",
          synopsis="Pass through synthetic variables which are unmentionable.",
          reason="Synthetic code might need local variables for safe-keeping.",
          matches="/* synthetic */ var @v = @initial?;",
          substitutes="<expanded>")
      public ParseTreeNode fire(ParseTreeNode node, Scope scope) {
        Map<String, ParseTreeNode> bindings = this.match(node);
        if (bindings != null && isSynthetic((Identifier) bindings.get("v"))) {
          Declaration d = (Declaration) expandAll(node, scope);
          Statement s;
          if (d.getInitializer() == null) {
            s = new Noop(d.getFilePosition());
          } else {
            s = new ExpressionStmt(
                Operation.createInfix(
                    Operator.ASSIGN, new Reference(d.getIdentifier()),
                    d.getInitializer()));
            getRewriter().markTreeForSideEffect(s);
            d.removeChild(d.getInitializer());
          }
          scope.addStartOfScopeStatement(d);
View Full Code Here

TOP

Related Classes of com.google.caja.parser.js.Reference

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.