Package com.google.dart.engine.internal.element.member

Source Code of com.google.dart.engine.internal.element.member.ParameterMember

/*
* Copyright (c) 2013, 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.element.member;

import com.google.dart.engine.element.ConstructorElement;
import com.google.dart.engine.element.Element;
import com.google.dart.engine.element.ElementVisitor;
import com.google.dart.engine.element.FieldFormalParameterElement;
import com.google.dart.engine.element.MethodElement;
import com.google.dart.engine.element.ParameterElement;
import com.google.dart.engine.element.PropertyAccessorElement;
import com.google.dart.engine.internal.type.TypeParameterTypeImpl;
import com.google.dart.engine.type.InterfaceType;
import com.google.dart.engine.type.ParameterizedType;
import com.google.dart.engine.type.Type;
import com.google.dart.engine.utilities.dart.ParameterKind;
import com.google.dart.engine.utilities.source.SourceRange;

/**
* Instances of the class {@code ParameterMember} represent a parameter element defined in a
* parameterized type where the values of the type parameters are known.
*/
public class ParameterMember extends VariableMember implements ParameterElement {
  /**
   * If the given parameter's type is different when any type parameters from the defining type's
   * declaration are replaced with the actual type arguments from the defining type, create a
   * parameter member representing the given parameter. Return the member that was created, or the
   * base parameter if no member was created.
   *
   * @param baseParameter the base parameter for which a member might be created
   * @param definingType the type defining the parameters and arguments to be used in the
   *          substitution
   * @return the parameter element that will return the correctly substituted types
   */
  public static ParameterElement from(ParameterElement baseParameter, ParameterizedType definingType) {
    if (baseParameter == null || definingType.getTypeArguments().length == 0) {
      return baseParameter;
    }
    // Check if parameter type depends on defining type type arguments.
    // It is possible that we did not resolve field formal parameter yet, so skip this check for it.
    boolean isFieldFormal = baseParameter instanceof FieldFormalParameterElement;
    if (!isFieldFormal) {
      Type baseType = baseParameter.getType();
      Type[] argumentTypes = definingType.getTypeArguments();
      Type[] parameterTypes = TypeParameterTypeImpl.getTypes(definingType.getTypeParameters());
      Type substitutedType = baseType.substitute(argumentTypes, parameterTypes);
      if (baseType.equals(substitutedType)) {
        return baseParameter;
      }
    }
    // TODO(brianwilkerson) Consider caching the substituted type in the instance. It would use more
    // memory but speed up some operations. We need to see how often the type is being re-computed.
    if (isFieldFormal) {
      return new FieldFormalParameterMember(
          (FieldFormalParameterElement) baseParameter,
          definingType);
    }
    return new ParameterMember(baseParameter, definingType);
  }

  /**
   * Initialize a newly created element to represent a parameter of the given parameterized type.
   *
   * @param baseElement the element on which the parameterized element was created
   * @param definingType the type in which the element is defined
   */
  public ParameterMember(ParameterElement baseElement, ParameterizedType definingType) {
    super(baseElement, definingType);
  }

  @Override
  public <R> R accept(ElementVisitor<R> visitor) {
    return visitor.visitParameterElement(this);
  }

  @Override
  @SuppressWarnings("unchecked")
  public <E extends Element> E getAncestor(Class<E> elementClass) {
    E element = getBaseElement().getAncestor(elementClass);
    ParameterizedType definingType = getDefiningType();
    if (definingType instanceof InterfaceType) {
      InterfaceType definingInterfaceType = (InterfaceType) definingType;
      if (element instanceof ConstructorElement) {
        return (E) ConstructorMember.from((ConstructorElement) element, definingInterfaceType);
      } else if (element instanceof MethodElement) {
        return (E) MethodMember.from((MethodElement) element, definingInterfaceType);
      } else if (element instanceof PropertyAccessorElement) {
        return (E) PropertyAccessorMember.from(
            (PropertyAccessorElement) element,
            definingInterfaceType);
      }
    }
    return element;
  }

  @Override
  public ParameterElement getBaseElement() {
    return (ParameterElement) super.getBaseElement();
  }

  @Override
  public String getDefaultValueCode() {
    return getBaseElement().getDefaultValueCode();
  }

  @Override
  public Element getEnclosingElement() {
    return getBaseElement().getEnclosingElement();
  }

  @Override
  public ParameterKind getParameterKind() {
    return getBaseElement().getParameterKind();
  }

  @Override
  public ParameterElement[] getParameters() {
    ParameterElement[] baseParameters = getBaseElement().getParameters();
    int parameterCount = baseParameters.length;
    if (parameterCount == 0) {
      return baseParameters;
    }
    ParameterElement[] parameterizedParameters = new ParameterElement[parameterCount];
    for (int i = 0; i < parameterCount; i++) {
      parameterizedParameters[i] = ParameterMember.from(baseParameters[i], getDefiningType());
    }
    return parameterizedParameters;
  }

  @Override
  public SourceRange getVisibleRange() {
    return getBaseElement().getVisibleRange();
  }

  @Override
  public boolean isInitializingFormal() {
    return getBaseElement().isInitializingFormal();
  }

  @Override
  public String toString() {
    ParameterElement baseElement = getBaseElement();
    String left = "";
    String right = "";
    switch (baseElement.getParameterKind()) {
      case NAMED:
        left = "{";
        right = "}";
        break;
      case POSITIONAL:
        left = "[";
        right = "]";
        break;
      case REQUIRED:
        // No need to change the default.
        break;
    }
    StringBuilder builder = new StringBuilder();
    builder.append(left);
    builder.append(getType());
    builder.append(" ");
    builder.append(baseElement.getDisplayName());
    builder.append(right);
    return builder.toString();
  }

  @Override
  public void visitChildren(ElementVisitor<?> visitor) {
    super.visitChildren(visitor);
    safelyVisitChildren(getParameters(), visitor);
  }
}
TOP

Related Classes of com.google.dart.engine.internal.element.member.ParameterMember

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.