FieldAccessExpr.java revision fead9ca09b117136b35bc5bf137340a754f9eddd
1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.databinding.tool.expr;
18
19import android.databinding.tool.reflection.Callable;
20import android.databinding.tool.reflection.ModelAnalyzer;
21import android.databinding.tool.reflection.ModelClass;
22import android.databinding.tool.util.L;
23
24import java.util.List;
25
26public class FieldAccessExpr extends Expr {
27    String mName;
28    Callable mGetter;
29    final boolean mIsObservableField;
30
31    FieldAccessExpr(Expr parent, String name) {
32        super(parent);
33        mName = name;
34        mIsObservableField = false;
35    }
36
37    FieldAccessExpr(Expr parent, String name, boolean isObservableField) {
38        super(parent);
39        mName = name;
40        mIsObservableField = isObservableField;
41    }
42
43    public Expr getChild() {
44        return getChildren().get(0);
45    }
46
47    public Callable getGetter() {
48        if (mGetter == null) {
49            getResolvedType();
50        }
51        return mGetter;
52    }
53
54    @Override
55    public boolean isDynamic() {
56        if (!getChild().isDynamic()) {
57            return false;
58        }
59        if (mGetter == null) {
60            getResolvedType();
61        }
62        // maybe this is just a final field in which case cannot be notified as changed
63        return mGetter.type != Callable.Type.FIELD || mGetter.isDynamic;
64    }
65
66    @Override
67    protected List<Dependency> constructDependencies() {
68        final List<Dependency> dependencies = constructDynamicChildrenDependencies();
69        for (Dependency dependency : dependencies) {
70            if (dependency.getOther() == getChild()) {
71                dependency.setMandatory(true);
72            }
73        }
74        return dependencies;
75    }
76
77    @Override
78    protected String computeUniqueKey() {
79        if (mIsObservableField) {
80            return sUniqueKeyJoiner.join(mName, "..", super.computeUniqueKey());
81        }
82        return sUniqueKeyJoiner.join(mName, ".", super.computeUniqueKey());
83    }
84
85    public String getName() {
86        return mName;
87    }
88
89    @Override
90    public void updateExpr(ModelAnalyzer modelAnalyzer) {
91        resolveType(modelAnalyzer);
92        super.updateExpr(modelAnalyzer);
93    }
94
95    @Override
96    protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) {
97        if (mGetter == null) {
98            Expr child = getChild();
99            child.resolveType(modelAnalyzer);
100            boolean isStatic = child instanceof StaticIdentifierExpr;
101            ModelClass resolvedType = child.getResolvedType();
102            L.d("resolving %s. Resolved type: %s", this, resolvedType);
103
104            mGetter = resolvedType.findGetterOrField(mName, isStatic);
105            if (mGetter.resolvedType.isObservableField()) {
106                // Make this the ".get()" and add an extra field access for the observable field
107                child.getParents().remove(this);
108                getChildren().remove(child);
109
110                FieldAccessExpr observableField = getModel().observableField(child, mName);
111                observableField.mGetter = mGetter;
112
113                getChildren().add(observableField);
114                observableField.getParents().add(this);
115                mGetter = mGetter.resolvedType.findGetterOrField("get", false);
116                mName = "";
117            }
118        }
119        return mGetter.resolvedType;
120    }
121
122    @Override
123    protected String asPackage() {
124        String parentPackage = getChild().asPackage();
125        return parentPackage == null ? null : parentPackage + "." + mName;
126    }
127}
128