/* * Copyright (C) 2014 Francis Galiegue <fgaliegue@gmail.com> * * 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.github.fge.grappa.transform; import com.google.common.collect.ImmutableMap; import org.objectweb.asm.Type; import com.github.fge.grappa.annotations.Cached; import com.github.fge.grappa.annotations.DontExtend; import com.github.fge.grappa.annotations.DontLabel; import com.github.fge.grappa.annotations.DontSkipActionsInPredicates; import com.github.fge.grappa.annotations.ExplicitActionsOnly; import com.github.fge.grappa.annotations.SkipActionsInPredicates; import com.github.fge.grappa.transform.base.RuleMethod; import java.lang.annotation.Annotation; import java.util.EnumSet; import java.util.Map; import java.util.Set; /** * Enumeration associating parser or rule annotations to their ASM descriptor * * @see Type#getDescriptor() */ public enum ParserAnnotation { CACHED(Cached.class), EXPLICIT_ACTIONS_ONLY(ExplicitActionsOnly.class), DONT_LABEL(DontLabel.class), DONT_EXTEND(DontExtend.class), DONT_SKIP_ACTIONS_IN_PREDICATES(DontSkipActionsInPredicates.class), SKIP_ACTIONS_IN_PREDICATES(SkipActionsInPredicates.class), ; /** * @see RuleMethod#moveFlagsTo(RuleMethod) */ private static final Set<ParserAnnotation> FLAGS_COPY = EnumSet.of(CACHED, DONT_LABEL); /** * @see RuleMethod#moveFlagsTo(RuleMethod) */ private static final Set<ParserAnnotation> FLAGS_CLEAR = EnumSet.of(CACHED); /** * @see RuleMethod#moveFlagsTo(RuleMethod) */ private static final Set<ParserAnnotation> FLAGS_SET = EnumSet.of(DONT_LABEL); private static final Map<String, ParserAnnotation> REVERSE_MAP; static { final ImmutableMap.Builder<String, ParserAnnotation> builder = ImmutableMap.builder(); for (final ParserAnnotation entry: values()) builder.put(entry.descriptor, entry); REVERSE_MAP = builder.build(); } private final String descriptor; ParserAnnotation(final Class<? extends Annotation> c) { descriptor = Type.getType(c).getDescriptor(); } /** * Record an enumeration value into a set if the descriptor is known * * @param set the set to record into * @param desc the descriptor * @return true if the descriptor is known */ public static boolean recordAnnotation(final Set<ParserAnnotation> set, final String desc) { final ParserAnnotation annotation = REVERSE_MAP.get(desc); if (annotation == null) return false; set.add(annotation); return true; } /** * @see RuleMethod#moveFlagsTo(RuleMethod) * * @param from set to move flags from * @param to set to move flags to */ public static void moveTo(final Set<ParserAnnotation> from, final Set<ParserAnnotation> to) { final Set<ParserAnnotation> transferred = EnumSet.copyOf(from); transferred.retainAll(FLAGS_COPY); to.addAll(transferred); from.addAll(FLAGS_SET); from.removeAll(FLAGS_CLEAR); } }