added nimfix tool

This commit is contained in:
Araq
2014-09-05 01:16:48 +02:00
parent 4c870fc293
commit bf557a7cdb
9 changed files with 156 additions and 11 deletions

View File

@@ -139,7 +139,7 @@ proc ropecg(m: BModule, frmt: TFormatStr, args: varargs[PRope]): PRope =
if i - 1 >= start:
app(result, substr(frmt, start, i - 1))
const compileTimeRopeFmt = not defined(booting)
const compileTimeRopeFmt = false
when compileTimeRopeFmt:
import macros
@@ -186,7 +186,7 @@ when compileTimeRopeFmt:
while s[i] in IdentChars: inc i
yield (kind: ffSym, value: substr(s, j, i-1), intValue: 0)
start = i
else: nil
else: discard
while i < length:
if s[i] != '$' and s[i] != '#': inc i
@@ -201,7 +201,7 @@ when compileTimeRopeFmt:
## the compilation of nimrod itself or will the macro execution time
## offset the gains?
result = newCall(bindSym"ropeConcat")
for frag in fmtStringFragments(fmt.strVal):
for frag in fmtStringFragments(fmt):
case frag.kind
of ffSym:
result.add(newCall(bindSym"cgsym", m, newStrLitNode(frag.value)))

View File

@@ -171,7 +171,7 @@ proc addOverloadableSymAt*(scope: PScope, fn: PSym) =
if fn.kind notin OverloadableSyms:
internalError(fn.info, "addOverloadableSymAt")
return
var check = strTableGet(scope.symbols, fn.name)
let check = strTableGet(scope.symbols, fn.name)
if check != nil and check.kind notin OverloadableSyms:
wrongRedefinition(fn.info, fn.name.s)
else:
@@ -187,12 +187,32 @@ proc addInterfaceOverloadableSymAt*(c: PContext, scope: PScope, sym: PSym) =
addOverloadableSymAt(scope, sym)
addInterfaceDeclAux(c, sym)
when defined(nimfix):
import strutils
# when we cannot find the identifier, retry with a changed identifer:
proc altSpelling(x: PIdent): PIdent =
case x.s[0]
of 'A'..'Z': result = getIdent(toLower(x.s[0]) & x.s.substr(1))
of 'a'..'z': result = getIdent(toLower(x.s[0]) & x.s.substr(1))
else: result = x
template fixSpelling(n: PNode; ident: PIdent; op: expr) =
let alt = ident.altSpelling
result = op(c, alt).skipAlias(n)
if result != nil:
prettybase.replaceDeprecated(n.info, ident, alt)
return result
else:
template fixSpelling(n: PNode; ident: PIdent; op: expr) = discard
proc lookUp*(c: PContext, n: PNode): PSym =
# Looks up a symbol. Generates an error in case of nil.
case n.kind
of nkIdent:
result = searchInScopes(c, n.ident).skipAlias(n)
if result == nil:
fixSpelling(n, n.ident, searchInScopes)
localError(n.info, errUndeclaredIdentifier, n.ident.s)
result = errorSym(c, n)
of nkSym:
@@ -201,6 +221,7 @@ proc lookUp*(c: PContext, n: PNode): PSym =
var ident = considerQuotedIdent(n)
result = searchInScopes(c, ident).skipAlias(n)
if result == nil:
fixSpelling(n, ident, searchInScopes)
localError(n.info, errUndeclaredIdentifier, ident.s)
result = errorSym(c, n)
else:
@@ -214,12 +235,13 @@ type
TLookupFlag* = enum
checkAmbiguity, checkUndeclared
proc qualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym =
proc qualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym =
case n.kind
of nkIdent, nkAccQuoted:
var ident = considerQuotedIdent(n)
result = searchInScopes(c, ident).skipAlias(n)
if result == nil and checkUndeclared in flags:
fixSpelling(n, ident, searchInScopes)
localError(n.info, errUndeclaredIdentifier, ident.s)
result = errorSym(c, n)
elif checkAmbiguity in flags and result != nil and
@@ -244,6 +266,7 @@ proc qualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym =
else:
result = strTableGet(m.tab, ident).skipAlias(n)
if result == nil and checkUndeclared in flags:
fixSpelling(n.sons[1], ident, searchInScopes)
localError(n.sons[1].info, errUndeclaredIdentifier, ident.s)
result = errorSym(c, n.sons[1])
elif n.sons[1].kind == nkSym:

View File

@@ -21,3 +21,4 @@ define:useStdoutAsStdmsg
cs:partial
#define:useNodeIds
symbol:nimfix

97
compiler/nimfix.nim Normal file
View File

@@ -0,0 +1,97 @@
#
#
# The Nim Compiler
# (c) Copyright 2014 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
## Nimfix is a tool that helps to convert old-style Nimrod code to Nim code.
import strutils, os, parseopt
import options, commands, modules, sem, passes, passaux, pretty, msgs, nimconf,
extccomp, condsyms
const Usage = """
Nimfix - Tool to patch Nim code
Usage:
nimfix [options] projectflie.nim
Options:
--overwriteFiles:on|off overwrite the original nim files.
DEFAULT is ON!
--checkExtern:on|off style check also extern names
--styleCheck:none|confirm|auto performs style checking for identifiers
and suggests an alternative spelling. If
'auto', it automatically corrects the
spelling. If 'confirm' it asks the user.
In addition, all command line options of Nim are supported.
"""
proc mainCommand =
#msgs.gErrorMax = high(int) # do not stop after first error
registerPass verbosePass
registerPass semPass
registerPass prettyPass
gCmd = cmdPretty
compileProject()
pretty.overwriteFiles()
proc processCmdLine*(pass: TCmdLinePass, cmd: string) =
var p = parseopt.initOptParser(cmd)
var argsCount = 0
while true:
parseopt.next(p)
case p.kind
of cmdEnd: break
of cmdLongoption, cmdShortOption:
case p.key.normalize
of "overwritefiles":
case p.val.normalize
of "on": gOverWrite = true
of "off": gOverWrite = false
else: localError(gCmdLineInfo, errOnOrOffExpected)
of "checkextern":
case p.val.normalize
of "on": gCheckExtern = true
of "off": gCheckExtern = false
else: localError(gCmdLineInfo, errOnOrOffExpected)
of "stylecheck":
case p.val.normalize
of "none": gStyleCheck = StyleCheck.None
of "confirm": gStyleCheck = StyleCheck.Confirm
of "auto": gStyleCheck = StyleCheck.Auto
else: localError(gCmdLineInfo, errGenerated,
"'none', 'confirm' or 'auto' expected")
else:
processSwitch(pass, p)
of cmdArgument:
if processArgument(pass, p, argsCount): break
proc handleCmdLine() =
if paramCount() == 0:
stdout.writeln(Usage)
else:
processCmdLine(passCmd1, "")
if gProjectName != "":
try:
gProjectFull = canonicalizePath(gProjectName)
except OSError:
gProjectFull = gProjectName
var p = splitFile(gProjectFull)
gProjectPath = p.dir
gProjectName = p.name
else:
gProjectPath = getCurrentDir()
loadConfigs(DefaultConfig) # load all config files
# now process command line arguments again, because some options in the
# command line can overwite the config file's settings
extccomp.initVars()
processCmdLine(passCmd2, "")
mainCommand()
condsyms.initDefines()
defineSymbol "nimfix"
handleCmdline()

16
compiler/nimfix.nim.cfg Normal file
View File

@@ -0,0 +1,16 @@
# Special configuration file for the Nim project
# gc:markAndSweep
hint[XDeclaredButNotUsed]:off
path:"$projectPath/.."
path:"$lib/packages/docutils"
define:useStdoutAsStdmsg
symbol:nimfix
define:nimfix
cs:partial
#define:useNodeIds
define:booting
define:noDocgen

View File

@@ -7,7 +7,7 @@
# distribution, for details about the copyright.
#
import ast, msgs, strutils
import ast, msgs, strutils, idents
type
TSourceFile* = object
@@ -41,7 +41,7 @@ proc differ*(line: string, a, b: int, x: string): bool =
let y = line[a..b]
result = cmpIgnoreStyle(y, x) == 0 and y != x
proc replaceDeprecated*(info: TLineInfo; oldSym, newSym: PSym) =
proc replaceDeprecated*(info: TLineInfo; oldSym, newSym: PIdent) =
loadFile(info)
let line = gSourceFiles[info.fileIndex].lines[info.line-1]
@@ -53,7 +53,10 @@ proc replaceDeprecated*(info: TLineInfo; oldSym, newSym: PSym) =
if line[first] == '`': inc first
let last = first+identLen(line, first)-1
if cmpIgnoreStyle(line[first..last], oldSym.name.s) == 0:
var x = line.substr(0, first-1) & newSym.name.s & line.substr(last+1)
if cmpIgnoreStyle(line[first..last], oldSym.s) == 0:
var x = line.substr(0, first-1) & newSym.s & line.substr(last+1)
system.shallowCopy(gSourceFiles[info.fileIndex].lines[info.line-1], x)
gSourceFiles[info.fileIndex].dirty = true
proc replaceDeprecated*(info: TLineInfo; oldSym, newSym: PSym) =
replaceDeprecated(info, oldSym.name, newSym.name)

View File

@@ -1482,6 +1482,9 @@ proc argtypeMatches*(c: PContext, f, a: PType): bool =
include suggest
when not declared(tests):
template tests(s: stmt) {.immediate.} = discard
tests:
var dummyOwner = newSym(skModule, getIdent("test_module"), nil, UnknownLineInfo())

View File

@@ -1138,7 +1138,7 @@ template needsAdditionalCopy(n): expr =
not c.isTemp(dest) and not fitsRegister(n.typ)
proc skipDeref(n: PNode): PNode =
result = if n.kind in {nkDerefExpr, nkHiddenDeref}: n.sons[0] else n
result = if n.kind in {nkDerefExpr, nkHiddenDeref}: n.sons[0] else: n
proc preventFalseAlias(c: PCtx; n: PNode; opc: TOpcode;
dest, idx, value: TRegister) =

View File

@@ -13,7 +13,9 @@ cc = gcc
arm.linux.gcc.exe = "arm-linux-gcc"
arm.linux.gcc.linkerexe = "arm-linux-gcc"
cs:partial
@if not nimfix:
cs:partial
@end
path="$lib/core"
path="$lib/pure"