/* * Copyright 2014 the original author or authors. * * 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.koloboke.jpsg.collect; import com.koloboke.jpsg.*; public final class MethodContext { private static final SimpleOption IMMUTABLE = new SimpleOption("Immutable"); private static final SimpleOption UPDATABLE = new SimpleOption("Updatable"); private static final SimpleOption MUTABLE = new SimpleOption("Mutable"); private static final SimpleOption NULL = new SimpleOption("null"); private static final SimpleOption TRUE = new SimpleOption("true"); private static final SimpleOption KEY_VIEW = new SimpleOption("key"); private static final SimpleOption VALUE_VIEW = new SimpleOption("value"); private static final SimpleOption MAP_VIEW = new SimpleOption("map"); private static final SimpleOption ENTRY_VIEW = new SimpleOption("entry"); private static final SimpleOption GENERIC = new SimpleOption("generic"); private static final SimpleOption INTERNAL = new SimpleOption("internal"); private final SimpleOption view; private final Context context; public MethodContext(Context context) { this.context = context; Option vt = context.getOption("view"); if (KEY_VIEW.equals(vt)) view = KEY_VIEW; else if (VALUE_VIEW.equals(vt)) view = VALUE_VIEW; else if (MAP_VIEW.equals(vt)) view = MAP_VIEW; else if (ENTRY_VIEW.equals(vt)) view = ENTRY_VIEW; else { if (context.getOption("value") != null) { view = MAP_VIEW; } else { view = KEY_VIEW; } } } private String keyDim() { return context.getOption("elem") != null ? "elem" : "key"; } public Option keyOption() { return getOption(keyDim()); } public boolean isIntegralKey() { Option key = keyOption(); return isPrimitiveKey() && !(key == PrimitiveType.FLOAT) && !(key == PrimitiveType.DOUBLE); } public boolean isFloatingKey() { return isPrimitiveKey() && !isIntegralKey(); } public boolean isObjectKey() { return keyOption() instanceof ObjectType; } public boolean isNullKey() { return NULL.equals(keyOption()); } public boolean isObjectOrNullKey() { return isObjectKey() || isNullKey(); } public boolean isPrimitiveKey() { return keyOption() instanceof PrimitiveType; } public boolean isObjectValue() { return mapValueOption() instanceof ObjectType; } public boolean isPrimitiveValue() { return mapValueOption() instanceof PrimitiveType; } public boolean isFloatingValue() { Option opt = mapValueOption(); return opt == PrimitiveType.FLOAT || opt == PrimitiveType.DOUBLE; } public boolean isNullValue() { return NULL.equals(mapValueOption()); } public final Option viewOption() { if (isKeyView()) return keyOption(); if (isValueView()) return mapValueOption(); throw new IllegalStateException(); } /** @return K or char..long, floating bits */ public String keyUnwrappedType() { if (isObjectKey() || isNullKey()) { return ObjectType.genericParamName(keyDim()); } else if (isPrimitiveKey()) { return primitiveBitsType(keyOption()); } else { throw new IllegalStateException(); } } /** @return K or char..double */ public String keyType() { if (isObjectKey() || isNullKey()) { return ObjectType.genericParamName(keyDim()); } else if (isPrimitiveKey()) { return ((PrimitiveType) keyOption()).standalone; } else { throw new IllegalStateException(); } } /** @return Object or char..long, floating bits */ public String keyUnwrappedRawType() { if (!isPrimitiveKey()) { return "Object"; } else { return primitiveBitsType(keyOption()); } } /** @return V or char..long, floating bits */ public String valueUnwrappedType() { if (isPrimitiveValue()) { return primitiveBitsType(mapValueOption()); } else { return "V"; } } /** @return V or char..double */ public String valueType() { if (isPrimitiveValue()) { return ((PrimitiveType) mapValueOption()).standalone; } else { return "V"; } } private String primitiveBitsType(Option opt) { PrimitiveType type = (PrimitiveType) opt; return type.bitsType().standalone; } /** @return V or char..double if version=Generic, else Character..Double */ public String valueGenericType() { if (isPrimitiveValue()) { PrimitiveType valType = (PrimitiveType) mapValueOption(); if (genericVersion()) { return valType.className; } else { return valType.standalone; } } else { return "V"; } } public String applyValueName() { String methodName = "apply"; if (mapValueOption() instanceof PrimitiveType && !genericVersion()) { methodName += "As" + ((PrimitiveType) mapValueOption()).title; } return methodName; } public final boolean isKeyView() { return view == KEY_VIEW; } public final boolean isValueView() { return view == VALUE_VIEW; } public final boolean isEntryView() { return view == ENTRY_VIEW; } public final boolean isMapView() { return view == MAP_VIEW; } public final boolean isPrimitiveView() { return (isKeyView() && !isObjectKey()) || (isValueView() && !isObjectValue()); } public final boolean isFloatingView() { return (isKeyView() && isFloatingKey()) || (isValueView() && isFloatingValue()); } public final boolean isObjectView() { return (isKeyView() && isObjectKey()) || (isValueView() && isObjectValue()); } public Option mapValueOption() { return getOption("value"); } public boolean hasValues() { return mapValueOption() != null; } public Option getOption(String dim) { return context.getOption(dim); } public boolean immutable() { return getOption("mutability").equals(IMMUTABLE); } public boolean updatable() { return getOption("mutability").equals(UPDATABLE); } public boolean mutable() { return getOption("mutability").equals(MUTABLE); } public boolean genericVersion() { return GENERIC.equals(getOption("version")); } public boolean internalVersion() { return INTERNAL.equals(getOption("version")); } public boolean nullKeyAllowed() { return TRUE.equals(getOption("nullKeyAllowed")); } public boolean delayedRemoved() { return TRUE.equals(getOption("delayedRemoved")); } public boolean concurrentModificationChecked() { Option concurrentModificationChecked = getOption("concurrentModificationChecked"); if (concurrentModificationChecked == null) { throw new IllegalStateException( "concurrentModificationChecked should be present in the context"); } return TRUE.equals(concurrentModificationChecked); } public String unsafeGetKeyBits(String object, String offset) { return unsafeGet(object, offset, ((PrimitiveType) keyOption()).bitsType()); } public void unsafePutKeyBits(MethodGenerator g, String object, String offset, String key) { g.lines(unsafePut(object, offset, key, ((PrimitiveType) keyOption()).bitsType()) + ";"); } public String unsafeGetValueBits(String object, String offset) { return unsafeGet(object, offset, ((PrimitiveType) mapValueOption()).bitsType()); } public void unsafePutValueBits(MethodGenerator g, String object, String offset, String value) { g.lines(unsafePut(object, offset, value, ((PrimitiveType) mapValueOption()).bitsType()) + ";"); } private String unsafeGet(String object, String offset, PrimitiveType type) { return "U.get" + type.title + "(" + object + ", " + offset + ")"; } private String unsafePut(String object, String offset, String value, PrimitiveType type) { return "U.put" + type.title + "(" + object + ", " + offset + ", " + value +")"; } }