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 19731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyarimport android.databinding.tool.processing.Scope; 20fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.Callable; 21716ba89e7f459f49ea85070d4710c1d79d715298George Mountimport android.databinding.tool.reflection.Callable.Type; 22fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.ModelAnalyzer; 23fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.ModelClass; 24716ba89e7f459f49ea85070d4710c1d79d715298George Mountimport android.databinding.tool.reflection.ModelMethod; 25fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.util.L; 26d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 27716ba89e7f459f49ea85070d4710c1d79d715298George Mountimport java.util.ArrayList; 28d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarimport java.util.List; 29d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 30d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarpublic class FieldAccessExpr extends Expr { 31d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar String mName; 32e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mount Callable mGetter; 337920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount final boolean mIsObservableField; 34716ba89e7f459f49ea85070d4710c1d79d715298George Mount private List<ModelMethod> mListenerMethods; 35716ba89e7f459f49ea85070d4710c1d79d715298George Mount private List<ModelMethod> mCalledMethods; 36716ba89e7f459f49ea85070d4710c1d79d715298George Mount private List<ModelClass> mListenerTypes; 37716ba89e7f459f49ea85070d4710c1d79d715298George Mount private List<ModelMethod> mPotentialListeners; 38d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 39d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar FieldAccessExpr(Expr parent, String name) { 40d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar super(parent); 41d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar mName = name; 427920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount mIsObservableField = false; 437920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount } 447920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount 457920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount FieldAccessExpr(Expr parent, String name, boolean isObservableField) { 467920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount super(parent); 477920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount mName = name; 487920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount mIsObservableField = isObservableField; 49d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 50d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 51a70fed6415aa1e8bbbe929aee776402ac3b81c86George Mount public Expr getChild() { 527920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount return getChildren().get(0); 53d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 54d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 55e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mount public Callable getGetter() { 569e20571da789c7d50650513c38d5a333b11b9fd3Yigit Boyar if (mGetter == null) { 579e20571da789c7d50650513c38d5a333b11b9fd3Yigit Boyar getResolvedType(); 589e20571da789c7d50650513c38d5a333b11b9fd3Yigit Boyar } 59d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return mGetter; 60d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 61d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 62716ba89e7f459f49ea85070d4710c1d79d715298George Mount public List<ModelMethod> getListenerMethods() { 63716ba89e7f459f49ea85070d4710c1d79d715298George Mount return mListenerMethods; 64716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 65716ba89e7f459f49ea85070d4710c1d79d715298George Mount 66716ba89e7f459f49ea85070d4710c1d79d715298George Mount public List<ModelMethod> getCalledMethods() { 67716ba89e7f459f49ea85070d4710c1d79d715298George Mount return mCalledMethods; 68716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 69716ba89e7f459f49ea85070d4710c1d79d715298George Mount 70716ba89e7f459f49ea85070d4710c1d79d715298George Mount public List<ModelClass> getListenerTypes() { return mListenerTypes; } 71716ba89e7f459f49ea85070d4710c1d79d715298George Mount 72716ba89e7f459f49ea85070d4710c1d79d715298George Mount public boolean isListener() { 73716ba89e7f459f49ea85070d4710c1d79d715298George Mount return mListenerMethods != null && !mListenerMethods.isEmpty(); 74716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 75716ba89e7f459f49ea85070d4710c1d79d715298George Mount 76716ba89e7f459f49ea85070d4710c1d79d715298George Mount public int getMinApi() { 77716ba89e7f459f49ea85070d4710c1d79d715298George Mount if (isListener()) { 78716ba89e7f459f49ea85070d4710c1d79d715298George Mount int minApi = 1; 79716ba89e7f459f49ea85070d4710c1d79d715298George Mount for (ModelClass listener : mListenerTypes) { 80716ba89e7f459f49ea85070d4710c1d79d715298George Mount int listenerApi = listener.getMinApi(); 81716ba89e7f459f49ea85070d4710c1d79d715298George Mount minApi = Math.max(minApi, listenerApi); 82716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 83716ba89e7f459f49ea85070d4710c1d79d715298George Mount return minApi; 84716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 85716ba89e7f459f49ea85070d4710c1d79d715298George Mount return mGetter.getMinApi(); 86716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 87716ba89e7f459f49ea85070d4710c1d79d715298George Mount 88d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar @Override 89d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar public boolean isDynamic() { 90d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (mGetter == null) { 91d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar getResolvedType(); 92d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 93716ba89e7f459f49ea85070d4710c1d79d715298George Mount if (mGetter == null || mGetter.type == Type.METHOD) { 94716ba89e7f459f49ea85070d4710c1d79d715298George Mount return !isListener(); 95019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar } 96019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar // if it is static final, gone 97019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar if (getChild().isDynamic()) { 98019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar // if owner is dynamic, then we can be dynamic unless we are static final 99019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar return !mGetter.isStatic() || mGetter.isDynamic(); 100019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar } 101019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar 102019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar // if owner is NOT dynamic, we can be dynamic if an only if getter is dynamic 103019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar return mGetter.isDynamic(); 104d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 105d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 106c4a07bddb4dd5c3bfbecf4d87909c5b447ae56dcGeorge Mount public boolean hasBindableAnnotations() { 107c4a07bddb4dd5c3bfbecf4d87909c5b447ae56dcGeorge Mount return mGetter.canBeInvalidated(); 108c4a07bddb4dd5c3bfbecf4d87909c5b447ae56dcGeorge Mount } 109c4a07bddb4dd5c3bfbecf4d87909c5b447ae56dcGeorge Mount 110d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar @Override 111716ba89e7f459f49ea85070d4710c1d79d715298George Mount public boolean resolveListeners(ModelClass listener) { 112716ba89e7f459f49ea85070d4710c1d79d715298George Mount if (mPotentialListeners == null) { 113716ba89e7f459f49ea85070d4710c1d79d715298George Mount return false; 114716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 115716ba89e7f459f49ea85070d4710c1d79d715298George Mount 116716ba89e7f459f49ea85070d4710c1d79d715298George Mount List<ModelMethod> abstractMethods = listener.getAbstractMethods(); 117716ba89e7f459f49ea85070d4710c1d79d715298George Mount int numberOfAbstractMethods = abstractMethods == null ? 0 : abstractMethods.size(); 118716ba89e7f459f49ea85070d4710c1d79d715298George Mount if (numberOfAbstractMethods != 1) { 119716ba89e7f459f49ea85070d4710c1d79d715298George Mount if (mGetter == null) { 120716ba89e7f459f49ea85070d4710c1d79d715298George Mount L.e("Could not find accessor %s.%s and %s has %d abstract methods, so is" + 121716ba89e7f459f49ea85070d4710c1d79d715298George Mount " not resolved as a listener", 122716ba89e7f459f49ea85070d4710c1d79d715298George Mount getChild().getResolvedType().getCanonicalName(), mName, 123716ba89e7f459f49ea85070d4710c1d79d715298George Mount listener.getCanonicalName(), numberOfAbstractMethods); 124716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 125716ba89e7f459f49ea85070d4710c1d79d715298George Mount return false; 126716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 127716ba89e7f459f49ea85070d4710c1d79d715298George Mount 128716ba89e7f459f49ea85070d4710c1d79d715298George Mount // See if we've already resolved this listener type 129716ba89e7f459f49ea85070d4710c1d79d715298George Mount if (mListenerMethods == null) { 130716ba89e7f459f49ea85070d4710c1d79d715298George Mount mListenerMethods = new ArrayList<ModelMethod>(); 131716ba89e7f459f49ea85070d4710c1d79d715298George Mount mCalledMethods = new ArrayList<ModelMethod>(); 132716ba89e7f459f49ea85070d4710c1d79d715298George Mount mListenerTypes = new ArrayList<ModelClass>(); 133716ba89e7f459f49ea85070d4710c1d79d715298George Mount } else { 134716ba89e7f459f49ea85070d4710c1d79d715298George Mount for (ModelClass previousListeners : mListenerTypes) { 135716ba89e7f459f49ea85070d4710c1d79d715298George Mount if (previousListeners.equals(listener)) { 136716ba89e7f459f49ea85070d4710c1d79d715298George Mount return false; 137716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 138716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 139716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 140716ba89e7f459f49ea85070d4710c1d79d715298George Mount 141716ba89e7f459f49ea85070d4710c1d79d715298George Mount // Look for a signature matching the abstract method 142716ba89e7f459f49ea85070d4710c1d79d715298George Mount final ModelMethod listenerMethod = abstractMethods.get(0); 143716ba89e7f459f49ea85070d4710c1d79d715298George Mount final ModelClass[] listenerParameters = listenerMethod.getParameterTypes(); 144716ba89e7f459f49ea85070d4710c1d79d715298George Mount for (ModelMethod method : mPotentialListeners) { 145716ba89e7f459f49ea85070d4710c1d79d715298George Mount if (acceptsParameters(method, listenerParameters)) { 146716ba89e7f459f49ea85070d4710c1d79d715298George Mount mListenerTypes.add(listener); 147716ba89e7f459f49ea85070d4710c1d79d715298George Mount mListenerMethods.add(listenerMethod); 148716ba89e7f459f49ea85070d4710c1d79d715298George Mount mCalledMethods.add(method); 149716ba89e7f459f49ea85070d4710c1d79d715298George Mount resetResolvedType(); 150716ba89e7f459f49ea85070d4710c1d79d715298George Mount return true; 151716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 152716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 153716ba89e7f459f49ea85070d4710c1d79d715298George Mount 154716ba89e7f459f49ea85070d4710c1d79d715298George Mount if (mGetter == null) { 155716ba89e7f459f49ea85070d4710c1d79d715298George Mount L.e("Listener class %s with method %s did not match signature of any method %s.%s", 156716ba89e7f459f49ea85070d4710c1d79d715298George Mount listener.getCanonicalName(), listenerMethod.getName(), 157716ba89e7f459f49ea85070d4710c1d79d715298George Mount getChild().getResolvedType().getCanonicalName(), mName); 158716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 159716ba89e7f459f49ea85070d4710c1d79d715298George Mount return false; 160716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 161716ba89e7f459f49ea85070d4710c1d79d715298George Mount 162716ba89e7f459f49ea85070d4710c1d79d715298George Mount private boolean acceptsParameters(ModelMethod method, ModelClass[] listenerParameters) { 163716ba89e7f459f49ea85070d4710c1d79d715298George Mount ModelClass[] parameters = method.getParameterTypes(); 164716ba89e7f459f49ea85070d4710c1d79d715298George Mount if (parameters.length != listenerParameters.length) { 165716ba89e7f459f49ea85070d4710c1d79d715298George Mount return false; 166716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 167716ba89e7f459f49ea85070d4710c1d79d715298George Mount for (int i = 0; i < parameters.length; i++) { 168716ba89e7f459f49ea85070d4710c1d79d715298George Mount if (!parameters[i].isAssignableFrom(listenerParameters[i])) { 169716ba89e7f459f49ea85070d4710c1d79d715298George Mount return false; 170716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 171716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 172716ba89e7f459f49ea85070d4710c1d79d715298George Mount return true; 173716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 174716ba89e7f459f49ea85070d4710c1d79d715298George Mount 175716ba89e7f459f49ea85070d4710c1d79d715298George Mount @Override 176dc69f49d687ec036947f26a9bf9025a305de0721Yigit Boyar protected List<Dependency> constructDependencies() { 177dc69f49d687ec036947f26a9bf9025a305de0721Yigit Boyar final List<Dependency> dependencies = constructDynamicChildrenDependencies(); 178dc69f49d687ec036947f26a9bf9025a305de0721Yigit Boyar for (Dependency dependency : dependencies) { 179a70fed6415aa1e8bbbe929aee776402ac3b81c86George Mount if (dependency.getOther() == getChild()) { 180dc69f49d687ec036947f26a9bf9025a305de0721Yigit Boyar dependency.setMandatory(true); 181dc69f49d687ec036947f26a9bf9025a305de0721Yigit Boyar } 182dc69f49d687ec036947f26a9bf9025a305de0721Yigit Boyar } 183dc69f49d687ec036947f26a9bf9025a305de0721Yigit Boyar return dependencies; 184dc69f49d687ec036947f26a9bf9025a305de0721Yigit Boyar } 185dc69f49d687ec036947f26a9bf9025a305de0721Yigit Boyar 186dc69f49d687ec036947f26a9bf9025a305de0721Yigit Boyar @Override 187d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar protected String computeUniqueKey() { 1887920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount if (mIsObservableField) { 1892611838bffef5a009ca71e3e9e59a93f29b098edYigit Boyar return join(mName, "..", super.computeUniqueKey()); 1907920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount } 1912611838bffef5a009ca71e3e9e59a93f29b098edYigit Boyar return join(mName, ".", super.computeUniqueKey()); 192d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 193d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 194d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar public String getName() { 195d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return mName; 196d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 197d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 198d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar @Override 19979fc7f3727815ab35bb1bb2e060bfb7db3176eedGeorge Mount public void updateExpr(ModelAnalyzer modelAnalyzer) { 200731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar try { 201731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar Scope.enter(this); 202731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar resolveType(modelAnalyzer); 203731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar super.updateExpr(modelAnalyzer); 204731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar } finally { 205731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar Scope.exit(); 206731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar } 20718243f6f1b7527272ef4feccdf4327d80d9f2241George Mount } 20818243f6f1b7527272ef4feccdf4327d80d9f2241George Mount 20918243f6f1b7527272ef4feccdf4327d80d9f2241George Mount @Override 21018243f6f1b7527272ef4feccdf4327d80d9f2241George Mount protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) { 2117920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount if (mGetter == null) { 212716ba89e7f459f49ea85070d4710c1d79d715298George Mount if (mPotentialListeners != null) { 213716ba89e7f459f49ea85070d4710c1d79d715298George Mount return modelAnalyzer.findClass(Object.class); 214716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 215a70fed6415aa1e8bbbe929aee776402ac3b81c86George Mount Expr child = getChild(); 216731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar child.getResolvedType(); 217a70fed6415aa1e8bbbe929aee776402ac3b81c86George Mount boolean isStatic = child instanceof StaticIdentifierExpr; 218f9e51c010bd2eab9cca01baaccc0e5a73b8b72c9Yigit Boyar ModelClass resolvedType = child.getResolvedType(); 219e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar L.d("resolving %s. Resolved class type: %s", this, resolvedType); 220f9e51c010bd2eab9cca01baaccc0e5a73b8b72c9Yigit Boyar 221fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount mGetter = resolvedType.findGetterOrField(mName, isStatic); 222716ba89e7f459f49ea85070d4710c1d79d715298George Mount mPotentialListeners = resolvedType.findMethods(mName, isStatic); 223716ba89e7f459f49ea85070d4710c1d79d715298George Mount 224716ba89e7f459f49ea85070d4710c1d79d715298George Mount if (mGetter == null) { 225716ba89e7f459f49ea85070d4710c1d79d715298George Mount if (mPotentialListeners == null) { 226716ba89e7f459f49ea85070d4710c1d79d715298George Mount L.e("Could not find accessor %s.%s", resolvedType.getCanonicalName(), mName); 227716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 228716ba89e7f459f49ea85070d4710c1d79d715298George Mount return modelAnalyzer.findClass(Object.class); 229716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 230ec2f3896c21a504b464bf591cdb45b62692b6760Yigit Boyar 231ec2f3896c21a504b464bf591cdb45b62692b6760Yigit Boyar if (mGetter.isStatic() && !isStatic) { 232ec2f3896c21a504b464bf591cdb45b62692b6760Yigit Boyar // found a static method on an instance. register a new one 233ec2f3896c21a504b464bf591cdb45b62692b6760Yigit Boyar child.getParents().remove(this); 234ec2f3896c21a504b464bf591cdb45b62692b6760Yigit Boyar getChildren().remove(child); 235ec2f3896c21a504b464bf591cdb45b62692b6760Yigit Boyar StaticIdentifierExpr staticId = getModel().staticIdentifierFor(resolvedType); 236ec2f3896c21a504b464bf591cdb45b62692b6760Yigit Boyar getChildren().add(staticId); 237ec2f3896c21a504b464bf591cdb45b62692b6760Yigit Boyar staticId.getParents().add(this); 238ec2f3896c21a504b464bf591cdb45b62692b6760Yigit Boyar child = getChild(); // replace the child for the next if stmt 239ec2f3896c21a504b464bf591cdb45b62692b6760Yigit Boyar } 240ec2f3896c21a504b464bf591cdb45b62692b6760Yigit Boyar 241fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount if (mGetter.resolvedType.isObservableField()) { 2427920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount // Make this the ".get()" and add an extra field access for the observable field 243a70fed6415aa1e8bbbe929aee776402ac3b81c86George Mount child.getParents().remove(this); 244a70fed6415aa1e8bbbe929aee776402ac3b81c86George Mount getChildren().remove(child); 2457920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount 246a70fed6415aa1e8bbbe929aee776402ac3b81c86George Mount FieldAccessExpr observableField = getModel().observableField(child, mName); 2477920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount observableField.mGetter = mGetter; 2487920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount 2497920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount getChildren().add(observableField); 2507920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount observableField.getParents().add(this); 251fa9fe12980ef1103fabe33bf5ff0e2f53042a204George Mount mGetter = mGetter.resolvedType.findGetterOrField("get", false); 2527920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount mName = ""; 2537920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount } 2547920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount } 255716ba89e7f459f49ea85070d4710c1d79d715298George Mount if (isListener()) { 256716ba89e7f459f49ea85070d4710c1d79d715298George Mount return modelAnalyzer.findClass(Object.class); 257716ba89e7f459f49ea85070d4710c1d79d715298George Mount } 25818243f6f1b7527272ef4feccdf4327d80d9f2241George Mount return mGetter.resolvedType; 2597920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount } 2607920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount 2617920e17f7b501d5792e7e3250e9dbb69eca86adeGeorge Mount @Override 26218243f6f1b7527272ef4feccdf4327d80d9f2241George Mount protected String asPackage() { 263a70fed6415aa1e8bbbe929aee776402ac3b81c86George Mount String parentPackage = getChild().asPackage(); 26418243f6f1b7527272ef4feccdf4327d80d9f2241George Mount return parentPackage == null ? null : parentPackage + "." + mName; 265d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 266d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 267