/* * Copyright (c) 2012, the Dart project authors. * * Licensed under the Eclipse Public License v1.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.eclipse.org/legal/epl-v10.html * * 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.google.dart.engine.internal.scope; import com.google.dart.engine.ast.SimpleIdentifier; import com.google.dart.engine.element.LabelElement; import com.google.dart.engine.internal.element.LabelElementImpl; import com.google.dart.engine.scanner.StringToken; import com.google.dart.engine.scanner.TokenType; /** * Instances of the class {@code LabelScope} represent a scope in which a single label is defined. * * @coverage dart.engine.resolver */ public class LabelScope { /** * The label scope enclosing this label scope. */ private LabelScope outerScope; /** * The label defined in this scope. */ private String label; /** * The element to which the label resolves. */ private LabelElement element; /** * The marker used to look up a label element for an unlabeled {@code break} or {@code continue}. */ public static final String EMPTY_LABEL = ""; /** * The label element returned for scopes that can be the target of an unlabeled {@code break} or * {@code continue}. */ private static final SimpleIdentifier EMPTY_LABEL_IDENTIFIER = new SimpleIdentifier( new StringToken(TokenType.IDENTIFIER, "", 0)); /** * Initialize a newly created scope to represent the potential target of an unlabeled * {@code break} or {@code continue}. * * @param outerScope the label scope enclosing the new label scope * @param onSwitchStatement {@code true} if this label is associated with a {@code switch} * statement * @param onSwitchMember {@code true} if this label is associated with a {@code switch} member */ public LabelScope(LabelScope outerScope, boolean onSwitchStatement, boolean onSwitchMember) { this(outerScope, EMPTY_LABEL, new LabelElementImpl( EMPTY_LABEL_IDENTIFIER, onSwitchStatement, onSwitchMember)); } /** * Initialize a newly created scope to represent the given label. * * @param outerScope the label scope enclosing the new label scope * @param label the label defined in this scope * @param element the element to which the label resolves */ public LabelScope(LabelScope outerScope, String label, LabelElement element) { this.outerScope = outerScope; this.label = label; this.element = element; } /** * Return the label element corresponding to the given label, or {@code null} if the given label * is not defined in this scope. * * @param targetLabel the label being looked up * @return the label element corresponding to the given label */ public LabelElement lookup(String targetLabel) { if (label.equals(targetLabel)) { return element; } else if (outerScope != null) { return outerScope.lookup(targetLabel); } else { return null; } } }