1 /* 2 * Copyright the original author or authors. 3 * 4 * Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (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.mozilla.org/MPL/MPL-1.1.html 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 17 import org.as2lib.core.BasicClass; 18 19 /** 20 * {@code ClassUtil} contains fundamental operations to efficiently and easily 21 * work with any class. All methods here are supposed to be used with functions 22 * treated as classes. 23 * 24 * @author Martin Heidegger 25 * @author Simon Wacker 26 */ 27 class org.as2lib.util.ClassUtil extends BasicClass { 28 29 /** 30 * Checks if the passed-in {@code subClass} is extended by the passed-in 31 * {@code superClass}. 32 * 33 * @param subClass the class to check 34 * @param superClass the class to match 35 * @return {@code true} if {@code subClass} is a sub-class of {@code superClass} 36 */ 37 public static function isSubClassOf(subClass:Function, superClass:Function):Boolean { 38 var base:Object = subClass.prototype; 39 // A superclass has to be in the prototype chain 40 while(base !== undefined) { 41 base = base.__proto__; 42 if(base === superClass.prototype) { 43 return true; 44 } 45 } 46 return false; 47 } 48 49 /** 50 * Checks if the passed-in {@code clazz} implements the passed-in {@code 51 * interfaze}. 52 * 53 * @param clazz the class to check 54 * @param interfaze the interface the {@code clazz} may implement 55 * @return {@code true} if the passed-in {@code clazz} implements the passed-in 56 * {@code interfaze} else {@code false} 57 */ 58 public static function isImplementationOf(clazz:Function, interfaze:Function):Boolean { 59 // A interface must not be in the prototype chain. 60 if (isSubClassOf(clazz, interfaze)) { 61 return false; 62 } 63 // If it's an interface then it must not be extended but the class has 64 // to be an instance of it 65 return (createCleanInstance(clazz) instanceof interfaze); 66 } 67 68 /** 69 * Creates a new instance of the passed-in {@code clazz} without invoking its 70 * constructor. 71 * 72 * @param clazz the class to create a new instance of 73 * @return new instance of the passed-in class. 74 * @author Martin Heidegger 75 * @author Ralf Bokelberg (www.qlod.com) 76 */ 77 public static function createCleanInstance(clazz:Function):Object { 78 var result:Object = new Object(); 79 result.__proto__ = clazz.prototype; 80 result.__constructor__ = clazz; 81 return result; 82 } 83 84 /** 85 * Creates a new instance of the passed-in {@code clazz} applying the 86 * passed-in {@code args} to the constructor. 87 * 88 * <p>This util is mostly made for MTASC compatibility because it doesn't 89 * allow {@code new clazz()} for usual variables. 90 * 91 * @param clazz Class to be instanciated 92 * @param args Arguments to be applied to the constructor 93 * @return new instance of the class 94 */ 95 public static function createInstance(clazz:Function, args:Array) { 96 if (!clazz) return null; 97 var result:Object = new Object(); 98 result.__proto__ = clazz.prototype; 99 result.__constructor__ = clazz; 100 clazz.apply(result, args); 101 return result; 102 } 103 }