简体   繁体   中英

How can I count the number each variable type, appears in an Android class? e.g. int, string etc

I've created a small Android application which reads in, a particular Android class (.java).

I'd like to (but currently don't know how):

  • Count the number each variable type is globally declared (as it is on the page, not during or after run-time etc.) eg

5 regular ints , 3 regular strings , 1 regular drawables , 2 ArrayList of ints

  • Count the number each variable type is locally declared, in each function (as it is on the page, not during or after run-time etc.) eg

Function A: 2 regular ints , 1 regular strings

Function B: 3 regular drawables , 4 ArrayList of ints

  • Count the number of subroutines and functions, within the class (as it is on the page, not during or after run-time etc.)

So far I've figured out the below, but due to the programmatic nature it doesn't work correctly:

        int numberofArrayLists = Collections.frequency(androidClass, "ArrayList<String>");
        int numberofIntLists = Collections.frequency(androidClass, "ArrayList<Int>");
        int numberofBooleanLists = Collections.frequency(androidClass, "ArrayList<Boolean>");

My code:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    try {
        ArrayList<String> androidClass =  readAndroidClass("/sdcard/MainActivity.java");
    } catch (IOException e) {
        e.printStackTrace();
    }
}


public ArrayList<String> readAndroidClass(String classLocationString) throws IOException {
    ArrayList<String> androidClass = new ArrayList<String>();
    FileInputStream is;
    BufferedReader reader;
    final File classLocation = new File(classLocationString);

    if (classLocation.exists()) {
        is = new FileInputStream(classLocation);
        reader = new BufferedReader(new InputStreamReader(is));
        String line = reader.readLine();
        while(line != null){
            androidClass.add(reader.readLine());
        }
    }

    return androidClass;
}

Example of an Android Java class to attempt the above:

public class MainActivity extends ListActivity {
    private PackageManager packageManager = null;
    private List<ApplicationInfo> applist = null;
    private ApplicationAdapter listadaptor = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        packageManager = getPackageManager();

        new LoadApplications().execute();
    }

    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu, menu);

        return true;
    }

    public boolean onOptionsItemSelected(MenuItem item) {
        return false;
    }

    private List<ApplicationInfo> checkForLaunchIntent(List<ApplicationInfo> list) {
        ArrayList<ApplicationInfo> applist = new ArrayList<ApplicationInfo>();
        for (ApplicationInfo info : list) {
            try {
                if (null != packageManager.getLaunchIntentForPackage(info.packageName)) {
                    applist.add(info);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return applist;
    }

    private class LoadApplications extends AsyncTask<Void, Void, Void> {
        private ProgressDialog progress = null;

        @Override
        protected Void doInBackground(Void... params) {
            applist = checkForLaunchIntent(packageManager.getInstalledApplications(PackageManager.GET_META_DATA));
            listadaptor = new ApplicationAdapter(MainActivity.this,
                    R.layout.snippet_list_row, applist);

            return null;
        }

        @Override
        protected void onCancelled() {
            super.onCancelled();
        }

        @Override
        protected void onPostExecute(Void result) {
            setListAdapter(listadaptor);
            progress.dismiss();
            super.onPostExecute(result);
        }

        @Override
        protected void onPreExecute() {
            progress = ProgressDialog.show(MainActivity.this, null,
                    "Loading application info...");
            super.onPreExecute();
        }

        @Override
        protected void onProgressUpdate(Void... values) {
            super.onProgressUpdate(values);
        }
    }
}

The question involves lot of code to write. So I am giving you an idea about how to move ahead. You can use this idea, customize it and modify it to make it better. Do let me know, if you need further help

For counting variables at a class level:

Create a skeleton for declaration statements:

AccessMode OtherQualifier DataType VariableName EndMarker

where    
    AccessMode       =  { private, public, protected }    
    OtherQualifier   =  { static }    
    DataType         =  { int, char, string, boolean ..}    
    VariableName     =  { anything }    
    EndMarker        =  { ; , }

Write a function to detect whether a line is variable declaration or not

private boolean isLineVariableDeclaration(String line)
{
    this.hasAccessMode(line)
    // call other functions too ..
}

private bool hasAccessMode(String line)
{
    String access = line.Split(" ")[0].toLowerCase();

    // Check if AccessMode list has "access"
    // return true if it exists
}

private bool hasOtherQualifier(String line)
{
    String qualifier = line.Split(" ")[1].toLowerCase();

    // Check if OtherQualifier list has "qualifier"
    // return true if it exists
}

private bool hasDataType(String line)
{
    String dataType = line.Split(" ")[2].toLowerCase();

    // Check if DataType list has "dataType"
    // return true if it exists
}

private bool hasEndMarker(String line)
{
    String endMarker = line.Split(" ")[3].toLowerCase();

    // Statement looks like
    // private static int someVar;
    if(endMarker.Equals(";"))
    {
        // since this is line end
       // return true;
    }
    // Statement looks like
    // private static int someVar, someOtherVar;
    else if(endMarker.Equals(","))
    {
        // this means there are more variables so such type
        // do more to collect them
    }
} 

For counting variables inside a function:

Create a skeleton for declaration statements:

OtherQualifier DataType VariableName EndMarker

where      
    OtherQualifier   =  { static }    
    DataType         =  { int, char, string, boolean ..}    
    VariableName     =  { anything }    
    EndMarker        =  { ; , }

Using similar approach, write function here. For finding presence of "{" and "}" ie to detect function starting and closing do one thing:

  • Set a int bracesCounter = 0;
  • Whenever you encounter a { , increase bracesCounter
  • Whenever you encounter a '}', decrease bracesCounter
  • The moment your bracesCounter is zero again, you are out of function scope

For counting number of if statements:

Create a skeleton for statements:

IF_KEYWORD LEFT_FUNCTION_BRACKET EXPRESSION RIGHT_FUNCTION_BRACKET OTHER

where    
   IF_KEYWORD                    = { if }   
   LEFT_FUNCTION_BRACKET         = { ( }    
   EXPRESSION                    = { WITHOUT_OPERATOR, WITH_OPERATOR }       
   WITHOUT_OPERATOR              = { SIMPLE_OPERAND, OPERAND_WITH_FUNC }      
   SIMPLE_OPERAND                = { OPERAND }    
   OPERAND_WITH_FUNC             = { OPERAND.FUNC(), !OPERAND.FUNC() }     
   WITH_OPERATOR                 = { SIMPLE_OPERAND_WITH_OPERATOR,  OPERAND_WITH_FUNC_OPERATOR }   
   SIMPLE_OPERAND_WITH_OPERATOR  = { LEFT_OPERAND OPERATOR RIGHT_OPERAND }
   OPERAND_WITH_FUNC_OPERATOR    = { OPERAND_WITH_FUNC OPERATOR OPERAND_WITH_FUNC  }    
   LEFT_OPERAND                  = { OPERAND }   
   RIGHT_OPERAND                 = { OPERAND }    
   OPERATOR                      = { !=, ==, >, <, >=, <= }    
   OTHER                         = { RIGHT_CURLY_BRACES, NEW_LINE} 
   RIGHT_CURLY_BRACES            = { { } 
   NEW_LINE                      = { \n } 
so on and so forth..

However, above may seen tedious to you, if your requirement is just to count if's (or while's). So, instead, you can do this

  • On any line if you encounter if check if it followed by (
  • Set brackets = 1
  • Now whenever you encounter ( increase brackets by 1 and whenever you encounter whenever you encounter ) decrease brackets by 1.
  • When brackets become 0 , if condition statement is parsed successfully
  • Please note: Keep on reading lines and lines, until brackets become zero
  • Now, when brackets is 0 see if it is followed by {
  • If yes, again set brackets = 1 Now whenever you encounter { increase brackets by 1 and whenever you encounter whenever you encounter } decrease brackets by 1.
  • When brackets become 0 , if statement is parsed successfully

You are done !

PS Modify the algorithm above to suit your needs

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM