diff options
author | Araq <rumpf_a@web.de> | 2012-07-30 23:07:19 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2012-07-30 23:07:19 +0200 |
commit | 674c05f426d586deba1401270f78b74c22c540bc (patch) | |
tree | 320432ef06fcfc607ef0e65ab416b84c03803716 | |
parent | b0c11d3efbcfc3cd2e8d852ec196930ebace91ad (diff) | |
download | Nim-674c05f426d586deba1401270f78b74c22c540bc.tar.gz |
made compiler more robust for idetools; implemented idetools.usages
-rwxr-xr-x | compiler/commands.nim | 5 | ||||
-rwxr-xr-x | compiler/nimsets.nim | 20 | ||||
-rwxr-xr-x | compiler/options.nim | 1 | ||||
-rwxr-xr-x | compiler/renderer.nim | 4 | ||||
-rwxr-xr-x | compiler/semdata.nim | 8 | ||||
-rwxr-xr-x | compiler/semexprs.nim | 22 | ||||
-rwxr-xr-x | compiler/semstmts.nim | 10 | ||||
-rwxr-xr-x | compiler/semtypes.nim | 9 | ||||
-rwxr-xr-x | compiler/sigmatch.nim | 28 | ||||
-rwxr-xr-x | compiler/suggest.nim | 33 | ||||
-rwxr-xr-x | doc/advopt.txt | 3 |
11 files changed, 96 insertions, 47 deletions
diff --git a/compiler/commands.nim b/compiler/commands.nim index db0469e94..b7c64eb4b 100755 --- a/compiler/commands.nim +++ b/compiler/commands.nim @@ -455,7 +455,10 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) = of "context": expectNoArg(switch, arg, pass, info) incl(gGlobalOptions, optContext) - of "stdout": + of "usages": + expectNoArg(switch, arg, pass, info) + incl(gGlobalOptions, optUsages) + of "stdout": expectNoArg(switch, arg, pass, info) incl(gGlobalOptions, optStdout) else: diff --git a/compiler/nimsets.nim b/compiler/nimsets.nim index d475c7b59..282188c64 100755 --- a/compiler/nimsets.nim +++ b/compiler/nimsets.nim @@ -31,7 +31,9 @@ proc cardSet*(s: PNode): BiggestInt # implementation proc inSet(s: PNode, elem: PNode): bool = - if s.kind != nkCurly: InternalError(s.info, "inSet") + if s.kind != nkCurly: + InternalError(s.info, "inSet") + return false for i in countup(0, sonsLen(s) - 1): if s.sons[i].kind == nkRange: if leValue(s.sons[i].sons[0], elem) and @@ -48,17 +50,19 @@ proc overlap(a, b: PNode): bool = result = leValue(a.sons[0], b.sons[1]) and leValue(b.sons[1], a.sons[1]) or leValue(a.sons[0], b.sons[0]) and leValue(b.sons[0], a.sons[1]) - else: + else: result = leValue(a.sons[0], b) and leValue(b, a.sons[1]) - else: - if b.kind == nkRange: + else: + if b.kind == nkRange: result = leValue(b.sons[0], a) and leValue(a, b.sons[1]) - else: + else: result = sameValue(a, b) proc SomeInSet(s: PNode, a, b: PNode): bool = # checks if some element of a..b is in the set s - if s.kind != nkCurly: InternalError(s.info, "SomeInSet") + if s.kind != nkCurly: + InternalError(s.info, "SomeInSet") + return false for i in countup(0, sonsLen(s) - 1): if s.sons[i].kind == nkRange: if leValue(s.sons[i].sons[0], b) and leValue(b, s.sons[i].sons[1]) or @@ -164,7 +168,9 @@ proc cardSet(s: PNode): BiggestInt = Inc(result) proc SetHasRange(s: PNode): bool = - if s.kind != nkCurly: InternalError(s.info, "SetHasRange") + if s.kind != nkCurly: + InternalError(s.info, "SetHasRange") + return false for i in countup(0, sonsLen(s) - 1): if s.sons[i].kind == nkRange: return true diff --git a/compiler/options.nim b/compiler/options.nim index 91f7f778d..de257aa15 100755 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -51,6 +51,7 @@ type # please make sure we have under 32 options optSuggest, # ideTools: 'suggest' optContext, # ideTools: 'context' optDef, # ideTools: 'def' + optUsages, # ideTools: 'usages' optThreadAnalysis, # thread analysis pass optTaintMode, # taint mode turned on optTlsEmulation, # thread var emulation turned on diff --git a/compiler/renderer.nim b/compiler/renderer.nim index 5d8a04198..a1a6de984 100755 --- a/compiler/renderer.nim +++ b/compiler/renderer.nim @@ -338,7 +338,9 @@ proc atom(n: PNode): string = of nkType: if (n.typ != nil) and (n.typ.sym != nil): result = n.typ.sym.name.s else: result = "[type node]" - else: InternalError("rnimsyn.atom " & $n.kind) + else: + InternalError("rnimsyn.atom " & $n.kind) + result = "" proc lcomma(n: PNode, start: int = 0, theEnd: int = - 1): int = assert(theEnd < 0) diff --git a/compiler/semdata.nim b/compiler/semdata.nim index 26552c294..ebae06ea1 100755 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -146,14 +146,16 @@ proc PushOwner(owner: PSym) = proc PopOwner() = var length = len(gOwners) - if (length <= 0): InternalError("popOwner") - setlen(gOwners, length - 1) + if length > 0: setlen(gOwners, length - 1) + else: InternalError("popOwner") proc lastOptionEntry(c: PContext): POptionEntry = result = POptionEntry(c.optionStack.tail) proc pushProcCon*(c: PContext, owner: PSym) {.inline.} = - if owner == nil: InternalError("owner is nil") + if owner == nil: + InternalError("owner is nil") + return var x: PProcCon new(x) x.owner = owner diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index a82852089..1ed1776ee 100755 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -118,8 +118,10 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = LocalError(n.info, errIllegalCaptureX, s.name.s) result = newSymNode(s, n.info) of skGenericParam: - if s.ast == nil: InternalError(n.info, "no default for") - result = semExpr(c, s.ast) + if s.ast != nil: result = semExpr(c, s.ast) + else: + InternalError(n.info, "no default for") + result = emptyNode of skType: markUsed(n, s) result = newSymNode(s, n.info) @@ -322,14 +324,17 @@ proc changeType(n: PNode, newType: PType) = of nkPar: if newType.kind != tyTuple: InternalError(n.info, "changeType: no tuple type for constructor") - if newType.n == nil: nil + elif newType.n == nil: nil elif sonsLen(n) > 0 and n.sons[0].kind == nkExprColonExpr: for i in countup(0, sonsLen(n) - 1): var m = n.sons[i].sons[0] if m.kind != nkSym: internalError(m.info, "changeType(): invalid tuple constr") + return var f = getSymFromList(newType.n, m.sym.name) - if f == nil: internalError(m.info, "changeType(): invalid identifier") + if f == nil: + internalError(m.info, "changeType(): invalid identifier") + return changeType(n.sons[i].sons[1], f.typ) else: for i in countup(0, sonsLen(n) - 1): @@ -485,7 +490,9 @@ proc analyseIfAddressTaken(c: PContext, n: PNode): PNode = result = newHiddenAddrTaken(c, n) of nkDotExpr: checkSonsLen(n, 2) - if n.sons[1].kind != nkSym: internalError(n.info, "analyseIfAddressTaken") + if n.sons[1].kind != nkSym: + internalError(n.info, "analyseIfAddressTaken") + return if skipTypes(n.sons[1].sym.typ, abstractInst).kind != tyVar: incl(n.sons[1].sym.flags, sfAddrTaken) result = newHiddenAddrTaken(c, n) @@ -590,6 +597,7 @@ proc semOverloadedCallAnalyseEffects(c: PContext, n: PNode, nOrig: PNode, if result != nil: if result.sons[0].kind != nkSym: InternalError("semDirectCallAnalyseEffects") + return let callee = result.sons[0].sym case callee.kind of skMacro, skTemplate: nil @@ -1225,8 +1233,8 @@ proc semIfExpr(c: PContext, n: PNode): PNode = of nkElseExpr: checkSonsLen(it, 1) it.sons[0] = semExprWithType(c, it.sons[0]) - if typ == nil: InternalError(it.info, "semIfExpr") - it.sons[0] = fitNode(c, typ, it.sons[0]) + if typ != nil: it.sons[0] = fitNode(c, typ, it.sons[0]) + else: InternalError(it.info, "semIfExpr") else: illFormedAst(n) result.typ = typ diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 33d0d4f5c..c82e7d8de 100755 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -29,7 +29,7 @@ proc semWhen(c: PContext, n: PNode, semCheck = true): PNode = checkSonsLen(it, 2) var e = semConstExpr(c, it.sons[0]) if e.kind != nkIntLit: InternalError(n.info, "semWhen") - if e.intVal != 0 and result == nil: + elif e.intVal != 0 and result == nil: setResult(it.sons[1]) of nkElse, nkElseExpr: checkSonsLen(it, 1) @@ -514,8 +514,8 @@ proc addGenericParamListToScope(c: PContext, n: PNode) = InternalError(n.info, "addGenericParamListToScope") for i in countup(0, sonsLen(n)-1): var a = n.sons[i] - if a.kind != nkSym: internalError(a.info, "addGenericParamListToScope") - addDecl(c, a.sym) + if a.kind == nkSym: addDecl(c, a.sym) + else: internalError(a.info, "addGenericParamListToScope") proc typeSectionLeftSidePass(c: PContext, n: PNode) = # process the symbols on the left side for the whole type section, before @@ -628,8 +628,8 @@ proc semParamList(c: PContext, n, genericParams: PNode, s: PSym) = proc addParams(c: PContext, n: PNode, kind: TSymKind) = for i in countup(1, sonsLen(n)-1): - if (n.sons[i].kind != nkSym): InternalError(n.info, "addParams") - addParamOrResult(c, n.sons[i].sym, kind) + if n.sons[i].kind == nkSym: addParamOrResult(c, n.sons[i].sym, kind) + else: InternalError(n.info, "addParams") proc semBorrow(c: PContext, n: PNode, s: PSym) = # search for the correct alias: diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 3a3b0d722..a0e2283a3 100755 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -367,7 +367,7 @@ proc semRecordCase(c: PContext, n: PNode, check: var TIntSet, pos: var int, checkMinSonsLen(n, 2) semRecordNodeAux(c, n.sons[0], check, pos, a, rectype) if a.sons[0].kind != nkSym: - internalError("semRecordCase: dicriminant is no symbol") + internalError("semRecordCase: discriminant is no symbol") return incl(a.sons[0].sym.flags, sfDiscriminant) var covered: biggestInt = 0 @@ -412,7 +412,7 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var TIntSet, pos: var int, if c.InGenericContext == 0: var e = semConstBoolExpr(c, it.sons[0]) if e.kind != nkIntLit: InternalError(e.info, "semRecordNodeAux") - if e.intVal != 0 and branch == nil: branch = it.sons[1] + elif e.intVal != 0 and branch == nil: branch = it.sons[1] else: it.sons[0] = forceBool(c, semExprWithType(c, it.sons[0])) of nkElse: @@ -735,6 +735,7 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType = isConcrete = false elif s.typ.containerID == 0: InternalError(n.info, "semtypes.semGeneric") + return errorType(c) elif sonsLen(n) != sonsLen(s.typ): LocalError(n.info, errWrongNumberOfArguments) return errorType(c) @@ -930,7 +931,9 @@ proc semGenericConstraints(c: PContext, n: PNode, result: PType) = proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode = result = copyNode(n) - if n.kind != nkGenericParams: InternalError(n.info, "semGenericParamList") + if n.kind != nkGenericParams: + InternalError(n.info, "semGenericParamList") + return for i in countup(0, sonsLen(n)-1): var a = n.sons[i] if a.kind != nkIdentDefs: illFormedAst(n) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 8ae6250d5..ba0cba749 100755 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -228,24 +228,25 @@ proc minRel(a, b: TTypeRelation): TTypeRelation = if a <= b: result = a else: result = b -proc tupleRel(c: var TCandidate, f, a: PType): TTypeRelation = +proc tupleRel(c: var TCandidate, f, a: PType): TTypeRelation = result = isNone if sameType(f, a): result = isEqual - elif sonsLen(a) == sonsLen(f): + elif sonsLen(a) == sonsLen(f): result = isEqual - for i in countup(0, sonsLen(f) - 1): + for i in countup(0, sonsLen(f) - 1): var m = typeRel(c, f.sons[i], a.sons[i]) if m < isSubtype: return isNone result = minRel(result, m) - if f.n != nil and a.n != nil: - for i in countup(0, sonsLen(f.n) - 1): + if f.n != nil and a.n != nil: + for i in countup(0, sonsLen(f.n) - 1): # check field names: if f.n.sons[i].kind != nkSym: InternalError(f.n.info, "tupleRel") - if a.n.sons[i].kind != nkSym: InternalError(a.n.info, "tupleRel") - var x = f.n.sons[i].sym - var y = a.n.sons[i].sym - if x.name.id != y.name.id: return isNone + elif a.n.sons[i].kind != nkSym: InternalError(a.n.info, "tupleRel") + else: + var x = f.n.sons[i].sym + var y = a.n.sons[i].sym + if x.name.id != y.name.id: return isNone proc matchTypeClass(c: var TCandidate, f, a: PType): TTypeRelation = for i in countup(0, f.sonsLen - 1): @@ -501,7 +502,7 @@ proc typeRel(c: var TCandidate, f, a: PType): TTypeRelation = for i in countup(1, sonsLen(f) - 1): if a.sons[i].kind == tyGenericParam: InternalError("wrong instantiated type!") - if typeRel(c, f.sons[i], a.sons[i]) <= isSubtype: return + elif typeRel(c, f.sons[i], a.sons[i]) <= isSubtype: return result = isGeneric else: result = typeRel(c, f.sons[0], a) @@ -539,7 +540,7 @@ proc typeRel(c: var TCandidate, f, a: PType): TTypeRelation = result = isNone of tyExpr, tyStmt: result = isGeneric - else: internalError("typeRel(" & $f.kind & ')') + else: internalError("typeRel: " & $f.kind) proc cmpTypes*(f, a: PType): TTypeRelation = var c: TCandidate @@ -551,7 +552,9 @@ proc getInstantiatedType(c: PContext, arg: PNode, m: TCandidate, result = PType(idTableGet(m.bindings, f)) if result == nil: result = generateTypeInstance(c, m.bindings, arg, f) - if result == nil: InternalError(arg.info, "getInstantiatedType") + if result == nil: + InternalError(arg.info, "getInstantiatedType") + result = errorType(c) proc implicitConv(kind: TNodeKind, f: PType, arg: PNode, m: TCandidate, c: PContext): PNode = @@ -794,6 +797,7 @@ proc matchesAux*(c: PContext, n, nOrig: PNode, else: if m.callee.n.sons[f].kind != nkSym: InternalError(n.sons[a].info, "matches") + return formal = m.callee.n.sons[f].sym if ContainsOrIncl(marker, formal.position): # already in namedParams: diff --git a/compiler/suggest.nim b/compiler/suggest.nim index ea7d17d16..240316cec 100755 --- a/compiler/suggest.nim +++ b/compiler/suggest.nim @@ -19,7 +19,7 @@ const sectionDef = "def" sectionContext = "con" -proc SymToStr(s: PSym, isLocal: bool, section: string): string = +proc SymToStr(s: PSym, isLocal: bool, section: string, li: TLineInfo): string = result = section result.add(sep) result.add($s.kind) @@ -33,11 +33,14 @@ proc SymToStr(s: PSym, isLocal: bool, section: string): string = if s.typ != nil: result.add(typeToString(s.typ)) result.add(sep) - result.add(toFilename(s.info)) + result.add(toFilename(li)) result.add(sep) - result.add($ToLinenumber(s.info)) + result.add($ToLinenumber(li)) result.add(sep) - result.add($ToColumn(s.info)) + result.add($ToColumn(li)) + +proc SymToStr(s: PSym, isLocal: bool, section: string): string = + result = SymToStr(s, isLocal, section, s.info) proc filterSym(s: PSym): bool {.inline.} = result = s.name.s[0] in lexer.SymChars @@ -196,6 +199,9 @@ proc fuzzySemCheck(c: PContext, n: PNode): PNode = if n.kind notin {nkNone..nkNilLit}: for i in 0 .. < sonsLen(n): result.addSon(fuzzySemCheck(c, n.sons[i])) +var + usageSym: PSym + proc suggestExpr*(c: PContext, node: PNode) = var cp = msgs.inCheckpoint(node.info) if cp == cpNone: return @@ -233,13 +239,26 @@ proc suggestExpr*(c: PContext, node: PNode) = suggestCall(c, a, n, outputs) if optDef in gGlobalOptions: - var n = findClosestSym(fuzzySemCheck(c, node)) - if n != nil: + let n = findClosestSym(fuzzySemCheck(c, node)) + if n != nil: OutWriteln(SymToStr(n.sym, isLocal=false, sectionDef)) inc outputs + if optUsages in gGlobalOptions: + if usageSym == nil: + let n = findClosestSym(fuzzySemCheck(c, node)) + if n != nil: + usageSym = n.sym + OutWriteln(SymToStr(n.sym, isLocal=false, sectionDef)) + inc outputs + else: + let n = node + if n.kind == nkSym and n.sym == usageSym: + OutWriteln(SymToStr(n.sym, isLocal=false, sectionDef, n.info)) + inc outputs + dec(c.InCompilesContext) - if outputs > 0: quit(0) + if outputs > 0 and optUsages notin gGlobalOptions: quit(0) proc suggestStmt*(c: PContext, n: PNode) = suggestExpr(c, n) diff --git a/doc/advopt.txt b/doc/advopt.txt index 5077de4db..9a642addb 100755 --- a/doc/advopt.txt +++ b/doc/advopt.txt @@ -13,8 +13,9 @@ Advanced commands: //idetools compiler support for IDEs: possible options: --track:FILE,LINE,COL track a file/cursor position --suggest suggest all possible symbols at position - --def list all possible symbols at position + --def list all possible definitions at position --context list possible invokation context + --usages list all usages of the symbol at position Advanced options: -m, --mainmodule:FILE set the project main module |