1c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount/*
2c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount * Copyright (C) 2016 The Android Open Source Project
3c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount *
4c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount * Licensed under the Apache License, Version 2.0 (the "License");
5c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount * you may not use this file except in compliance with the License.
6c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount * You may obtain a copy of the License at
7c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount *
8c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount *      http://www.apache.org/licenses/LICENSE-2.0
9c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount *
10c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount * Unless required by applicable law or agreed to in writing, software
11c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount * distributed under the License is distributed on an "AS IS" BASIS,
12c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount * See the License for the specific language governing permissions and
14c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount * limitations under the License.
15c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount */
16c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount
17c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mountpackage android.databinding.tool.expr;
18c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount
19c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mountimport android.databinding.tool.reflection.ModelAnalyzer;
20c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mountimport android.databinding.tool.reflection.ModelClass;
21c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mountimport android.databinding.tool.util.L;
22c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mountimport android.databinding.tool.util.Preconditions;
23c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mountimport android.databinding.tool.writer.KCode;
24c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount
25c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mountpublic class MethodReferenceExpr extends MethodBaseExpr {
26c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount
27c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount    MethodReferenceExpr(Expr parent, String name) {
28c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount        super(parent, name);
29c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount    }
30c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount
31c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount    @Override
32c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount    protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) {
33c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount        return modelAnalyzer.findClass(Object.class);
34c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount    }
35c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount
36c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount    @Override
37c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount    protected String computeUniqueKey() {
38c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount        return join(mName, "::", getTarget().getUniqueKey());
39c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount    }
40c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount
41c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount    @Override
42c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount    public String getInvertibleError() {
43c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount        return "Listeners do not support two-way binding";
44c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount    }
45c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount
46c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount    @Override
47c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount    public boolean isDynamic() {
48c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount        return true;
49c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount    }
50c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount
51c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount    @Override
52c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount    public Expr resolveListeners(ModelClass listener, Expr parent) {
53c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount        try {
54c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount            return resolveListenersAsMethodReference(listener, parent);
55c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount        } catch (IllegalStateException e) {
56c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount            L.e("%s", e.getMessage());
57c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount            return this;
58c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount        }
59c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount    }
60c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount
61c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount    @Override
62c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount    protected KCode generateCode() {
63c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount        // once we can deprecate using Field.access for callbacks, we can get rid of this since
64c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount        // it will be detected when resolve type is run.
65c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount        Preconditions.check(false, "Cannot generate code for unresolved method reference %s", this);
66c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount        return null;
67c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount    }
68c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount
69c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount    @Override
70c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount    public Expr generateInverse(ExprModel model, Expr value, String bindingClassName) {
71c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount        Preconditions.check(false, "Method references do not have an inverse");
72c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount        return this;
73c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount    }
74c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount
75c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount    @Override
76c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount    public Expr cloneToModel(ExprModel model) {
77c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount        final Expr clonedTarget = getTarget().cloneToModel(model);
78c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount        return model.methodReference(clonedTarget, mName);
79c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount    }
80c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount
81c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount    @Override
82c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount    public String toString() {
83c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount        return getTarget().toString() + "::" + mName;
84c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount    }
85c0c1dab0b6254e4d27f18c37a72a9e7952e958a0George Mount}
86