Skip to content

Commit

Permalink
Convert Functionizer to new type system.
Browse files Browse the repository at this point in the history
	Change on 2016/11/05 by kstanger <kstanger@google.com>

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=138298380
  • Loading branch information
kstanger authored and tomball committed Nov 7, 2016
1 parent c45122b commit ae3d27c
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 101 deletions.
Expand Up @@ -23,7 +23,6 @@
import javax.lang.model.element.VariableElement; import javax.lang.model.element.VariableElement;
import org.eclipse.jdt.core.dom.IMethodBinding; import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding; import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.Modifier;


/** /**
* Generates signatures for classes, fields and methods, as defined by the JVM spec, 4.3.4, * Generates signatures for classes, fields and methods, as defined by the JVM spec, 4.3.4,
Expand Down Expand Up @@ -102,39 +101,40 @@ public static String createMethodTypeSignature(ExecutableElement method) {
return builder.toString(); return builder.toString();
} }


public static String createJniFunctionSignature(IMethodBinding method, ElementUtil elementUtil) { public static String createJniFunctionSignature(
ExecutableElement method, ElementUtil elementUtil) {
// Mangle function name as described in JNI specification. // Mangle function name as described in JNI specification.
// http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/design.html#wp615 // http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/design.html#wp615
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("Java_"); sb.append("Java_");


String methodName = method.getName(); String methodName = ElementUtil.getName(method);
ITypeBinding declaringClass = method.getDeclaringClass(); TypeElement declaringClass = ElementUtil.getDeclaringClass(method);
PackageElement pkg = elementUtil.getPackage(BindingConverter.getElement(declaringClass)); PackageElement pkg = elementUtil.getPackage(declaringClass);
if (pkg != null && !pkg.isUnnamed()) { if (pkg != null && !pkg.isUnnamed()) {
String pkgName = pkg.getQualifiedName().toString(); String pkgName = pkg.getQualifiedName().toString();
for (String part : pkgName.split("\\.")) { for (String part : pkgName.split("\\.")) {
sb.append(part); sb.append(part);
sb.append('_'); sb.append('_');
} }
} }
jniMangleClass(declaringClass, sb); jniMangleClass(BindingConverter.unwrapTypeElement(declaringClass), sb);
sb.append('_'); sb.append('_');
sb.append(jniMangle(methodName)); sb.append(jniMangle(methodName));


// Check whether the method is overloaded. // Check whether the method is overloaded.
int nameCount = 0; int nameCount = 0;
for (IMethodBinding m : declaringClass.getDeclaredMethods()) { for (ExecutableElement m : ElementUtil.getExecutables(declaringClass)) {
if (methodName.equals(m.getName()) && Modifier.isNative(m.getModifiers())) { if (methodName.equals(ElementUtil.getName(m)) && ElementUtil.isNative(m)) {
nameCount++; nameCount++;
} }
} }
if (nameCount >= 2) { if (nameCount >= 2) {
// Overloaded native methods, append JNI-mangled parameter types. // Overloaded native methods, append JNI-mangled parameter types.
sb.append("__"); sb.append("__");
ITypeBinding[] parameters = method.getParameterTypes(); for (VariableElement param : method.getParameters()) {
for (int iParam = 0; iParam < parameters.length; iParam++) { String type = createTypeSignature(
String type = createTypeSignature(parameters[iParam]); BindingConverter.unwrapTypeMirrorIntoTypeBinding(param.asType()));
sb.append(jniMangle(type)); sb.append(jniMangle(type));
} }
} }
Expand Down
Expand Up @@ -46,25 +46,22 @@
import com.google.devtools.j2objc.ast.TreeVisitor; import com.google.devtools.j2objc.ast.TreeVisitor;
import com.google.devtools.j2objc.ast.UnitTreeVisitor; import com.google.devtools.j2objc.ast.UnitTreeVisitor;
import com.google.devtools.j2objc.gen.SignatureGenerator; import com.google.devtools.j2objc.gen.SignatureGenerator;
import com.google.devtools.j2objc.jdt.BindingConverter;
import com.google.devtools.j2objc.types.FunctionElement; import com.google.devtools.j2objc.types.FunctionElement;
import com.google.devtools.j2objc.types.GeneratedVariableBinding; import com.google.devtools.j2objc.types.GeneratedVariableElement;
import com.google.devtools.j2objc.util.BindingUtil;
import com.google.devtools.j2objc.util.CaptureInfo; import com.google.devtools.j2objc.util.CaptureInfo;
import com.google.devtools.j2objc.util.ElementUtil; import com.google.devtools.j2objc.util.ElementUtil;
import com.google.devtools.j2objc.util.ErrorUtil; import com.google.devtools.j2objc.util.ErrorUtil;
import com.google.devtools.j2objc.util.NameTable; import com.google.devtools.j2objc.util.NameTable;
import com.google.devtools.j2objc.util.TranslationUtil; import com.google.devtools.j2objc.util.TranslationUtil;
import com.google.devtools.j2objc.util.TypeUtil;
import com.google.devtools.j2objc.util.UnicodeUtils; import com.google.devtools.j2objc.util.UnicodeUtils;
import java.lang.reflect.Modifier;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement; import javax.lang.model.element.VariableElement;
import org.eclipse.jdt.core.dom.IMethodBinding; import javax.lang.model.type.TypeMirror;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.Modifier;


/** /**
* Converts methods that don't need dynamic dispatch to C functions. This optimization * Converts methods that don't need dynamic dispatch to C functions. This optimization
Expand All @@ -76,7 +73,7 @@
public class Functionizer extends UnitTreeVisitor { public class Functionizer extends UnitTreeVisitor {


private final CaptureInfo captureInfo; private final CaptureInfo captureInfo;
private Set<IMethodBinding> functionizableMethods; private Set<ExecutableElement> functionizableMethods;


public Functionizer(CompilationUnit unit) { public Functionizer(CompilationUnit unit) {
super(unit); super(unit);
Expand All @@ -94,20 +91,20 @@ public boolean visit(CompilationUnit node) {
* final we must also find an invocation for that method. Static methods, though, * final we must also find an invocation for that method. Static methods, though,
* are always functionized since there are no dynamic dispatch issues. * are always functionized since there are no dynamic dispatch issues.
*/ */
private Set<IMethodBinding> determineFunctionizableMethods(final CompilationUnit unit) { private Set<ExecutableElement> determineFunctionizableMethods(final CompilationUnit unit) {
final Set<IMethodBinding> functionizableDeclarations = Sets.newHashSet(); final Set<ExecutableElement> functionizableDeclarations = Sets.newHashSet();
final Set<IMethodBinding> invocations = Sets.newHashSet(); final Set<ExecutableElement> invocations = Sets.newHashSet();
unit.accept(new TreeVisitor() { unit.accept(new TreeVisitor() {
@Override @Override
public void endVisit(MethodDeclaration node) { public void endVisit(MethodDeclaration node) {
if (canFunctionize(node)) { if (canFunctionize(node)) {
functionizableDeclarations.add(node.getMethodBinding()); functionizableDeclarations.add(node.getExecutableElement());
} }
} }


@Override @Override
public void endVisit(MethodInvocation node) { public void endVisit(MethodInvocation node) {
invocations.add(node.getMethodBinding().getMethodDeclaration()); invocations.add(node.getExecutableElement());
} }
}); });
return Sets.intersection(functionizableDeclarations, invocations); return Sets.intersection(functionizableDeclarations, invocations);
Expand All @@ -132,23 +129,23 @@ public boolean visit(SingleMemberAnnotation node) {
* Determines whether an instance method can be functionized. * Determines whether an instance method can be functionized.
*/ */
private boolean canFunctionize(MethodDeclaration node) { private boolean canFunctionize(MethodDeclaration node) {
IMethodBinding m = node.getMethodBinding(); ExecutableElement m = node.getExecutableElement();
int modifiers = node.getModifiers(); int modifiers = node.getModifiers();


// Never functionize these types of methods. // Never functionize these types of methods.
if (Modifier.isStatic(modifiers) || Modifier.isAbstract(modifiers) || !node.hasDeclaration() if (Modifier.isStatic(modifiers) || Modifier.isAbstract(modifiers) || !node.hasDeclaration()
|| m.isAnnotationMember()) { || ElementUtil.isAnnotationMember(m)) {
return false; return false;
} }


// Don't functionize equals/hash, since they are often called by collections. // Don't functionize equals/hash, since they are often called by collections.
String name = m.getName(); String name = ElementUtil.getName(m);
if ((name.equals("hashCode") && m.getParameterTypes().length == 0) if ((name.equals("hashCode") && m.getParameters().isEmpty())
|| (name.equals("equals") && m.getParameterTypes().length == 1)) { || (name.equals("equals") && m.getParameters().size() == 1)) {
return false; return false;
} }


if (!BindingUtil.isPrivate(m) && !BindingUtil.isFinal(m)) { if (!ElementUtil.isPrivate(m) && !ElementUtil.isFinal(m)) {
return false; return false;
} }


Expand Down Expand Up @@ -202,20 +199,20 @@ private void transferParams(


@Override @Override
public void endVisit(MethodInvocation node) { public void endVisit(MethodInvocation node) {
IMethodBinding binding = node.getMethodBinding().getMethodDeclaration(); ExecutableElement element = node.getExecutableElement();
if (!BindingUtil.isStatic(binding) && !functionizableMethods.contains(binding)) { if (!ElementUtil.isStatic(element) && !functionizableMethods.contains(element)) {
return; return;
} }


FunctionInvocation functionInvocation = new FunctionInvocation( FunctionInvocation functionInvocation =
newFunctionElement(BindingConverter.getExecutableElement(binding)), node.getTypeBinding()); new FunctionInvocation(newFunctionElement(element), node.getTypeMirror());
List<Expression> args = functionInvocation.getArguments(); List<Expression> args = functionInvocation.getArguments();
TreeUtil.moveList(node.getArguments(), args); TreeUtil.moveList(node.getArguments(), args);


if (!BindingUtil.isStatic(binding)) { if (!ElementUtil.isStatic(element)) {
Expression expr = node.getExpression(); Expression expr = node.getExpression();
if (expr == null) { if (expr == null) {
expr = new ThisExpression(TreeUtil.getEnclosingTypeBinding(node)); expr = new ThisExpression(TreeUtil.getEnclosingTypeElement(node).asType());
} }
args.add(0, TreeUtil.remove(expr)); args.add(0, TreeUtil.remove(expr));
} }
Expand All @@ -225,14 +222,14 @@ public void endVisit(MethodInvocation node) {


@Override @Override
public void endVisit(SuperMethodInvocation node) { public void endVisit(SuperMethodInvocation node) {
IMethodBinding binding = node.getMethodBinding().getMethodDeclaration(); ExecutableElement element = node.getExecutableElement();
// Yes, super method invocations can be static. // Yes, super method invocations can be static.
if (!BindingUtil.isStatic(binding)) { if (!ElementUtil.isStatic(element)) {
return; return;
} }


FunctionInvocation functionInvocation = new FunctionInvocation( FunctionInvocation functionInvocation =
newFunctionElement(BindingConverter.getExecutableElement(binding)), node.getTypeBinding()); new FunctionInvocation(newFunctionElement(element), node.getTypeMirror());
TreeUtil.moveList(node.getArguments(), functionInvocation.getArguments()); TreeUtil.moveList(node.getArguments(), functionInvocation.getArguments());
node.replaceWith(functionInvocation); node.replaceWith(functionInvocation);
} }
Expand Down Expand Up @@ -306,26 +303,26 @@ public void endVisit(ClassInstanceCreation node) {


@Override @Override
public void endVisit(MethodDeclaration node) { public void endVisit(MethodDeclaration node) {
IMethodBinding binding = node.getMethodBinding(); ExecutableElement element = node.getExecutableElement();
// Don't functionize certain ObjC methods like dealloc or __annotations, since // Don't functionize certain ObjC methods like dealloc or __annotations, since
// they are added by the translator and need to remain in method form. // they are added by the translator and need to remain in method form.
if (!node.hasDeclaration()) { if (!node.hasDeclaration()) {
return; return;
} }
boolean isInstanceMethod = !BindingUtil.isStatic(binding) && !binding.isConstructor(); boolean isConstructor = ElementUtil.isConstructor(element);
boolean isDefaultMethod = Modifier.isDefault(node.getModifiers()); boolean isInstanceMethod = !ElementUtil.isStatic(element) && !isConstructor;
boolean isDefaultMethod = ElementUtil.isDefault(element);
List<BodyDeclaration> declarationList = TreeUtil.asDeclarationSublist(node); List<BodyDeclaration> declarationList = TreeUtil.asDeclarationSublist(node);
if (!isInstanceMethod || isDefaultMethod || Modifier.isNative(node.getModifiers()) if (!isInstanceMethod || isDefaultMethod || Modifier.isNative(node.getModifiers())
|| functionizableMethods.contains(binding)) { || functionizableMethods.contains(element)) {
ITypeBinding declaringClass = binding.getDeclaringClass(); TypeElement declaringClass = ElementUtil.getDeclaringClass(element);
boolean isEnumConstructor = binding.isConstructor() && declaringClass.isEnum(); boolean isEnumConstructor = isConstructor && ElementUtil.isEnum(declaringClass);
if (binding.isConstructor()) { if (isConstructor) {
addImplicitParameters(node, BindingConverter.getTypeElement(declaringClass)); addImplicitParameters(node, declaringClass);
} }
FunctionDeclaration function = makeFunction(node); FunctionDeclaration function = makeFunction(node);
declarationList.add(function); declarationList.add(function);
if (binding.isConstructor() && !BindingUtil.isAbstract(declaringClass) if (isConstructor && !ElementUtil.isAbstract(declaringClass) && !isEnumConstructor) {
&& !isEnumConstructor) {
declarationList.add(makeAllocatingConstructor(node, false)); declarationList.add(makeAllocatingConstructor(node, false));
declarationList.add(makeAllocatingConstructor(node, true)); declarationList.add(makeAllocatingConstructor(node, true));
} else if (isEnumConstructor && Options.useARC()) { } else if (isEnumConstructor && Options.useARC()) {
Expand All @@ -335,17 +332,16 @@ public void endVisit(MethodDeclaration node) {
// Instance methods must be kept in case they are invoked using "super". // Instance methods must be kept in case they are invoked using "super".
boolean keepMethod = isInstanceMethod boolean keepMethod = isInstanceMethod
// Public methods must be kept for the public API. // Public methods must be kept for the public API.
|| !(BindingUtil.isPrivateInnerType(declaringClass) || BindingUtil.isPrivate(binding)) || !(ElementUtil.isPrivateInnerType(declaringClass) || ElementUtil.isPrivate(element))
// Methods must be kept for reflection if enabled. // Methods must be kept for reflection if enabled.
|| (TranslationUtil.needsReflection(BindingConverter.getTypeElement(declaringClass)) || (TranslationUtil.needsReflection(declaringClass) && !isEnumConstructor);
&& !isEnumConstructor);
if (keepMethod) { if (keepMethod) {
if (isDefaultMethod) { if (isDefaultMethod) {
// For default methods keep only the declaration. Implementing classes will add a shim. // For default methods keep only the declaration. Implementing classes will add a shim.
node.setBody(null); node.setBody(null);
node.addModifiers(Modifier.ABSTRACT); node.addModifiers(Modifier.ABSTRACT);
} else { } else {
setFunctionCaller(node, binding); setFunctionCaller(node, element);
} }
} else { } else {
node.remove(); node.remove();
Expand All @@ -369,25 +365,24 @@ private void addImplicitParameters(MethodDeclaration node, TypeElement type) {
* Create an equivalent function declaration for a given method. * Create an equivalent function declaration for a given method.
*/ */
private FunctionDeclaration makeFunction(MethodDeclaration method) { private FunctionDeclaration makeFunction(MethodDeclaration method) {
IMethodBinding m = method.getMethodBinding();
ExecutableElement elem = method.getExecutableElement(); ExecutableElement elem = method.getExecutableElement();
ITypeBinding declaringClass = m.getDeclaringClass(); TypeElement declaringClass = ElementUtil.getDeclaringClass(elem);
boolean isInstanceMethod = !BindingUtil.isStatic(m) && !m.isConstructor(); boolean isInstanceMethod = !ElementUtil.isStatic(elem) && !ElementUtil.isConstructor(elem);


FunctionDeclaration function = FunctionDeclaration function =
new FunctionDeclaration(nameTable.getFullFunctionName(elem), m.getReturnType()); new FunctionDeclaration(nameTable.getFullFunctionName(elem), elem.getReturnType());
function.setJniSignature(SignatureGenerator.createJniFunctionSignature(m, elementUtil)); function.setJniSignature(SignatureGenerator.createJniFunctionSignature(elem, elementUtil));
function.setLineNumber(method.getName().getLineNumber()); function.setLineNumber(method.getName().getLineNumber());


if (!BindingUtil.isStatic(m)) { if (!ElementUtil.isStatic(elem)) {
GeneratedVariableBinding var = new GeneratedVariableBinding(NameTable.SELF_NAME, 0, VariableElement var = GeneratedVariableElement.newParameter(
declaringClass, false, true, declaringClass, null); NameTable.SELF_NAME, declaringClass.asType(), null);
function.addParameter(new SingleVariableDeclaration(var)); function.addParameter(new SingleVariableDeclaration(var));
} }
TreeUtil.copyList(method.getParameters(), function.getParameters()); TreeUtil.copyList(method.getParameters(), function.getParameters());


function.setModifiers(method.getModifiers() & Modifier.STATIC); function.setModifiers(method.getModifiers() & Modifier.STATIC);
if (BindingUtil.isPrivate(m) || (isInstanceMethod && !BindingUtil.isDefault(m))) { if (ElementUtil.isPrivate(elem) || (isInstanceMethod && !ElementUtil.isDefault(elem))) {
function.addModifiers(Modifier.PRIVATE); function.addModifiers(Modifier.PRIVATE);
} else { } else {
function.addModifiers(Modifier.PUBLIC); function.addModifiers(Modifier.PUBLIC);
Expand All @@ -400,16 +395,14 @@ private FunctionDeclaration makeFunction(MethodDeclaration method) {


function.setBody(TreeUtil.remove(method.getBody())); function.setBody(TreeUtil.remove(method.getBody()));


if (BindingUtil.isStatic(m)) { if (ElementUtil.isStatic(elem)) {
// Add class initialization invocation, since this may be the first use of this class. // Add class initialization invocation, since this may be the first use of this class.
String initName = UnicodeUtils.format("%s_initialize", nameTable.getFullName(declaringClass)); String initName = UnicodeUtils.format("%s_initialize", nameTable.getFullName(declaringClass));
ITypeBinding voidType = typeEnv.resolveJavaType("void"); TypeMirror voidType = typeUtil.getVoidType();
FunctionElement initElement = new FunctionElement(initName, voidType, declaringClass); FunctionElement initElement = new FunctionElement(initName, voidType, declaringClass);
FunctionInvocation initCall = new FunctionInvocation(initElement, voidType); FunctionInvocation initCall = new FunctionInvocation(initElement, voidType);
function.getBody().addStatement(0, new ExpressionStatement(initCall)); function.getBody().addStatement(0, new ExpressionStatement(initCall));
} } else {

if (!BindingUtil.isStatic(m)) {
FunctionConverter.convert(function); FunctionConverter.convert(function);
} }


Expand All @@ -422,15 +415,14 @@ private FunctionDeclaration makeFunction(MethodDeclaration method) {
private FunctionDeclaration makeAllocatingConstructor( private FunctionDeclaration makeAllocatingConstructor(
MethodDeclaration method, boolean releasing) { MethodDeclaration method, boolean releasing) {
assert method.isConstructor(); assert method.isConstructor();
IMethodBinding binding = method.getMethodBinding();
ExecutableElement element = method.getExecutableElement(); ExecutableElement element = method.getExecutableElement();
ITypeBinding declaringClass = binding.getDeclaringClass(); TypeElement declaringClass = ElementUtil.getDeclaringClass(element);


String name = releasing ? nameTable.getReleasingConstructorName(element) String name = releasing ? nameTable.getReleasingConstructorName(element)
: nameTable.getAllocatingConstructorName(element); : nameTable.getAllocatingConstructorName(element);
FunctionDeclaration function = new FunctionDeclaration(name, declaringClass); FunctionDeclaration function = new FunctionDeclaration(name, declaringClass.asType());
function.setLineNumber(method.getName().getLineNumber()); function.setLineNumber(method.getName().getLineNumber());
function.setModifiers(BindingUtil.isPrivate(binding) ? Modifier.PRIVATE : Modifier.PUBLIC); function.setModifiers(ElementUtil.isPrivate(element) ? Modifier.PRIVATE : Modifier.PUBLIC);
function.setReturnsRetained(!releasing); function.setReturnsRetained(!releasing);
TreeUtil.copyList(method.getParameters(), function.getParameters()); TreeUtil.copyList(method.getParameters(), function.getParameters());
Block body = new Block(); Block body = new Block();
Expand All @@ -440,7 +432,7 @@ private FunctionDeclaration makeAllocatingConstructor(
sb.append(nameTable.getFullName(declaringClass)); sb.append(nameTable.getFullName(declaringClass));
sb.append(", ").append(nameTable.getFunctionName(element)); sb.append(", ").append(nameTable.getFunctionName(element));
for (SingleVariableDeclaration param : function.getParameters()) { for (SingleVariableDeclaration param : function.getParameters()) {
sb.append(", ").append(nameTable.getVariableQualifiedName(param.getVariableBinding())); sb.append(", ").append(nameTable.getVariableQualifiedName(param.getVariableElement()));
} }
sb.append(")"); sb.append(")");
body.addStatement(new NativeStatement(sb.toString())); body.addStatement(new NativeStatement(sb.toString()));
Expand All @@ -451,26 +443,26 @@ private FunctionDeclaration makeAllocatingConstructor(
/** /**
* Replace method block statements with single statement that invokes function. * Replace method block statements with single statement that invokes function.
*/ */
private void setFunctionCaller(MethodDeclaration method, IMethodBinding methodBinding) { private void setFunctionCaller(MethodDeclaration method, ExecutableElement methodElement) {
ITypeBinding returnType = methodBinding.getReturnType(); TypeMirror returnType = methodElement.getReturnType();
ITypeBinding declaringClass = methodBinding.getDeclaringClass(); TypeElement declaringClass = ElementUtil.getDeclaringClass(methodElement);
Block body = new Block(); Block body = new Block();
method.setBody(body); method.setBody(body);
method.removeModifiers(Modifier.NATIVE); method.removeModifiers(Modifier.NATIVE);
List<Statement> stmts = body.getStatements(); List<Statement> stmts = body.getStatements();
FunctionInvocation invocation = new FunctionInvocation( FunctionInvocation invocation =
newFunctionElement(BindingConverter.getExecutableElement(methodBinding)), returnType); new FunctionInvocation(newFunctionElement(methodElement), returnType);
List<Expression> args = invocation.getArguments(); List<Expression> args = invocation.getArguments();
if (!BindingUtil.isStatic(methodBinding)) { if (!ElementUtil.isStatic(methodElement)) {
args.add(new ThisExpression(methodBinding.getDeclaringClass())); args.add(new ThisExpression(declaringClass.asType()));
} }
for (SingleVariableDeclaration param : method.getParameters()) { for (SingleVariableDeclaration param : method.getParameters()) {
args.add(new SimpleName(param.getVariableBinding())); args.add(new SimpleName(param.getVariableElement()));
} }
if (BindingUtil.isVoid(returnType)) { if (TypeUtil.isVoid(returnType)) {
stmts.add(new ExpressionStatement(invocation)); stmts.add(new ExpressionStatement(invocation));
if (methodBinding.isConstructor()) { if (ElementUtil.isConstructor(methodElement)) {
stmts.add(new ReturnStatement(new ThisExpression(declaringClass))); stmts.add(new ReturnStatement(new ThisExpression(declaringClass.asType())));
} }
} else { } else {
stmts.add(new ReturnStatement(invocation)); stmts.add(new ReturnStatement(invocation));
Expand All @@ -482,14 +474,13 @@ private void setFunctionCaller(MethodDeclaration method, IMethodBinding methodBi
*/ */
private static class FunctionConverter extends TreeVisitor { private static class FunctionConverter extends TreeVisitor {


private final IVariableBinding selfParam; private final VariableElement selfParam;


static void convert(FunctionDeclaration function) { static void convert(FunctionDeclaration function) {
IVariableBinding selfParam = function.getParameter(0).getVariableBinding(); function.accept(new FunctionConverter(function.getParameter(0).getVariableElement()));
function.accept(new FunctionConverter(selfParam));
} }


private FunctionConverter(IVariableBinding selfParam) { private FunctionConverter(VariableElement selfParam) {
this.selfParam = selfParam; this.selfParam = selfParam;
} }


Expand Down

0 comments on commit ae3d27c

Please sign in to comment.