codepad
[
create a new paste
]
login
|
about
Language:
C
C++
D
Haskell
Lua
OCaml
PHP
Perl
Plain Text
Python
Ruby
Scheme
Tcl
""" Notepad++ Python Script script to add setters and getters to C++ classes Copyright (C) 2013 George Snyder This script is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License (GNU GPL) as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. The code is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU GPL for more details. As additional permission under GNU GPL version 3 section 7, you may distribute non-source (e.g., minimized or compacted) forms of that code without the copy of the GNU GPL normally required by section 4, provided you include this license notice and a URL through which recipients can access the Corresponding Source. """ from Npp import notepad,console,editor import re,pprint # only deal with C++ files if (re.match(".*\\.cpp$", notepad.getCurrentFilename())): # parse the editor text into statements, blocks (including labeled sections) blocks = [] structure = blocks blockPath = [{'children':blocks, 'blockType':'root', 'text': '', 'start':0,'end':editor.getLength()}] statementStart = 0 depth = 0 inComment = False inQuote = False quoteChar = "" quoteStrings = ["'", '"'] for i in range(0, editor.getLength()): line = editor.getLine(editor.lineFromPosition(i)) c = "%c" % editor.getCharAt(i) if re.match('\\s*(//.*)?$', line): # line is a comment, skip it i = editor.getLineEndPosition(editor.lineFromPosition(i)) elif c == '/' and editor.getCharAt(i+1) == '*': inComment = True elif inComment and editor.getTextRange(i, i+2) == "*/": inComment = False elif inComment == True: continue elif inQuote: if c in quoteStrings: inQuote = False elif c in quoteStrings: inQuote = True quoteChar = c elif c == ';': tmp = {'blockType': 'statement', 'text': editor.getTextRange(statementStart, i).strip(), 'start': statementStart, 'end': i} blocks.append(tmp) statementStart = i+1 elif c == '{': depth += 1 tmp = {'blockType': 'regular', 'text': editor.getTextRange(statementStart, i).strip(), 'children': [], 'start': statementStart, 'end': -1} blocks.append(tmp) blockPath.append(tmp) blocks = tmp['children'] statementStart = i+1 elif c == '}': if blockPath[len(blockPath)-1]['blockType'] == 'label': terminated = 2 else: terminated = 1 depth -= terminated if depth < 0: console.write("Invalid C++, too many closing curly braces at line %d\n" % editor.lineFromPosition(i)) break for j in range(0, terminated): blockPath.pop()['end'] = i blocks = blockPath[len(blockPath)-1]['children'] statementStart = i+1 elif c == ':': if blockPath[len(blockPath)-1]['blockType'] != 'label': depth += 1 else: blockPath.pop()['end'] = statementStart blocks = blockPath[len(blockPath)-1]['children'] tmp = {'blockType': 'label', 'text': re.match('.*(?:\A|\W)([a-z]\w*):', line).group(1), 'children': [], 'start': statementStart, 'end': -1} blocks.append(tmp) blockPath.append(tmp) blocks = tmp['children'] statementStart = i+1 if depth > 0: console.write("Invalid C++, too many opening curly braces.\n") # find the 'class' block that contains our cursor currentPosition = editor.getCurrentPos() classBlock = None for block in structure: if block['text'].startswith('class') and block['start'] < currentPosition and block['end'] > currentPosition: classBlock = block break if classBlock == None: console.write("You (position %d) don't appear to be inside a class, we don't know which class needs setters!\n" % currentPosition) else: # find the 'private' and 'public' 'block's in that block privateBlock = None publicBlock = None for block in classBlock['children']: if block['blockType'] == 'label': if block['text'] == 'private': privateBlock = block if block['text'] == 'public': publicBlock = block # create a list of all private variable names privateVars = [] if privateBlock != None: # find indentation indentation = re.match('.*[\n\r]*?([\t ]*)\w.*', editor.getTextRange(privateBlock['start'], privateBlock['end']), flags=re.MULTILINE).group(1) indentBase = re.match('.*[\n\r]*?([\t ]*)\w.*', editor.getTextRange(privateBlock['children'][0]['start'], privateBlock['children'][0]['end']), flags=re.MULTILINE).group(1) for i in range(0, len(privateBlock['children'])): if privateBlock['children'][i]['blockType'] == 'statement': m = re.match('\s*(?P<dataType>\w+)\s+(?P<varName>\w+)\s*', privateBlock['children'][i]['text']) if m: privateVars.append([m.group('dataType'), m.group('varName')]) else: console.write("Could not find the private label") # make a list of already created setters and getters changes = {} existingMethods = [] if publicBlock != None: for i in range(0, len(publicBlock['children'])): if publicBlock['children'][i]['blockType'] == 'regular': m = re.match('\s*(?P<datatype>\w+)\s+(?P<methodName>(?P<type>set|get)(?P<varName>\w+))\(.*', publicBlock['children'][i]['text']) if m: existingMethods.append(m.group('datatype') + m.group('methodName')) else: console.write("Could not find the public label") # prepend setters and getters that aren't already created if publicBlock != None: insertPoint = publicBlock['children'][0]['start'] changes[insertPoint] = "" else: insertPoint = privateBlock['end'] if len(privateVars) == 0: changes[insertPoint] = "\r\npublic:" # add public label if it doesn't exist for var in privateVars: formatVars = {'base': indentBase, 'indent': indentation, 'capName': var[1].capitalize(), 'dType': var[0], 'vName': var[1]} if not ("voidset%s" % (var[1].capitalize()) in existingMethods): changes[insertPoint] += "\r\n%(base)svoid set%(capName)s(%(dType)s %(vName)s) {\r\n%(base)s%(indent)sthis->%(vName)s = %(vName)s;\r\n%(base)s}" % formatVars console.write("Adding setter 'void set%(capName)s(%(dType)s)'\n" % formatVars) for var in privateVars: formatVars = {'base': indentBase, 'indent': indentation, 'capName': var[1].capitalize(), 'dType': var[0], 'vName': var[1]} if not ("%sget%s" % (var[0], var[1].capitalize()) in existingMethods): changes[insertPoint] += "\r\n%(base)s%(dType)s get%(capName)s() {\r\n%(base)s%(indent)sreturn %(vName)s\r\n%(base)s}" % formatVars console.write("Adding getter '%(dType)s get%(capName)s()'\n" % formatVars) # apply changes changeOrder = changes.keys() changeOrder.sort(reverse=True) for key in changeOrder: editor.insertText(key, changes[key]) else: console.write("Currently only C++ is supported for adding setters and getters. Might work on other languages if you disable this check. Feel free to modify the script.\n")
Private
[
?
]
Run code
Submit