private void addDuplicatedMethodError(
      String message, IOpenMethod method, IOpenMethod existedMethod) {
    ISyntaxNode newMethodSyntaxNode = method.getInfo().getSyntaxNode();
    if (newMethodSyntaxNode instanceof TableSyntaxNode) {
      SyntaxNodeException error =
          SyntaxNodeExceptionUtils.createError(message, newMethodSyntaxNode);
      ((TableSyntaxNode) newMethodSyntaxNode).addError(error);

      try {
        TableSyntaxNode existedMethodSyntaxNode =
            (TableSyntaxNode) existedMethod.getInfo().getSyntaxNode();
        if (existedMethodSyntaxNode != null) {
          existedMethodSyntaxNode.addError(
              SyntaxNodeExceptionUtils.createError(message, existedMethodSyntaxNode));
        }
      } catch (Exception ex) {
        log.warn(
            "Cannot get a syntax node for the method: {}",
            MethodUtil.printMethod(existedMethod, new StringBuilder()),
            ex);
      }

      addError(error);
    } else {
      addError(new DuplicatedMethodException(message, method));
    }
  }
 protected void addTestSuiteMethodsFromDependencies() {
   for (CompiledDependency dependency : this.getDependencies()) {
     for (IOpenMethod depMethod :
         dependency.getCompiledOpenClass().getOpenClassWithErrors().getMethods()) {
       if (depMethod instanceof TestSuiteMethod) {
         TestSuiteMethod testSuiteMethod = (TestSuiteMethod) depMethod;
         try {
           // Workaround for set dependency names in method while
           // compile
           if (testSuiteMethod.getModuleName() == null) {
             testSuiteMethod.setModuleName(dependency.getDependencyName());
           }
           TestSuiteMethod newTestSuiteMethod = createNewTestSuiteMethod(testSuiteMethod);
           addMethod(newTestSuiteMethod);
         } catch (OpenlNotCheckedException e) {
           if (Log.isDebugEnabled()) {
             Log.debug(e.getMessage(), e);
           }
           addError(e);
         }
       }
     }
   }
 }
  /**
   * Adds method to <code>XlsModuleOpenClass</code>.
   *
   * @param method method object
   */
  @Override
  public void addMethod(IOpenMethod method) {
    if (method instanceof OpenMethodDispatcher) {
      addDispatcherMethod((OpenMethodDispatcher) method);
      return;
    }
    IOpenMethod m = decorateForMultimoduleDispatching(method);

    // Workaround needed to set the module name in the method while compile
    if (m instanceof AMethod) {
      if (((AMethod) m).getModuleName() == null) {
        XlsMetaInfo metaInfo = getXlsMetaInfo();
        if (metaInfo != null) {
          IOpenSourceCodeModule sourceCodeModule = metaInfo.getXlsModuleNode().getModule();
          if (sourceCodeModule instanceof IModuleInfo) {
            ((AMethod) m).setModuleName(((IModuleInfo) sourceCodeModule).getModuleName());
          }
        }
      }
    }

    // Checks that method already exists in the class. If it already
    // exists then "overload" it using decorator; otherwise - just add to
    // the class.
    //
    IOpenMethod existedMethod =
        getDeclaredMethod(method.getName(), method.getSignature().getParameterTypes());
    if (existedMethod != null) {

      if (!existedMethod.getType().equals(method.getType())) {
        String message =
            String.format(
                "Method \"%s\" with return type \"%s\" has already been defined with another return type (\"%s\")",
                method.getName(),
                method.getType().getDisplayName(0),
                existedMethod.getType().getDisplayName(0));
        addDuplicatedMethodError(message, method, existedMethod);
        return;
      }

      if (method != existedMethod && method instanceof TestSuiteMethod) {
        validateTestSuiteMethod(method, existedMethod);
        return;
      }

      // Checks the instance of existed method. If it's the
      // OpenMethodDecorator then just add the method-candidate to
      // decorator; otherwise - replace existed method with new instance
      // of OpenMethodDecorator for existed method and add new one.
      //
      try {
        if (existedMethod instanceof OpenMethodDispatcher) {
          OpenMethodDispatcher decorator = (OpenMethodDispatcher) existedMethod;
          decorator.addMethod(undecorateForMultimoduleDispatching(m));
        } else {
          if (m != existedMethod) {
            // Create decorator for existed method.
            //
            OpenMethodDispatcher dispatcher = getOpenMethodDispatcher(existedMethod);

            IOpenMethod openMethod = decorateForMultimoduleDispatching(dispatcher);

            overrideMethod(openMethod);

            dispatcher.addMethod(undecorateForMultimoduleDispatching(m));
          }
        }
      } catch (DuplicatedMethodException e) {
        SyntaxNodeException error = null;
        if (m instanceof IMemberMetaInfo) {
          IMemberMetaInfo memberMetaInfo = (IMemberMetaInfo) m;
          if (memberMetaInfo.getSyntaxNode() != null) {
            if (memberMetaInfo.getSyntaxNode() instanceof TableSyntaxNode) {
              error =
                  SyntaxNodeExceptionUtils.createError(
                      e.getMessage(), e, memberMetaInfo.getSyntaxNode());
              ((TableSyntaxNode) memberMetaInfo.getSyntaxNode()).addError(error);
            }
          }
        }
        boolean f = false;
        for (Throwable t : getErrors()) {
          if (t.getMessage().equals(e.getMessage())) {
            f = true;
            break;
          }
        }
        if (!f) {
          if (error != null) {
            addError(error);
          } else {
            addError(e);
          }
        }
      }
    } else {
      // Just wrap original method with dispatcher functionality.
      //

      if (dispatchingValidationEnabled
          && !(m instanceof TestSuiteMethod)
          && dimensionalPropertyPresented(m)) {
        // Create dispatcher for existed method.
        //
        OpenMethodDispatcher dispatcher = getOpenMethodDispatcher(m);

        IOpenMethod openMethod = decorateForMultimoduleDispatching(dispatcher);

        super.addMethod(openMethod);

      } else {
        super.addMethod(m);
      }
    }
  }
  private void addDataTables(CompiledOpenClass dependency) {
    IOpenClass openClass = dependency.getOpenClassWithErrors();

    Map<String, IOpenField> fieldsMap = openClass.getFields();

    Set<String> tableUrls = new HashSet<String>();
    Map<String, IOpenField> fields = getFields();
    for (IOpenField openField : fields.values()) {
      if (openField instanceof DataOpenField) {
        tableUrls.add(((DataOpenField) openField).getTableUri());
      }
    }
    for (String key : fieldsMap.keySet()) {
      IOpenField field = fieldsMap.get(key);
      if (field instanceof DataOpenField) {
        DataOpenField dataOpenField = (DataOpenField) field;
        try {
          String tableUrl = dataOpenField.getTableUri();
          // Test tables are added both as methods and variables.
          if (!tableUrls.contains(tableUrl) && !duplicatedMethodUrls.contains(tableUrl)) {
            boolean containsInDependency = false;
            if (VirtualSourceCodeModule.SOURCE_URI.equals(metaInfo.getSourceUrl())) {
              for (CompiledDependency d : getDependencies()) {
                IOpenClass dependentModuleClass = d.getCompiledOpenClass().getOpenClassWithErrors();
                if (dependentModuleClass instanceof XlsModuleOpenClass) {
                  if (((XlsModuleOpenClass) dependentModuleClass)
                      .duplicatedMethodUrls.contains(tableUrl)) {
                    containsInDependency = true;
                    break;
                  }
                }
              }
            }
            if (!containsInDependency) {
              addField(field);
              tableUrls.add(tableUrl);
            }
          }
        } catch (OpenlNotCheckedException e) {
          SyntaxNodeException error =
              SyntaxNodeExceptionUtils.createError(
                  e.getMessage(), e, dataOpenField.getTable().getTableSyntaxNode());
          addError(error);
        }
      }
    }

    if (openClass instanceof XlsModuleOpenClass) {
      XlsModuleOpenClass xlsModuleOpenClass = (XlsModuleOpenClass) openClass;
      if (xlsModuleOpenClass.getDataBase() != null) {
        for (ITable table : xlsModuleOpenClass.getDataBase().getTables()) {
          if (XlsNodeTypes.XLS_DATA.toString().equals(table.getTableSyntaxNode().getType())) {
            try {
              getDataBase().registerTable(table);
            } catch (DuplicatedTableException e) {
              addError(e);
            } catch (OpenlNotCheckedException e) {
              addError(e);
            }
          }
        }
      }
    }
  }