コード例 #1
0
  public void run(JsRuleContext context, List<Hint> result) {
    JsParseResult info = AstUtilities.getParseResult(context.parserResult);
    Node node = context.node;

    AstElement element = (AstElement) node.element;
    if (element == null) {
      JsParseResult jps = AstUtilities.getParseResult(info);
      if (jps != null) {
        jps.getStructure();
        element = (AstElement) node.element;
        if (element == null) {
          return;
        }
      }
    }

    if (element.getKind() != ElementKind.METHOD && element.getKind() != ElementKind.CONSTRUCTOR) {
      return;
    }

    if (!(element instanceof FunctionAstElement)) {
      assert false : element;
      return;
    }

    FunctionAstElement func = (FunctionAstElement) element;

    Map<String, String> docProps = element.getDocProps();
    if (docProps == null || docProps.size() == 0) {
      return;
    }

    // Make sure we actually have some parameters in the doc props
    boolean found = false;
    for (String key : docProps.keySet()) {
      if (!key.startsWith("@")) {
        found = true;
        break;
      }
    }

    // Don't complain about functions that don't have any parameters
    if (!found) {
      return;
    }

    // Make sure every parameter is documented
    List<String> params = func.getParameters();
    List<String> missing = null;
    List<String> extra = null;
    for (String param : params) {
      if (!docProps.containsKey(param)) {
        if (missing == null) {
          missing = new ArrayList<String>();
        }
        missing.add(param);
      }
    }

    // TODO - make sure doc props exist even for items without types!!
    for (String key : docProps.keySet()) {
      if (key.startsWith("@")) {
        continue;
      }
      if (!params.contains(key)) {
        if (extra == null) {
          extra = new ArrayList<String>();
        }
        extra.add(key);
      }
    }

    if (missing != null || extra != null) {
      String label;
      if (missing != null && extra != null) {
        label = NbBundle.getMessage(WrongJsDoc.class, "WrongParamsBoth", missing, extra);
      } else if (missing != null) {
        label = NbBundle.getMessage(WrongJsDoc.class, "WrongParamsMissing", missing);
      } else {
        assert extra != null;
        label = NbBundle.getMessage(WrongJsDoc.class, "WrongParamsExtra", extra);
      }

      OffsetRange astRange = AstUtilities.getNameRange(node);
      OffsetRange lexRange = LexUtilities.getLexerOffsets(info, astRange);
      if (lexRange == OffsetRange.NONE) {
        return;
      }
      if (lexRange.getEnd() < context.doc.getLength()) {
        try {
          int startRowEnd = Utilities.getRowEnd(context.doc, lexRange.getStart());
          if (startRowEnd < lexRange.getEnd() && startRowEnd > lexRange.getStart()) {
            lexRange = new OffsetRange(lexRange.getStart(), startRowEnd);
          }
        } catch (BadLocationException ex) {
          Exceptions.printStackTrace(ex);
        }
      }

      List<HintFix> fixList =
          Collections.<HintFix>singletonList(new MoreInfoFix("wrongjsdoc")); // NOI18N
      Hint desc =
          new Hint(
              this, label, info.getSnapshot().getSource().getFileObject(), lexRange, fixList, 1450);
      result.add(desc);
    }
  }