예제 #1
0
  /*
   * (non-Javadoc)
   * @see com.aptana.editor.js.parsing.ast.JSTreeWalker#visit(com.aptana.editor.js.parsing.ast.JSFunctionNode)
   */
  @Override
  public void visit(JSFunctionNode node) {
    List<String> types = new ArrayList<String>();
    JSScope scope = this.getActiveScope(node.getBody().getStartingOffset());
    boolean foundReturnExpression = false;

    // infer return types
    for (JSReturnNode returnValue : node.getReturnNodes()) {
      IParseNode expression = returnValue.getExpression();

      if (!expression.isEmpty()) {
        foundReturnExpression = true;

        types.addAll(this.getTypes(expression, scope));
      }
    }

    // If we couldn't infer a return type and we had a return
    // expression, then have it return Object
    if (foundReturnExpression && types.isEmpty()) {
      types.add(JSTypeConstants.OBJECT_TYPE);
    }

    // build function type, including return values
    String type = JSTypeUtil.toFunctionType(types);
    this.addType(type);
  }
예제 #2
0
  /*
   * (non-Javadoc)
   * @see
   * com.aptana.editor.js.parsing.ast.JSTreeWalker#visit(com.aptana.editor.js.parsing.ast.JSArithmeticOperatorNode)
   */
  @Override
  public void visit(JSBinaryArithmeticOperatorNode node) {
    String type = JSTypeConstants.NUMBER_TYPE;

    if (node.getNodeType() == IJSNodeTypes.ADD) {
      IParseNode lhs = node.getLeftHandSide();
      IParseNode rhs = node.getRightHandSide();

      // NOTE: Iterate down the tree until we find the first non-addition node or the first string
      while (lhs.getNodeType() == IJSNodeTypes.ADD) {
        rhs = lhs.getLastChild();
        lhs = lhs.getFirstChild();

        if (rhs instanceof JSStringNode) {
          break;
        }
      }

      if (lhs instanceof JSStringNode || rhs instanceof JSStringNode) {
        type = JSTypeConstants.STRING_TYPE;
      } else {
        List<String> lhsTypes = this.getTypes(lhs);
        List<String> rhsTypes = this.getTypes(rhs);

        if (lhsTypes.contains(JSTypeConstants.STRING_TYPE)
            || rhsTypes.contains(JSTypeConstants.STRING_TYPE)) {
          type = JSTypeConstants.STRING_TYPE;
        }
      }
    }

    this.addType(type);
  }
 @Override
 public Object getParent(Object element) {
   if (element instanceof CommonOutlineItem) {
     IParseNode node = ((CommonOutlineItem) element).getReferenceNode();
     IParseNode parent = node.getParent();
     if (parent instanceof ParseRootNode) {
       // we're at the root of the nested language, which is not displayed; go one level up
       parent = parent.getParent();
     }
     return getOutlineItem(parent);
   }
   return super.getParent(element);
 }
예제 #4
0
 /**
  * @param document
  * @param hasBlockedChild
  * @param node
  */
 public FormatterJSIfNode(
     IFormatterDocument document,
     boolean hasBlockedChild,
     IParseNode node,
     boolean hasCommentBefore) {
   super(document, hasBlockedChild, node, hasCommentBefore);
   // Check if this node is located in the 'false' block of a parent 'if'. In that case, we can say
   // for sure that
   // this 'if' arrives right after an 'else'.
   if (node.getParent().getNodeType() == JSNodeTypes.IF) {
     JSIfNode parentIfNode = (JSIfNode) node.getParent();
     inElseIf = parentIfNode.getFalseBlock() == node;
   }
 }
예제 #5
0
  private void processPHPBlock(IParseNode root, int sourceLength)
      throws IOException, Exception // $codepro.audit.disable
      {
    Symbol startTag = getCurrentSymbol();
    advance();

    // finds the entire php block
    int start = getCurrentSymbol().getStart();
    int end = start;
    short id = getCurrentSymbol().getId();
    while (id != PHTMLTokens.PHP_END && id != PHTMLTokens.EOF) {
      end = getCurrentSymbol().getEnd();
      advance();
      id = getCurrentSymbol().getId();
    }

    IParseNode result = getParseResult(IPHPConstants.CONTENT_TYPE_PHP, start, end);
    if (result != null) {
      Symbol endTag = getCurrentSymbol();
      ParseNode phpNode = new ParseNode(IPHPConstants.CONTENT_TYPE_PHP);
      int endOffset;
      if ("?>".equals(endTag.value)) // $NON-NLS-1$
      {
        endOffset = endTag.getEnd() + 1;
      } else {
        endOffset = endTag.getEnd();
      }
      phpNode.setLocation(startTag.getStart(), Math.min(endOffset, sourceLength - 1));
      root.addChild(phpNode);
    }
  }
 @Override
 public CommonOutlineItem getOutlineItem(IParseNode node) {
   if (node instanceof HTMLNode) {
     return new HTMLOutlineItem(node.getNameNode().getNameRange(), node);
   }
   return super.getOutlineItem(node);
 }
예제 #7
0
  /*
   * (non-Javadoc)
   * @see com.aptana.editor.js.parsing.ast.JSTreeWalker#visit(com.aptana.editor.js.parsing.ast.JSIdentifierNode)
   */
  @Override
  public void visit(JSIdentifierNode node) {
    String name = node.getText();
    Collection<PropertyElement> properties = null;

    if (this._scope != null && this._scope.hasSymbol(name)) {
      IParseNode parent = node.getParent();

      if (parent != null && parent.getNodeType() == IJSNodeTypes.PARAMETERS) {
        // special handling of parameters to potentially get the type
        // from documentation and to prevent an infinite loop since
        // parameters point to themselves in the symbol table
        this.addParameterTypes(node);
      } else {
        // Check the local scope for type first
        JSSymbolTypeInferrer symbolInferrer =
            new JSSymbolTypeInferrer(this._scope, this._index, this._location);
        PropertyElement property = symbolInferrer.getSymbolPropertyElement(name);
        if (property != null) {
          // We found a match in the local scope
          properties = CollectionsUtil.newList(property);
        } else {
          // No match in the local scope, query the globals in index
          properties = this._queryHelper.getGlobals(this._index, getProject(), getFileName(), name);
        }
      }
    } else {
      // Scope says it doesn't has a symbol with that name, so query the globals in index
      properties = this._queryHelper.getGlobals(this._index, getProject(), getFileName(), name);
    }

    // Hopefully we found at least one match...
    if (properties != null) {
      for (PropertyElement property : properties) {
        if (property instanceof FunctionElement) {
          FunctionElement function = (FunctionElement) property;
          for (String type : function.getSignatureTypes()) {
            this.addType(type);
          }
        } else {
          for (String type : property.getTypeNames()) {
            this.addType(type);
          }
        }
      }
    }
  }
 private void filterRecursively(IParseNode[] nodes, List<CommonOutlineItem> list) {
   IPHPParseNode element;
   for (IParseNode node : nodes) {
     if (node instanceof IPHPParseNode) {
       element = (IPHPParseNode) node;
       // filters out any item that should not be in the outline
       if (!element.isFilteredFromOutline()) {
         list.add(getOutlineItem(element));
       } else {
         // the node may have children that we don't want to filter (like a function within an 'if'
         // statement).
         filterRecursively(node.getChildren(), list);
       }
     } else if (!(node instanceof HTMLTextNode)) {
       list.add(getOutlineItem(node));
     }
   }
 }
예제 #9
0
    /* (non-Javadoc)
     * @see com.aptana.editor.json.parsing.ast.JSONTreeWalker#visit(com.aptana.editor.json.parsing.ast.JSONEntryNode)
     */
    @Override
    public void visit(JSONEntryNode node) {
      JSONEntryFormatNode entry = new JSONEntryFormatNode(_document);
      IParseNode name = node.getFirstChild();
      Symbol colon = node.getColon();
      IParseNode value = node.getLastChild();
      IFormatterTextNode nameText =
          createTextNode(_document, name.getStartingOffset(), name.getEndingOffset() + 1);
      IFormatterTextNode colonText =
          createTextNode(_document, colon.getStart(), colon.getEnd() + 1);

      // add children
      entry.addChild(nameText);
      entry.addChild(colonText);

      // push node, visit children, then remove from stack
      push(entry);
      this.visit(value);
      checkedPop(entry, node.getEndingOffset() + 1);
    }
 @Override
 public CommonOutlineItem getOutlineItem(IParseNode node) {
   if (node == null) {
     return null;
   }
   if (node instanceof IPHPParseNode) {
     return new PHPOutlineItem(node.getNameNode().getNameRange(), node);
   } else {
     return super.getOutlineItem(node);
   }
 }
예제 #11
0
  /*
   * (non-Javadoc)
   * @see com.aptana.editor.js.parsing.ast.JSTreeWalker#visit(com.aptana.editor.js.parsing.ast.JSGetPropertyNode)
   */
  @Override
  public void visit(JSGetPropertyNode node) {
    IParseNode lhs = node.getLeftHandSide();

    if (lhs instanceof JSNode) {
      IParseNode rhs = node.getRightHandSide();
      String memberName = rhs.getText();

      for (String typeName : this.getTypes(lhs)) {
        // Fix up type names as might be necessary
        typeName = JSTypeMapper.getInstance().getMappedType(typeName);
        // TODO Combine with similar code from ParseUtil.getParentObjectTypes
        if (JSTypeConstants.FUNCTION_JQUERY.equals(typeName)
            && lhs instanceof JSIdentifierNode
            && (JSTypeConstants.DOLLAR.equals(lhs.getText())
                || JSTypeConstants.JQUERY.equals(lhs.getText()))) {
          typeName = JSTypeConstants.CLASS_JQUERY;
        }

        // lookup up rhs name in type and add that value's type here
        Collection<PropertyElement> properties =
            this._queryHelper.getTypeMembers(this._index, typeName, memberName);

        if (properties != null) {
          for (PropertyElement property : properties) {
            if (property instanceof FunctionElement) {
              FunctionElement function = (FunctionElement) property;
              for (String type : function.getSignatureTypes()) {
                this.addType(type);
              }
            } else {
              for (String type : property.getTypeNames()) {
                this.addType(type);
              }
            }
          }
        }
      }
    }
  }
예제 #12
0
  /**
   * A private helper function for {@link #toTreeString(IParseNode)}
   *
   * @param buffer
   * @param node
   */
  private static void toTreeString(List<String> buffer, IParseNode node) {
    // TODO: Move to an iterative (non-recursive) implementation if this gets used outside of unit
    // testing
    buffer.add("("); // $NON-NLS-1$
    buffer.add(node.getElementName());

    if (node.hasChildren()) {
      IParseNode lastChild = node.getLastChild();

      buffer.add(" "); // $NON-NLS-1$

      for (IParseNode child : node) {
        toTreeString(buffer, child);

        if (child != lastChild) {
          buffer.add(" "); // $NON-NLS-1$
        }
      }
    }

    buffer.add(")"); // $NON-NLS-1$
  }
예제 #13
0
  /**
   * addParameterTypes
   *
   * @param identifierNode
   */
  private void addParameterTypes(JSIdentifierNode identifierNode) {
    IParseNode parent = identifierNode.getParent();
    IParseNode grandparent = (parent != null) ? parent.getParent() : null;
    boolean foundType = false;

    if (grandparent != null && grandparent.getNodeType() == IJSNodeTypes.FUNCTION) {
      DocumentationBlock docs = ((JSNode) grandparent).getDocumentation();

      if (docs != null) {
        String name = identifierNode.getText();
        int index = identifierNode.getIndex();
        List<Tag> params = docs.getTags(TagType.PARAM);

        if (params != null && index < params.size()) {
          ParamTag param = (ParamTag) params.get(index);

          if (name.equals(param.getName())) {
            for (Type parameterType : param.getTypes()) {
              String type = parameterType.getName();

              // Fix up type names as might be necessary
              type = JSTypeMapper.getInstance().getMappedType(type);

              this.addType(type);
              foundType = true;
            }
          }
        }
      }
    }

    // Use "Object" as parameter type if we didn't find types by other
    // means
    if (!foundType) {
      this.addType(JSTypeConstants.DEFAULT_PARAMETER_TYPE);
    }
  }
예제 #14
0
 /**
  * @param parseResult
  * @param document
  * @return
  */
 public IFormatterContainerNode build(IParseNode parseResult, FormatterDocument document) {
   this.document = document;
   final IFormatterContainerNode rootNode = new FormatterCSSRootNode(document);
   start(rootNode);
   IParseNode[] children = parseResult.getChildren();
   addNodes(children);
   checkedPop(rootNode, document.getLength());
   // Collect Off/On tags
   if (parseResult instanceof IParseRootNode) {
     setOffOnRegions(
         resolveOffOnRegions(
             (IParseRootNode) parseResult,
             document,
             CSSFormatterConstants.FORMATTER_OFF_ON_ENABLED,
             CSSFormatterConstants.FORMATTER_OFF,
             CSSFormatterConstants.FORMATTER_ON));
   }
   return rootNode;
 }
예제 #15
0
  /*
   * (non-Javadoc)
   * @see com.aptana.editor.js.parsing.ast.JSTreeWalker#visit(com.aptana.editor.js.parsing.ast.JSInvokeNode)
   */
  @Override
  public void visit(JSInvokeNode node) {
    IParseNode child = node.getExpression();

    if (child instanceof JSNode) {
      // TODO hang the "require" string as a constant somewhere!
      if (child instanceof JSIdentifierNode
          && "require".equals(child.getNameNode().getName())) // $NON-NLS-1$
      {
        // it's a requires!
        JSArgumentsNode args = (JSArgumentsNode) node.getArguments();
        IParseNode[] children = args.getChildren();
        for (IParseNode arg : children) {
          if (arg instanceof JSStringNode) {
            JSStringNode string = (JSStringNode) arg;
            String text = string.getText();
            // strip quotes TODO Use util method to strip quotes!
            if (text.startsWith("'") || text.startsWith("\"")) // $NON-NLS-1$ //$NON-NLS-2$
            {
              text = text.substring(1, text.length() - 1);
            }

            // Handle resolving absolute versus relative module ids!
            URI resolved = _location.resolve(text);
            URI relative = _index.getRelativeDocumentPath(resolved);
            this.addType(relative.getPath() + ".exports"); // $NON-NLS-1$
          }
        }
      }

      List<String> types = this.getTypes(child);

      // NOTE: This is a special case for functions used as a RHS of assignments or as part of a
      // property chain.
      // If the invocation returns undefined, we change that to Object.
      // TODO: As a refinement, we want to check that the function being called is not defined in
      // the current
      // scope
      if (types.isEmpty()) {
        IParseNode parent = node.getParent();

        if (parent != null) {
          switch (parent.getNodeType()) {
            case IJSNodeTypes.ASSIGN:
              if (node.getIndex() == 1) {
                this.addType(JSTypeConstants.OBJECT_TYPE);
              }
              break;

            case IJSNodeTypes.GET_PROPERTY:
              this.addType(JSTypeConstants.OBJECT_TYPE);
              break;

            default:
              break;
          }
        }
      }

      for (String typeName : types) {
        if (JSTypeUtil.isFunctionPrefix(typeName)) {
          List<String> returnTypes = JSTypeUtil.getFunctionSignatureReturnTypeNames(typeName);
          for (String returnTypeName : returnTypes) {
            this.addType(returnTypeName);
          }
        }
      }
    }
  }