MethodCallExpr.java revision 019c36b97c7c172ac03997f6bf170e65b2ed7fe4
1d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar/*
2d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * Copyright (C) 2015 The Android Open Source Project
3d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar *
4d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License");
5d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * you may not use this file except in compliance with the License.
6d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * You may obtain a copy of the License at
7d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar *
8d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar *      http://www.apache.org/licenses/LICENSE-2.0
9d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar *
10d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * Unless required by applicable law or agreed to in writing, software
11d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS,
12d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * See the License for the specific language governing permissions and
14d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * limitations under the License.
15d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar */
16d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
17fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountpackage android.databinding.tool.expr;
18d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
19d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarimport com.google.common.collect.Iterables;
20d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
21fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.Callable;
22fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.Callable.Type;
23fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.ModelAnalyzer;
24fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.ModelClass;
25fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.ModelMethod;
26fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.util.L;
27d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
28d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarimport java.util.ArrayList;
29d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarimport java.util.Arrays;
30d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarimport java.util.List;
31019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarimport static android.databinding.tool.reflection.Callable.STATIC;
32019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarimport static android.databinding.tool.reflection.Callable.DYNAMIC;
33019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarimport static android.databinding.tool.reflection.Callable.CAN_BE_INVALIDATED;
34019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar
35d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
36d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarpublic class MethodCallExpr extends Expr {
37d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    final String mName;
38d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
39e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mount    Callable mGetter;
40d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
41d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    MethodCallExpr(Expr target, String name, List<Expr> args) {
42d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar        super(Iterables.concat(Arrays.asList(target), args));
43d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar        mName = name;
44d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    }
45d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
46d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    @Override
4718243f6f1b7527272ef4feccdf4327d80d9f2241George Mount    public void updateExpr(ModelAnalyzer modelAnalyzer) {
4818243f6f1b7527272ef4feccdf4327d80d9f2241George Mount        resolveType(modelAnalyzer);
4918243f6f1b7527272ef4feccdf4327d80d9f2241George Mount        super.updateExpr(modelAnalyzer);
5018243f6f1b7527272ef4feccdf4327d80d9f2241George Mount    }
5118243f6f1b7527272ef4feccdf4327d80d9f2241George Mount
5218243f6f1b7527272ef4feccdf4327d80d9f2241George Mount    @Override
5379fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount    protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) {
54d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar        if (mGetter == null) {
55895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar            List<ModelClass> args = new ArrayList<ModelClass>();
567920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount            for (Expr expr : getArgs()) {
57d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar                args.add(expr.getResolvedType());
58d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar            }
5918243f6f1b7527272ef4feccdf4327d80d9f2241George Mount
6018243f6f1b7527272ef4feccdf4327d80d9f2241George Mount            Expr target = getTarget();
61a70fed6415aa1e8bbbe929aee776402ac3b81c86George Mount            boolean isStatic = target instanceof StaticIdentifierExpr;
62fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount            ModelMethod method = target.getResolvedType().getMethod(mName, args, isStatic);
63fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount            if (method == null) {
64fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount                String message = "cannot find method '" + mName + "' in class " +
65fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount                        target.getResolvedType().toJavaCode();
66fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount                IllegalArgumentException e = new IllegalArgumentException(message);
67fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount                L.e(e, "cannot find method %s in class %s", mName,
68fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount                        target.getResolvedType().toJavaCode());
69fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount                throw e;
70fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount            }
71019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar            int flags = DYNAMIC;
72019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar            if (method.isStatic()) {
73019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar                flags |= STATIC;
74019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar            }
75019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar            mGetter = new Callable(Type.METHOD, method.getName(), method.getReturnType(args), flags);
76d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar        }
77d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar        return mGetter.resolvedType;
78d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    }
79d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
80d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    @Override
81d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    protected List<Dependency> constructDependencies() {
82dc69f49d687ec036947f26a9bf9025a305de0721Yigit Boyar        final List<Dependency> dependencies = constructDynamicChildrenDependencies();
83dc69f49d687ec036947f26a9bf9025a305de0721Yigit Boyar        for (Dependency dependency : dependencies) {
847920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount            if (dependency.getOther() == getTarget()) {
85dc69f49d687ec036947f26a9bf9025a305de0721Yigit Boyar                dependency.setMandatory(true);
86dc69f49d687ec036947f26a9bf9025a305de0721Yigit Boyar            }
87dc69f49d687ec036947f26a9bf9025a305de0721Yigit Boyar        }
88dc69f49d687ec036947f26a9bf9025a305de0721Yigit Boyar        return dependencies;
89d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    }
90d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
91d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    @Override
92d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    protected String computeUniqueKey() {
937920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount        return sUniqueKeyJoiner.join(getTarget().computeUniqueKey(), mName,
947920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount                super.computeUniqueKey());
95d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    }
96d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
97d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    public Expr getTarget() {
987920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount        return getChildren().get(0);
99d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    }
100d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
101d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    public String getName() {
102d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar        return mName;
103d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    }
104d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
105d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    public List<Expr> getArgs() {
1067920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount        return getChildren().subList(1, getChildren().size());
107d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    }
108d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
109e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mount    public Callable getGetter() {
110d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar        return mGetter;
111d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    }
112d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar}
113