@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); }
@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()); }