Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 371450b5 authored by George Mount's avatar George Mount
Browse files

Support casting operation in binding expressions.

Bug 19272385

Change-Id: I5a992f4eaf6f456d21983481ab4ca01305582f36
parent 812d215f
Loading
Loading
Loading
Loading
+62 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.databinding.testapp;

import com.android.databinding.testapp.generated.CastTestBinder;

import android.support.v4.util.ArrayMap;
import android.test.UiThreadTest;

import java.util.ArrayList;

public class CastTest extends BaseDataBinderTest<CastTestBinder> {
    ArrayList<String> mValues = new ArrayList<>();
    ArrayMap<String, String> mMap = new ArrayMap<>();

    public CastTest() {
        super(CastTestBinder.class, R.layout.cast_test);
    }

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        try {
            runTestOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mValues.clear();
                    mValues.add("hello");
                    mValues.add("world");
                    mValues.add("not seen");
                    mMap.clear();
                    mMap.put("hello", "world");
                    mMap.put("world", "hello");
                    mBinder.setList(mValues);
                    mBinder.setMap(mMap);
                    mBinder.rebindDirty();
                }
            });
        } catch (Throwable throwable) {
            throw new Exception(throwable);
        }
    }

    @UiThreadTest
    public void testCast() throws Throwable {
        assertEquals("hello", mBinder.getTextView0().getText().toString());
        assertEquals("world", mBinder.getTextView1().getText().toString());
    }
}
+17 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
    <variable name="list" type="java.util.Collection&lt;java.lang.String&gt;"/>
    <variable name="map" type="java.lang.Object"/>

    <TextView
            android:id="@+id/textView0"
            android:layout_width="wrap_content" android:layout_height="wrap_content"
            android:text="@{((java.util.ArrayList&lt;java.lang.String&gt;)list)[0]}"/>
    <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content" android:layout_height="wrap_content"
            android:text="@{((java.util.Map&lt;java.lang.String,java.lang.String&gt;)map)[`hello`]}"/>
</LinearLayout>
 No newline at end of file
+19 −16
Original line number Diff line number Diff line
@@ -2,6 +2,8 @@ package com.android.databinding.annotationprocessor;

import com.android.databinding.reflection.ModelAnalyzer;

import org.apache.commons.io.IOUtils;

import android.binding.Bindable;

import java.io.File;
@@ -216,10 +218,12 @@ public class ProcessBindable extends AbstractProcessor {
                properties = (Intermediate) in.readObject();
            }
        } catch (IOException e) {
            System.err.println("Could not read Binding properties intermediate file: " +
            processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
                    "Could not read Binding properties intermediate file: " +
                    e.getLocalizedMessage());
        } catch (ClassNotFoundException e) {
            System.err.println("Could not read Binding properties intermediate file: " +
            processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
                    "Could not read Binding properties intermediate file: " +
                            e.getLocalizedMessage());
        } finally {
            try {
@@ -244,7 +248,8 @@ public class ProcessBindable extends AbstractProcessor {
                    .getResources(resourcePath);
            while (resources.hasMoreElements()) {
                URL url = resources.nextElement();
                System.out.println("Merging binding adapters from " + url);
                processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE,
                        "Merging binding adapters from " + url);
                InputStream inputStream = null;
                try {
                    inputStream = url.openStream();
@@ -254,22 +259,20 @@ public class ProcessBindable extends AbstractProcessor {
                        properties.captureProperties(intermediateProperties);
                    }
                } catch (IOException e) {
                    System.err.println("Could not merge in Bindables from " + url + ": " +
                    processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
                            "Could not merge in Bindables from " + url + ": " +
                                    e.getLocalizedMessage());
                } catch (ClassNotFoundException e) {
                    System.err.println("Could not read Binding properties intermediate file: " +
                    processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
                            "Could not read Binding properties intermediate file: " +
                                    e.getLocalizedMessage());
                } finally {
                    try {
                        inputStream.close();
                    } catch (IOException e2) {
                        System.err.println("Error closing intermediate Bindables store: " +
                                e2.getLocalizedMessage());
                    }
                    IOUtils.closeQuietly(inputStream);
                }
            }
        } catch (IOException e) {
            System.err.println("Could not read Binding properties intermediate file: " +
            processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
                    "Could not read Binding properties intermediate file: " +
                            e.getLocalizedMessage());
        }
    }
+5 −0
Original line number Diff line number Diff line
@@ -159,6 +159,11 @@ public class ExpressionVisitor extends BindingExpressionBaseVisitor<Expr> {
        return mModel.bracketExpr(visit(ctx.expression(0)), visit(ctx.expression(1)));
    }

    @Override
    public Expr visitCastOp(@NotNull BindingExpressionParser.CastOpContext ctx) {
        return mModel.castExpr(ctx.type().getText(), visit(ctx.expression()));
    }

    //    @Override
//    public Expr visitIdentifier(@NotNull BindingExpressionParser.IdentifierContext ctx) {
//        final String identifier = ctx.Identifier().getText();
+58 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.databinding.expr;

import com.android.databinding.reflection.ModelAnalyzer;
import com.android.databinding.reflection.ModelClass;

import java.util.List;

public class CastExpr extends Expr {

    final String mType;

    CastExpr(String type, Expr expr) {
        super(expr);
        mType = type;
    }

    @Override
    protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) {
        return modelAnalyzer.findClass(mType);
    }

    @Override
    protected List<Dependency> constructDependencies() {
        final List<Dependency> dependencies = constructDynamicChildrenDependencies();
        for (Dependency dependency : dependencies) {
            dependency.setMandatory(true);
        }
        return dependencies;
    }

    protected String computeUniqueKey() {
        return sUniqueKeyJoiner.join(mType, getCastExpr().computeUniqueKey());
    }

    public Expr getCastExpr() {
        return getChildren().get(0);
    }

    public String getCastType() {
        return mType;
    }
}
Loading