File: Make_Get_and_Set_Methods.bsh

package info (click to toggle)
jedit 5.5.0%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 14,720 kB
  • sloc: java: 103,377; xml: 96,521; makefile: 43; sh: 42; cpp: 6; python: 6
file content (426 lines) | stat: -rw-r--r-- 16,017 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
/**
Make_Get_and_Set_Functions.bsh - a BeanShell macro for
the jEdit text editor  that creates simple get() and set()
methods for the variables on selected lines.

Copyright (C)  2004 Thomas Galvin - software@thomas-galvin.com
based on Make_Get_and_Set_Methods.bsh by John Gellene

This macro will work on multiple selected lines; for instance,
selecting

<code>
public int foo;
public int bar;
</code>

and running the macro will produce get and set functions for both
variables, along with comments.  This macro produces c-style
functions, unless the buffer is in java mode.

Modifications by Dale Anson, Dec 2008:

1. Allows variable declarations to have an initial assignment, like
<code>
public int foo = 1;
public int bar = 2;
</code>

2. Allows multiple variables on same line, like
<code>
public int foo, bar;
</code>

3. Use line separator as set in buffer properties rather than always using \n.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
*/

// Localization
final static String DONE = jEdit.getProperty("macro.rs.MakeGetAndSetMethods.GenerateCode.label", "Generate Code");
final static String CANCEL = jEdit.getProperty("common.cancel");
final static String CreateGetMethodsLabel = jEdit.getProperty("macro.rs.MakeGetAndSetMethods.CreateGetMethods.label", "Create Get Methods");
final static String CreateSetMethodsLabel = jEdit.getProperty("macro.rs.MakeGetAndSetMethods.CreateSetMethods.label", "Create Set Methods");
final static String CreateGetandSetMethodsLabel = jEdit.getProperty("macro.rs.MakeGetAndSetMethods.CreateGetandSetMethods.label", "Create Get and Set Methods");
    
//Process
boolean JAVA_MODE = buffer.getMode().getName().equals( "java" );

// use line separator from current buffer
String LS = buffer.getStringProperty( "lineSeparator" );
if (LS == null) {
    // otherwise, use default line separator
    LS = jEdit.getProperty("buffer.lineSeparator");   
}

boolean createGetMethods = true;
boolean createSetMethods = true;

void setCaret( int selectionStart, int selectionEnd ) {
    textArea.setCaretPosition( selectionStart );
    textArea.moveCaretPosition( selectionEnd );
}

String getClassName() {
    int selectionStart;
    int selectionEnd;
    if(textArea.getSelection().length != 0){  // if there are selections exists
        selectionStart = textArea.getSelection(0).getStart();
        selectionEnd = textArea.getSelection(0).getEnd();
    }
    else {		// if no selection
        selectionStart = textArea.getCaretPosition();
        selectionEnd = textArea.getCaretPosition();
    }

    String text = textArea.getText();
    int index = text.lastIndexOf( "class", selectionStart );
    if ( index != -1 ) {
        textArea.setCaretPosition( index );
        int lineNumber = textArea.getCaretLine();
        int lineEnd = textArea.getLineEndOffset( lineNumber );
        String lineText = text.substring( index, lineEnd );

        StringTokenizer tokenizer = new StringTokenizer( lineText );
        tokenizer.nextToken(); //eat "class"
        if ( tokenizer.hasMoreTokens() ) {
            setCaret( selectionStart, selectionEnd );
            return tokenizer.nextToken();
        }
    }
    setCaret( selectionStart, selectionEnd );

    String fileClassName = buffer.getName();
    int index = fileClassName.lastIndexOf( '.' );
    if ( index != -1 ) {
        fileClassName = fileClassName.substring( 0, index );
        if ( fileClassName.toLowerCase().indexOf( "untitled" ) == -1 ) {
            return fileClassName;
        }
    }

    return "";
}

String createJavaGetMethod( String type, String variableName ) {
    String uppperVariable = Character.toUpperCase( variableName.charAt( 0 ) ) + variableName.substring( 1, variableName.length() );
    String result =
        "\t/**" + LS +
        "\t * Returns the value of " + variableName + "." + LS +
        "\t */" + LS +
        "\tpublic " + type + " get" + uppperVariable + "() {" + LS +
        "\t\treturn " + variableName + ";" + LS +
        "\t}" + LS;

    return result;
}

String createJavaSetMethod( String type, String variableName ) {
    String uppperVariable = Character.toUpperCase( variableName.charAt( 0 ) ) + variableName.substring( 1, variableName.length() );
    String result =
        "\t/**" + LS +
        "\t * Sets the value of " + variableName + "." + LS +
        "\t * @param " + variableName + " The value to assign " + variableName + "." + LS +
        "\t */" + LS +
        "\tpublic void set" + uppperVariable + "(" + type + " " + variableName + ") {" + LS +
        "\t\tthis." + variableName + " = " + variableName + ";" + LS +
        "\t}" + LS;

    return result;
}

String createCppGetMethod( String className, String type, String variableName ) {
    String scopeIndicator = "";
    if ( className != null && className.compareTo( "" ) != 0 ) {
        scopeIndicator = className + "::";
    }
    if (type == null) {
        type = "";   
    }
    String uppperVariable = Character.toUpperCase( variableName.charAt( 0 ) ) + variableName.substring( 1, variableName.length() );
    String result =
        "/*" + LS +
        "function: get" + uppperVariable + "()" + LS +
        "Returns the value of " + variableName + "." + LS +
        "*/" + LS +
        type + (type.length() > 0 ? " " : "") + scopeIndicator + "get" + uppperVariable + "()" + "" + LS +
        "{" + "" + LS +
        "  return " + variableName + ";" + "" + LS +
        "}" + LS;

    return result;
}

String createCppSetMethod( String className, String type, String variableName ) {
    String scopeIndicator = "";
    if ( className != null && className.compareTo( "" ) != 0 ) {
        scopeIndicator = className + "::";
    }

    String uppperVariable = Character.toUpperCase( variableName.charAt( 0 ) ) + variableName.substring( 1, variableName.length() );
    String setVariable = variableName + "Value";
    String result =
        "/*" + LS +
        "function: set" + uppperVariable + "()" + LS +
        "Sets the value of " + variableName + "." + LS +
        "Input: " + setVariable + " The value to assign " + variableName + "." + LS +
        "*/" + LS +
        "void " + scopeIndicator + "set" + uppperVariable + "(const " + type + "& " + setVariable + ")" + LS +
        "{" + "" + LS +
        "  " + variableName + " = " + setVariable + ";" + "" + LS +
        "}" + LS;

    return result;
}

void parseSelection() {
    // offsets from start of buffer
    int selectionStart;
    int selectionEnd;
    if (textArea.getSelection().length() == 0) {
        // no selection, use current line
        selectionStart = textArea.getLineStartOffset(textArea.getCaretLine());
        selectionEnd = textArea.getLineEndOffset(textArea.getCaretLine());
    }
    else {
        selectionStart = textArea.getSelection(0).getStart();
        selectionEnd = textArea.getSelection(0).getEnd();
    }

    StringBuffer code = new StringBuffer();
    String className = getClassName();
    
    // remove comments and blank lines
    ArrayList lines = stripComments(buffer, selectionStart, selectionEnd);
    if (lines.size() == 0) {
        return;   
    }
    
    // parse each line for variable declaration. Lines are already trimmed and
    // have all comments removed.
    for (int i = 0; i < lines.size(); i++) {
        String lineText = lines.get(i);
        
        // combine lines up to next semi-colon into a single line
        while(!lineText.endsWith(";") && i < lines.size()) {
            lineText += lines.get(++i);   
        }
        
        // ensure line contains at least two words, that is, a type
        // and a variable name at minimum. This is a fairly lame check in that
        // "public int" would qualify, but it does mean that I don't have to
        // do so much bounds checking below.
        if (!lineText.matches("\\S+\\s+[_A-Za-z0-9$]+.*?")) {
            continue;   
        }
        
        // remove semi-colon
        if ( lineText.endsWith( ";" ) ) {
            lineText = lineText.substring( 0, lineText.length() - 1 );
        }
        lineText = lineText.trim();
        if ( lineText.length() == 0 ) {
            continue;
        }
        
        // list to hold variable names
        ArrayList variables = new ArrayList();
        
        // the variable type
        String type = "";
        
        // could have declaration like "int x, y = 6;", which is why there
        // needs to be an array for the variable names
        if ( lineText.indexOf( "," ) > 0 ) {
            int comma = lineText.indexOf(",");
            String front = lineText.substring(0, comma);        // everything before the first comma
            if (front.indexOf("=") > 0) {
                front = front.substring(0, front.indexOf("=")); // drop the initial value  
            }
            front = front.trim();
            String[] fronts = front.split("\\s+");
            variables.add(fronts[fronts.length - 1]);           // last item in array is variable name
            type = fronts[fronts.length - 2];                   // next to last item is type

            String back = lineText.substring(comma + 1);        // everything after the first comma
            String[] backs = back.split(",");
            for (back : backs) {
                back = back.trim();
                String[] parts = back.split("\\s+");            // could have initializer with spaces
                String var = extractVar(parts[0]);              // could have i=0, ie, no spaces
                variables.add(var);   
            }
        }
        else {
            // just one variable declared, may be initialized
            if (lineText.indexOf("=") > 0) {
                lineText = lineText.substring(0, lineText.indexOf("="));    // drop the intial value
            }
            lineText = lineText.trim();
            String[] parts = lineText.split("\\s+");
            variables.add(extractVar(parts[parts.length - 1])); // last item in array is variable name
            type = parts[parts.length - 2];                     // next to last item is type
        }
        
        type = type.trim();
        
        if (variables.size() == 0) {
            continue;   
        }
        code.append( LS );

        // create the get and set methods for each variable
        for ( String variable : variables ) {
            if ( createGetMethods ) {
                String tmp = JAVA_MODE ? createJavaGetMethod( type, variable ) : createCppGetMethod( className, type, variable );
                if ( tmp != null && tmp.length() > 0 ) {
                    code.append( tmp ).append( LS );
                }
            }

            if ( createSetMethods && lineText.indexOf( "final " ) == -1 && lineText.indexOf( "const " ) == -1 ) {
                String tmp = JAVA_MODE ? createJavaSetMethod( type, variable ) : createCppSetMethod( className, type, variable );
                if ( tmp != null && tmp.compareTo( "" ) != 0 ) {
                    code.append( LS ).append( tmp ).append( LS );
                }
            }
        }
    }

    String toInsert = code.toString();
    if (toInsert.trim().length() == 0) {
        return;   
    }
    
    // move to the end of the selected text
    textArea.setCaretPosition( selectionEnd );

    // insert get/set methods
    textArea.setSelectedText( toInsert );

    // select the inserted code and indent it
    textArea.setCaretPosition( selectionEnd );
    textArea.moveCaretPosition( selectionEnd + code.length(), true );
    textArea.indentSelectedLines();
}

import org.gjt.sp.jedit.syntax.*;

// Given the buffer and start and end of the selection, remove comments and 
// blank lines, then return a list of the remaining lines. The list contains 
// the trimmed line text.
ArrayList stripComments( Buffer buffer, int startOffset, int endOffset ) {
    int firstLine = buffer.getLineOfOffset(startOffset);
    
    // the last line may not actually have anything selected, just the caret
    // happens to be at the start of the line or include part of the whitespace
    // at the start of the line. In this case, don't include the last line.
    int lastLine = buffer.getLineOfOffset(endOffset);
    String lastLineText = buffer.getText(buffer.getLineStartOffset(lastLine), endOffset - buffer.getLineStartOffset(lastLine));
    if (lastLineText.trim().length() == 0) {
        --lastLine;   
    }
    
    ArrayList lines = new ArrayList();
    DefaultTokenHandler tokenHandler = new DefaultTokenHandler();
    StringBuilder lineBuffer = new StringBuilder();
    
    for ( int lineNum = firstLine; lineNum <= lastLine; lineNum++ ) {
        int lineStart = buffer.getLineStartOffset(lineNum);
        lineBuffer.delete(0, lineBuffer.length());

        tokenHandler.init();
        buffer.markTokens( lineNum, tokenHandler );
        Token token = tokenHandler.getTokens();
        
        // skip comments
        while(token.id != Token.END) {
            if (token.id < Token.COMMENT1 || token.id > Token.COMMENT4) {
                lineBuffer.append(buffer.getText(lineStart + token.offset, token.length));
            }
            token = token.next;   
        }
        
        String line = lineBuffer.toString().trim();
        
        // skip blank lines
        if (line.length() > 0) {
            lines.add(line.trim());
        }
    }
    return lines;
} 

boolean isWhitespace(Token token) {
    String text = buffer.getText(token.offset, token.length);
    return text.trim().length() == 0;
}

// given something line "a = 6", returns just the "a". 
String extractVar(String var) {
    if (var == null) {
        return "";   
    }
    var = var.trim();
    if (var.indexOf("=") > 0) {
        var = var.substring(0, var.indexOf("=")).trim();
    }
    return var;
}

void displayPrompt() {
    JCheckBox getCheckbox = new JCheckBox( CreateGetMethodsLabel, true );
    JCheckBox setCheckbox = new JCheckBox( CreateSetMethodsLabel, true );

    JPanel checkBoxPanel = new JPanel(new BorderLayout());
    checkBoxPanel.setBorder(BorderFactory.createEmptyBorder(6, 6, 6, 6));
    checkBoxPanel.add( getCheckbox, BorderLayout.NORTH );
    checkBoxPanel.add( setCheckbox, BorderLayout.SOUTH );

    JButton createButton = new JButton( DONE );
    JButton cancelButton = new JButton( CANCEL );

    JPanel buttonPanel = new JPanel(new GridLayout(1, 2, 6, 0));
    buttonPanel.setBorder(BorderFactory.createEmptyBorder(11, 11, 11, 11));
    buttonPanel.add( createButton, BorderLayout.WEST );
    buttonPanel.add( cancelButton, BorderLayout.EAST );

    JPanel mainPanel = new JPanel();
    mainPanel.setLayout( new BorderLayout() );
    mainPanel.add( checkBoxPanel, BorderLayout.NORTH );
    mainPanel.add( buttonPanel, BorderLayout.SOUTH );

    JDialog dialog = new JDialog( view, CreateGetandSetMethodsLabel, false );
    dialog.setContentPane( mainPanel );

    actionPerformed( ActionEvent e ) {
        if ( e.getSource() == createButton ) {
            createGetMethods = getCheckbox.isSelected();
            createSetMethods = setCheckbox.isSelected();
            parseSelection();
        }
        this.dialog.dispose();
        return ;
    }

    createButton.addActionListener( this );
    cancelButton.addActionListener( this );

    dialog.pack();
    dialog.setLocationRelativeTo( view );
    dialog.setDefaultCloseOperation( JDialog.DISPOSE_ON_CLOSE );
    dialog.setVisible( true );
    createButton.requestFocus();
}


final static String NotEditableMessage = jEdit.getProperty("macro.rs.general.ErrorNotEditableDialog.message", "Buffer is not editable");
    displayPrompt();