예제 #1
0
    @Override
    public void endVisit(JsNameRef x, JsContext ctx) {
      String ident = x.getIdent();
      if (!x.isJsniReference()) {
        // Not a jsni reference.
        return;
      }

      JsniRef jsniRef = JsniRef.parse(ident);
      if (jsniRef == null) {
        emitError(ERR_MALFORMED_JSNI_IDENTIFIER, x.getSourceInfo(), null, ident);
        return;
      }

      Binding binding =
          resolveReference(x.getSourceInfo(), jsniRef, x.getQualifier() != null, ctx.isLvalue());

      assert !x.isResolved();
      if (!ident.equals(jsniRef.getResolvedReference())) {
        // Replace by the resolved reference (consisting of the fully qualified classname and the
        // method description including actual signature) so that dispatch everywhere is consistent
        // with the one resolved here.
        ident = jsniRef.getResolvedReference();
        JsNameRef newRef = new JsNameRef(x.getSourceInfo(), ident);
        newRef.setQualifier(x.getQualifier());
        ctx.replaceMe(newRef);
      }
      if (binding != null) {
        jsniRefs.put(ident, binding);
      }
    }
 private Node transform(JsNameRef x) {
   Node n;
   JsName name = x.getName();
   boolean isExternal = name == null || !name.isObfuscatable();
   if (x.getQualifier() != null) {
     n = IR.getprop(transform(x.getQualifier()), transformNameAsString(x.getShortIdent(), x));
     if (isExternal) {
       this.externalProperties.add(x.getShortIdent());
     }
   } else {
     n = transformName(x.getShortIdent(), x);
     if (isExternal) {
       this.externalVars.add(x.getShortIdent());
     } else if (name.getEnclosing() == program.getScope()) {
       this.globalVars.add(x.getShortIdent());
     }
   }
   applyOriginalName(n, x);
   return applySourceInfo(n, x);
 }
예제 #3
0
    @Override
    public void endVisit(JsBinaryOperation x, JsContext ctx) {
      // Look for the patern a.f = o.@C::m();
      if (!x.getOperator().isAssignment()) {
        return;
      }
      if (!(x.getArg1() instanceof JsNameRef) || !(x.getArg2() instanceof JsNameRef)) {
        return;
      }

      JsNameRef lhs = (JsNameRef) x.getArg1();
      JsNameRef rhs = (JsNameRef) x.getArg2();

      if (!rhs.isJsniReference() || !(jsniRefs.get(rhs.getIdent()) instanceof MethodBinding)) {
        // Not a reference to a JSNI method.
        return;
      }

      if (rhs.getQualifier() == null) {
        // Unqualified JSNI reference is OK.
        return;
      }

      if (lhs.getQualifier() == null) {
        // Assignment to unqualified variable is OK.
        return;
      }

      // Here we have a qualified JSNI method reference assigned to a field.
      JsniRef jsniRef = JsniRef.parse(rhs.getIdent());
      emitWarning(
          "unsafe",
          WARN_NOT_CAPTURING_QUALIFIER,
          x.getSourceInfo(),
          jsniRef,
          rhs.getQualifier().toSource());
    }