1081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson/*
2081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson * Copyright (C) 2011 The Android Open Source Project
3081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson *
4081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson * Licensed under the Apache License, Version 2.0 (the "License");
5081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson * you may not use this file except in compliance with the License.
6081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson * You may obtain a copy of the License at
7081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson *
8081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson *      http://www.apache.org/licenses/LICENSE-2.0
9081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson *
10081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson * Unless required by applicable law or agreed to in writing, software
11081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
12081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson * See the License for the specific language governing permissions and
14081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson * limitations under the License.
15081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson */
16081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson
17081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilsonpackage com.android.dx.merge;
18081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson
19fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport com.android.dex.ClassDef;
20fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport com.android.dex.Dex;
21081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilsonimport java.util.Comparator;
22081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson
23081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson/**
24081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson * Name and structure of a type. Used to order types such that each type is
25081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson * preceded by its supertype and implemented interfaces.
26081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson */
27dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilsonfinal class SortableType {
28081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson    public static final Comparator<SortableType> NULLS_LAST_ORDER = new Comparator<SortableType>() {
29081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson        public int compare(SortableType a, SortableType b) {
30081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson            if (a == b) {
31081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson                return 0;
32081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson            }
33081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson            if (b == null) {
34081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson                return -1;
35081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson            }
36081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson            if (a == null) {
37081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson                return 1;
38081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson            }
39081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson            if (a.depth != b.depth) {
40081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson                return a.depth - b.depth;
41081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson            }
42dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson            return a.getTypeIndex() - b.getTypeIndex();
43081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson        }
44081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson    };
45081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson
46fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilson    private final Dex dex;
47dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson    private ClassDef classDef;
48081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson    private int depth = -1;
49081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson
50fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilson    public SortableType(Dex dex, ClassDef classDef) {
51fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilson        this.dex = dex;
52dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson        this.classDef = classDef;
53081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson    }
54081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson
55fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilson    public Dex getDex() {
56fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilson        return dex;
57081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson    }
58081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson
59dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson    public ClassDef getClassDef() {
60dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson        return classDef;
61081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson    }
62081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson
63dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson    public int getTypeIndex() {
64dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson        return classDef.getTypeIndex();
65081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson    }
66081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson
67081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson    /**
68081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson     * Assigns this type's depth if the depths of its supertype and implemented
69081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson     * interfaces are known. Returns false if the depth couldn't be computed
70081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson     * yet.
71081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson     */
72081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson    public boolean tryAssignDepth(SortableType[] types) {
73081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson        int max;
74dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson        if (classDef.getSupertypeIndex() == ClassDef.NO_INDEX) {
75081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson            max = 0; // this is Object.class or an interface
76081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson        } else {
77dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson            SortableType sortableSupertype = types[classDef.getSupertypeIndex()];
78081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson            if (sortableSupertype == null) {
79081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson                max = 1; // unknown, so assume it's a root.
80081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson            } else if (sortableSupertype.depth == -1) {
81081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson                return false;
82081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson            } else {
83081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson                max = sortableSupertype.depth;
84081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson            }
85081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson        }
86081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson
87dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson        for (short interfaceIndex : classDef.getInterfaces()) {
88081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson            SortableType implemented = types[interfaceIndex];
89081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson            if (implemented == null) {
90081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson                max = Math.max(max, 1); // unknown, so assume it's a root.
91081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson            } else if (implemented.depth == -1) {
92081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson                return false;
93081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson            } else {
94081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson                max = Math.max(max, implemented.depth);
95081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson            }
96081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson        }
97081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson
98081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson        depth = max + 1;
99081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson        return true;
100081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson    }
101081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson
102081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson    public boolean isDepthAssigned() {
103081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson        return depth != -1;
104081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson    }
105081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson}
106