/** * Copyright (c) 2012-2016 André Bargull * Alle Rechte vorbehalten / All Rights Reserved. Use is subject to license terms. * * <https://github.com/anba/es6draft> */ package com.github.anba.es6draft.compiler; import com.github.anba.es6draft.compiler.assembler.Stack; import com.github.anba.es6draft.compiler.assembler.Type; import com.github.anba.es6draft.compiler.assembler.Variables; /** * Application specific override of {@link Stack}. */ final class StackImpl extends Stack { public StackImpl(Variables variables) { super(variables); } @Override protected Type intersectionType(Type left, Type right) { // Hard coded type relationships to avoid dynamic class loading. // TODO: Change to a less brittle approach. Type commonType = Types.Object; if (isCharSequence(left)) { if (isCharSequence(right)) { commonType = Types.CharSequence; } } else if (isNumber(left)) { if (isNumber(right)) { commonType = Types.Number; } } else if (isFunctionObject(left)) { if (isFunctionObject(right)) { commonType = Types.FunctionObject; } else if (isOrdinaryObject(right)) { commonType = Types.OrdinaryObject; } else if (isScriptObject(right)) { commonType = Types.ScriptObject; } else if (isCallable(right) || isConstructor(right)) { commonType = Types.Callable; } } else if (isOrdinaryObject(left)) { if (isFunctionObject(right) || isOrdinaryObject(right)) { commonType = Types.OrdinaryObject; } else if (isScriptObject(right) || isCallable(right) || isConstructor(right)) { commonType = Types.ScriptObject; } } else if (isScriptObject(left)) { if (isFunctionObject(right) || isOrdinaryObject(right) || isScriptObject(right) || isCallable(right) || isConstructor(right)) { commonType = Types.ScriptObject; } } else if (isCallable(left)) { if (isFunctionObject(right) || isCallable(right) || isConstructor(right)) { commonType = Types.Callable; } else if (isOrdinaryObject(right) || isScriptObject(right)) { commonType = Types.ScriptObject; } } else if (isConstructor(left)) { if (isConstructor(right)) { commonType = Types.Constructor; } else if (isFunctionObject(right) || isCallable(right)) { commonType = Types.Callable; } else if (isOrdinaryObject(right) || isScriptObject(right)) { commonType = Types.ScriptObject; } } return commonType; } private static boolean isCharSequence(Type type) { return Types.String.equals(type) || Types.CharSequence.equals(type); } private static boolean isNumber(Type type) { return Types.Integer.equals(type) || Types.Long.equals(type) || Types.Double.equals(type); } private static boolean isFunctionObject(Type type) { return Types.OrdinaryFunction.equals(type) || Types.OrdinaryConstructorFunction.equals(type) || Types.OrdinaryGenerator.equals(type) || Types.OrdinaryConstructorGenerator.equals(type) || Types.OrdinaryAsyncFunction.equals(type) || Types.LegacyConstructorFunction.equals(type) || Types.FunctionObject.equals(type); } private static boolean isOrdinaryObject(Type type) { return Types.OrdinaryObject.equals(type) || Types.ArrayObject.equals(type) || Types.ArgumentsObject.equals(type) || Types.RegExpObject.equals(type) || Types.GeneratorObject.equals(type) || Types.AsyncGeneratorObject.equals(type) || Types.ModuleNamespaceObject.equals(type); } private static boolean isConstructor(Type type) { return Types.Constructor.equals(type); } private static boolean isCallable(Type type) { return Types.Callable.equals(type); } private static boolean isScriptObject(Type type) { return Types.ScriptObject.equals(type); } }