All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ow2.mind.adl.generic.GenericDefinitionLoader Maven / Gradle / Ivy

The newest version!
/**
 * Copyright (C) 2009 STMicroelectronics
 *
 * This file is part of "Mind Compiler" is free software: you can redistribute 
 * it and/or modify it under the terms of the GNU Lesser General Public License 
 * as published by the Free Software Foundation, either version 3 of the 
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT 
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see .
 *
 * Contact: [email protected]
 *
 * Authors: Matthieu Leclercq
 * Contributors: 
 */

package org.ow2.mind.adl.generic;

import static org.ow2.mind.adl.ast.ASTHelper.isType;
import static org.ow2.mind.adl.ast.ASTHelper.setResolvedComponentDefinition;

import java.util.HashMap;
import java.util.Map;

import org.objectweb.fractal.adl.ADLException;
import org.objectweb.fractal.adl.Definition;
import org.objectweb.fractal.adl.NodeFactory;
import org.ow2.mind.adl.ADLErrors;
import org.ow2.mind.adl.AbstractDelegatingLoader;
import org.ow2.mind.adl.DefinitionReferenceResolver;
import org.ow2.mind.adl.ast.ASTHelper;
import org.ow2.mind.adl.ast.Component;
import org.ow2.mind.adl.ast.ComponentContainer;
import org.ow2.mind.adl.generic.ast.FormalTypeParameter;
import org.ow2.mind.adl.generic.ast.FormalTypeParameterContainer;
import org.ow2.mind.adl.generic.ast.FormalTypeParameterReference;
import org.ow2.mind.adl.imports.ast.Import;
import org.ow2.mind.adl.imports.ast.ImportContainer;
import org.ow2.mind.error.ErrorManager;

import com.google.inject.Inject;

/**
 * This delegating Loader checks that types of formal type arguments are
 * correct. It also checks if a formal type argument hides an import statement.
 */
public class GenericDefinitionLoader extends AbstractDelegatingLoader {

  @Inject
  protected ErrorManager                errorManagerItf;

  @Inject
  protected NodeFactory                 nodeFactoryItf;

  @Inject
  protected DefinitionReferenceResolver definitionReferenceResolverItf;

  // ---------------------------------------------------------------------------
  // Implementation of the Loader interface
  // ---------------------------------------------------------------------------

  public Definition load(final String name, final Map context)
      throws ADLException {

    // delegates loading of definition to client loader.
    final Definition d = clientLoader.load(name, context);

    final Import[] imports = d instanceof ImportContainer
        ? ((ImportContainer) d).getImports()
        : null;

    // resolve types of formal type parameters (if any)
    if (d instanceof FormalTypeParameterContainer) {
      final FormalTypeParameter[] formalTypeParameters = ((FormalTypeParameterContainer) d)
          .getFormalTypeParameters();
      if (formalTypeParameters.length > 0) {
        final Map typeParameterTypes = new HashMap(
            formalTypeParameters.length);
        for (final FormalTypeParameter typeParameter : formalTypeParameters) {

          // checks that formal type parameter do not hide an import.
          if (imports != null) {
            for (final Import imp : imports) {
              if (typeParameter.getName().equals(imp.getSimpleName())) {
                errorManagerItf.logWarning(
                    ADLErrors.WARNING_TEMPLATE_VARIABLE_HIDE, typeParameter,
                    typeParameter.getName(), imp.astGetSource());
              }
            }
          }

          if (typeParameter.getDefinitionReference() == null) {
            // If the formal type parameter do not define a type to which it
            // must conform, pass it. This can happen for special definitions
            // like "Factory".
            continue;
          }

          final Definition typeParameterTypeDefinition = definitionReferenceResolverItf
              .resolve(typeParameter.getDefinitionReference(), d, context);

          if (!isType(typeParameterTypeDefinition))
            errorManagerItf
                .logError(ADLErrors.INVALID_REFERENCE_NOT_A_TYPE,
                    typeParameter, typeParameter.getDefinitionReference()
                        .getName());

          if (typeParameterTypes.put(typeParameter.getName(),
              typeParameterTypeDefinition) != null) {
            errorManagerItf.logError(
                ADLErrors.DUPLICATED_TEMPALTE_VARIABLE_NAME, typeParameter,
                typeParameter.getName());
          }
        }

        if (d instanceof ComponentContainer) {
          for (final Component subComp : ((ComponentContainer) d)
              .getComponents()) {

            if (subComp instanceof FormalTypeParameterReference) {
              final String ref = ((FormalTypeParameterReference) subComp)
                  .getTypeParameterReference();

              if (ref != null) {
                Definition typeParameterType = typeParameterTypes.get(ref);
                if (typeParameterType == null) {
                  errorManagerItf.logError(
                      ADLErrors.UNDEFINED_TEMPALTE_VARIABLE, subComp, ref);
                  typeParameterType = ASTHelper.newUnresolvedDefinitionNode(
                      nodeFactoryItf, null);
                }
                setResolvedComponentDefinition(subComp, typeParameterType);
              }
            }
          }
        }
      }
    }
    return d;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy