Package com.googlecode.goclipse.go.lang.parser

Source Code of com.googlecode.goclipse.go.lang.parser.VariableParser

package com.googlecode.goclipse.go.lang.parser;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import com.googlecode.goclipse.Activator;
import com.googlecode.goclipse.go.lang.lexer.Lexer;
import com.googlecode.goclipse.go.lang.lexer.TokenListener;
import com.googlecode.goclipse.go.lang.lexer.TokenType;
import com.googlecode.goclipse.go.lang.lexer.Tokenizer;
import com.googlecode.goclipse.go.lang.model.TypeClass;
import com.googlecode.goclipse.go.lang.model.Var;

/**
*
* @author steel
*/
public class VariableParser implements TokenListener {

  private enum State {
    START, SIMPLE_VAR, SIMPLE_TYPE, INFERENCE, FINISHED, ERROR,
  }
 
  private File              file              = null;
  private ScopeParser     scopeParser       = null;
  private ArrayList<Var>    vars              = new ArrayList<Var>();
  private State             state          = State.START;
  //private TokenType        previousTokenType = TokenType.NEWLINE;
  //private String           previousTextValue = "\n";
  private Var               var           = new Var();
  private StringBuffer      comment         = new StringBuffer();
  private int         lastCommentLine   = 0;
  private FunctionParser    functionParser    = null;
  private ArrayList<String> previousIdentifier= new ArrayList<String>();
  private ArrayList<Var>    varBuffer         = new ArrayList<Var>();
  private String            type              = "";
 
  /**
   * @param tokenizer
   */
  public VariableParser(Tokenizer tokenizer, File file, FunctionParser functionParser) {
    tokenizer.addTokenListener(this);
    this.file = file;
    var.setFile(file);
    this.functionParser = functionParser;
  }
 
  /**
   * @param scopeParser
   */
  public void setScopeParser(ScopeParser scopeParser){
    this.scopeParser = scopeParser;
  }
 
  @Override
  public void tokenFound(TokenType type, String value, boolean inComment,
      int linenumber, int start, int end) {
   
    if (inComment) {
      if (!TokenType.COMMENT.equals(type)
          && !TokenType.BLOCK_COMMENT_START.equals(type)
          && !TokenType.BLOCK_COMMENT_END.equals(type)) {

        if (linenumber > lastCommentLine
            && TokenType.DIVIDE.equals(type)) {
          lastCommentLine = linenumber;
        }
        else {
          comment.append(value);
          lastCommentLine = linenumber;
        }
      }
      return;
    }
   
    handleVarBufferFlush(type);
   
    if (linenumber - lastCommentLine > 1) {
      comment = new StringBuffer();
    }
   
    //System.out.println(state);
   
   
    if (!inComment) {
     
      switch (state) {
     
      case START:
       
        if (TokenType.VAR.equals(type)) {
          state = State.SIMPLE_VAR;
         
        } else if((TokenType.INFERENCE.equals(type))){
          // TODO this inference parsing does not work
          //System.out.println("State Changed On: "+ type +":"+ value);
          state = State.INFERENCE;
        }
        break;
     
      // var name type
      case SIMPLE_VAR:
        if(TokenType.IDENTIFIER.equals(type)){
          var.setName(value);
          var.setInsertionText(value);
          var.setDocumentation(comment.toString());
          var.setLine(linenumber);
          state = State.SIMPLE_TYPE;
        }
        break;
             
      case SIMPLE_TYPE:
       
        boolean found = false;
       
        // this isn't very clean, I'll have to come back a rethink all this
        // is TypeClass enough???
        if(TokenType.IDENTIFIER.equals(type))    {var.setTypeClass(TypeClass.USER);    var.setName(var.getName()+" : "+value);          found = true;}
        else if(TokenType.UINT.equals(type))   {var.setTypeClass(TypeClass.UINT);    var.setName(var.getName()+" : "+type.getText()); found = true;}
        else if(TokenType.UINT8.equals(type))   {var.setTypeClass(TypeClass.UINT8);   var.setName(var.getName()+" : "+type.getText()); found = true;}
        else if(TokenType.UINT16.equals(type))   {var.setTypeClass(TypeClass.UINT16);  var.setName(var.getName()+" : "+type.getText()); found = true;}
        else if(TokenType.UINT32.equals(type))   {var.setTypeClass(TypeClass.UINT32);  var.setName(var.getName()+" : "+type.getText()); found = true;}
        else if(TokenType.UINT64.equals(type))   {var.setTypeClass(TypeClass.UINT64);  var.setName(var.getName()+" : "+type.getText()); found = true;}
        else if(TokenType.RUNE.equals(type))   {var.setTypeClass(TypeClass.RUNE);    var.setName(var.getName()+" : "+type.getText()); found = true;}
        else if(TokenType.INT.equals(type))       {var.setTypeClass(TypeClass.INT);     var.setName(var.getName()+" : "+type.getText()); found = true;}
        else if(TokenType.INT8.equals(type))   {var.setTypeClass(TypeClass.INT8);    var.setName(var.getName()+" : "+type.getText()); found = true;}
        else if(TokenType.INT16.equals(type))   {var.setTypeClass(TypeClass.INT16);   var.setName(var.getName()+" : "+type.getText()); found = true;}
        else if(TokenType.INT32.equals(type))   {var.setTypeClass(TypeClass.INT32);   var.setName(var.getName()+" : "+type.getText()); found = true;}
        else if(TokenType.INT64.equals(type))   {var.setTypeClass(TypeClass.INT64);   var.setName(var.getName()+" : "+type.getText()); found = true;}
        else if(TokenType.FLOAT32.equals(type))  {var.setTypeClass(TypeClass.FLOAT32); var.setName(var.getName()+" : "+type.getText()); found = true;}
        else if(TokenType.FLOAT64.equals(type))  {var.setTypeClass(TypeClass.FLOAT64); var.setName(var.getName()+" : "+type.getText()); found = true;}
        else if(TokenType.BYTE.equals(type))   {var.setTypeClass(TypeClass.BYTE);    var.setName(var.getName()+" : "+type.getText()); found = true;}
        else if(TokenType.UINTPTR.equals(type))  {var.setTypeClass(TypeClass.UINTPTR); var.setName(var.getName()+" : "+type.getText()); found = true;}
        else if(TokenType.STRING.equals(type))   {var.setTypeClass(TypeClass.STRING);  var.setName(var.getName()+" : "+type.getText()); found = true;}
        else if(TokenType.BOOL.equals(type))   {var.setTypeClass(TypeClass.BOOL);    var.setName(var.getName()+" : "+type.getText()); found = true;}
        else if(TokenType.CHAN.equals(type))   {var.setTypeClass(TypeClass.CHAN);    var.setChan(true); found = true;}
        else if(TokenType.MAP.equals(type))      {var.setTypeClass(TypeClass.MAP);     var.setMap(true);  found = true;}
        else if(TokenType.LBRACKET.equals(type)) {var.setTypeClass(TypeClass.ARRAY);   var.setArray(true);found = false;}
        else if(TokenType.MULTIPLY.equals(type)) {var.setPointer(true);                                   found = false;}
       
        if(found) {
         
          state = State.START;
          vars.add(var);
          var.setLine(linenumber);
         
          if (scopeParser != null) {
            scopeParser.addVariable(var);
          }
         
          var = new Var();
          var.setFile(file);
          comment = new StringBuffer();
        }
       
        break;
       
      case INFERENCE:
       
        for(String s:previousIdentifier){
         
          if (var.getInsertionText() == null) {
            var.setInsertionText(s);
          }
         
          state = State.START;
          vars.add(var);
          var.setLine(linenumber);
         
          if (scopeParser != null) {
            scopeParser.addVariable(var);
          }
         
          var = new Var();
          var.setFile(file);
          comment = new StringBuffer();
        }
       
        previousIdentifier.clear();
        break;
       
      }
     
    }
   
    // keep track of the last identifier for inferenced variables
    if (TokenType.IDENTIFIER.equals(type)){
      previousIdentifier.add(value);
     
    } else if(!TokenType.COMMA.equals(type)&&
          !TokenType.SPACE.equals(type)&&
          !TokenType.NEWLINE.equals(type)&&
          !TokenType.TAB.equals(type)&&
          !TokenType.TYPE.equals(type)){
     
      previousIdentifier.clear();
    }
  }

  /**
   * Handle the times we flush the buffer.  We do this so those
   * times we declare a var within a statement like a for loop,
   * the new var falls into the inner scope and not the outer.
   * @param type
   */
  private void handleVarBufferFlush(TokenType type) {
    switch (type) {
    case LBRACE:
    case RBRACE:
    case IF:
    case ELSE:
    case SWITCH:
    case FOR:
    case FUNC:
    case TYPE:
    case GO:
    case CASE:
    case DEFAULT:
      if (scopeParser!=null) {
        for(Var var:varBuffer) {
          scopeParser.addVariable(var);
        }
        varBuffer.clear();
      }
    }
  }
 
  @Override
  public boolean isWhitespaceParser() {
    return false;
  }
 
 
  /**
   * @return the vars
   */
  public ArrayList<Var> getVars() {
    return vars;
  }

  /**
   * @param vars the vars to set
   */
  public void setVars(ArrayList<Var> vars) {
    this.vars = vars;
  }

  public static void main(String[] args) {

    Lexer lexer = new Lexer();
    Tokenizer tokenizer = new Tokenizer(lexer);
    VariableParser fparser = new VariableParser(tokenizer, null, null);

    try {
      lexer.scan(new File("test/test_go/import_test.go"));
      for (Var var : fparser.vars) {
        Activator.logInfo("=================================================");
        Activator.logInfo(var.getDocumentation());
        Activator.logInfo("-------------------------------------------------");
        Activator.logInfo(var.getName());
        Activator.logInfo(var.getInsertionText());
        Activator.logInfo("-------------------------------------------------");
      }

    } catch (IOException e) {
      Activator.logError(e);
    }
  }
}
TOP

Related Classes of com.googlecode.goclipse.go.lang.parser.VariableParser

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.