This commit is contained in:
Andrii Riabushenko
2019-07-25 23:02:04 +01:00
parent 3bb6d1916e
commit d7bc4e43a2
9 changed files with 50 additions and 41 deletions

View File

@@ -480,7 +480,8 @@ proc formatMsg*(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg: string): s
title &
getMessageStr(msg, arg)
proc liMessage(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg: string,
proc liMessage(conf: ConfigRef; notes: TNoteKinds, options: TOptions,
info: TLineInfo, msg: TMsgKind, arg: string,
eh: TErrorHandling) =
var
title: string
@@ -500,15 +501,16 @@ proc liMessage(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg: string,
conf.m.lastError = info
of warnMin..warnMax:
sev = Severity.Warning
ignoreMsg = optWarns notin conf.options or msg notin conf.notes
ignoreMsg = optWarns notin options or msg notin notes
if not ignoreMsg: writeContext(conf, info)
title = WarningTitle
color = WarningColor
kind = WarningsToStr[ord(msg) - ord(warnMin)]
inc(conf.warnCounter)
of hintMin..hintMax:
sev = Severity.Hint
ignoreMsg = optHints notin conf.options or msg notin conf.notes
ignoreMsg = optHints notin options or msg notin notes
title = HintTitle
color = HintColor
if msg != hintUserRaw: kind = HintsToStr[ord(msg) - ord(hintMin)]
@@ -534,30 +536,34 @@ proc fatal*(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg = "") =
# this fixes bug #7080 so that it is at least obvious 'fatal'
# was executed.
conf.m.errorOutputs = {eStdOut, eStdErr}
liMessage(conf, info, msg, arg, doAbort)
liMessage(conf, conf.notes, conf.options, info, msg, arg, doAbort)
proc globalError*(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg = "") =
liMessage(conf, info, msg, arg, doRaise)
liMessage(conf, conf.notes, conf.options, info, msg, arg, doRaise)
proc globalError*(conf: ConfigRef; info: TLineInfo, arg: string) =
liMessage(conf, info, errGenerated, arg, doRaise)
liMessage(conf, conf.notes, conf.options, info, errGenerated, arg, doRaise)
proc localError*(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg = "") =
liMessage(conf, info, msg, arg, doNothing)
liMessage(conf, conf.notes, conf.options, info, msg, arg, doNothing)
proc localError*(conf: ConfigRef; info: TLineInfo, arg: string) =
liMessage(conf, info, errGenerated, arg, doNothing)
liMessage(conf, conf.notes, conf.options, info, errGenerated, arg, doNothing)
proc localError*(conf: ConfigRef; info: TLineInfo, format: string, params: openArray[string]) =
localError(conf, info, format % params)
proc message*(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg = "") =
liMessage(conf, info, msg, arg, doNothing)
liMessage(conf, conf.notes, conf.options, info, msg, arg, doNothing)
proc message*(conf: ConfigRef; notes: TNoteKinds, options: TOptions;
info: TLineInfo, msg: TMsgKind, arg = "") =
liMessage(conf, notes, options, info, msg, arg, doNothing)
proc internalError*(conf: ConfigRef; info: TLineInfo, errMsg: string) =
if conf.cmd == cmdIdeTools and conf.structuredErrorHook.isNil: return
writeContext(conf, info)
liMessage(conf, info, errInternal, errMsg, doAbort)
liMessage(conf, conf.notes, conf.options, info, errInternal, errMsg, doAbort)
proc internalError*(conf: ConfigRef; errMsg: string) =
if conf.cmd == cmdIdeTools and conf.structuredErrorHook.isNil: return

View File

@@ -467,7 +467,7 @@ proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
if efNoSemCheck notin flags:
result = semAfterMacroCall(c, n, result, sym, flags)
if c.config.macrosToExpand.hasKey(sym.name.s):
message(c.config, nOrig.info, hintExpandMacro, renderTree(result))
message(c, nOrig.info, hintExpandMacro, renderTree(result))
result = wrapInComesFrom(nOrig.info, sym, result)
popInfoContext(c.config)
@@ -620,7 +620,7 @@ proc myProcess(context: PPassContext, n: PNode): PNode =
proc reportUnusedModules(c: PContext) =
for i in 0..high(c.unusedImports):
message(c.config, c.unusedImports[i][1], warnUnusedImportX, c.unusedImports[i][0].name.s)
message(c, c.unusedImports[i][1], warnUnusedImportX, c.unusedImports[i][0].name.s)
proc myClose(graph: ModuleGraph; context: PPassContext, n: PNode): PNode =
var c = PContext(context)

View File

@@ -526,7 +526,7 @@ proc semOverloadedCall(c: PContext, n, nOrig: PNode,
# this may be triggered, when the explain pragma is used
if errors.len > 0:
let (_, candidates) = presentFailedCandidates(c, n, errors)
message(c.config, n.info, hintUserRaw,
message(c, n.info, hintUserRaw,
"Non-matching candidates for " & renderTree(n) & "\n" &
candidates)
result = semResolvedCall(c, r, n, flags)

View File

@@ -171,6 +171,9 @@ proc popOwner*(c: PContext) =
proc lastOptionEntry*(c: PContext): POptionEntry =
result = c.optionStack[^1]
proc message*(c: PContext, info: TLineInfo, msg: TMsgKind, arg = "") =
message(c.config, c.lastOptionEntry.notes, c.lastOptionEntry.options, info, msg, arg)
proc popProcCon*(c: PContext) {.inline.} = c.p = c.p.next
proc put*(p: PProcCon; key, val: PSym) =

View File

@@ -289,7 +289,7 @@ proc semConv(c: PContext, n: PNode): PNode =
elif op.kind in {nkPar, nkTupleConstr} and targetType.kind == tyTuple:
op = fitNode(c, targetType, op, result.info)
of convNotNeedeed:
message(c.config, n.info, hintConvFromXtoItselfNotNeeded, result.typ.typeToString)
message(c, n.info, hintConvFromXtoItselfNotNeeded, result.typ.typeToString)
of convNotLegal:
result = fitNode(c, result.typ, result.sons[1], result.info)
if result == nil:
@@ -2588,7 +2588,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
result.kind = nkCall
result = semExpr(c, result, flags)
of nkBind:
message(c.config, n.info, warnDeprecated, "bind is deprecated")
message(c, n.info, warnDeprecated, "bind is deprecated")
result = semExpr(c, n.sons[0], flags)
of nkTypeOfExpr, nkTupleTy, nkTupleClassTy, nkRefTy..nkEnumTy, nkStaticTy:
if c.matchedConcept != nil and n.len == 1:

View File

@@ -305,7 +305,7 @@ proc semOf(c: PContext, n: PNode): PNode =
# | returns: `maxint` iff `a` and `b` are not compatible at all
if diff <= 0:
# optimize to true:
message(c.config, n.info, hintConditionAlwaysTrue, renderTree(n))
message(c, n.info, hintConditionAlwaysTrue, renderTree(n))
result = newIntNode(nkIntLit, 1)
result.info = n.info
result.typ = getSysType(c.graph, n.info, tyBool)
@@ -314,7 +314,7 @@ proc semOf(c: PContext, n: PNode): PNode =
if commonSuperclass(a, b) == nil:
localError(c.config, n.info, "'$1' cannot be of this subtype" % typeToString(a))
else:
message(c.config, n.info, hintConditionAlwaysFalse, renderTree(n))
message(c, n.info, hintConditionAlwaysFalse, renderTree(n))
result = newIntNode(nkIntLit, 0)
result.info = n.info
result.typ = getSysType(c.graph, n.info, tyBool)

View File

@@ -221,33 +221,33 @@ else:
if not a.inEnforcedNoSideEffects: a.hasSideEffect = true
markGcUnsafe(a, reason)
proc listGcUnsafety(s: PSym; onlyWarning: bool; cycleCheck: var IntSet; conf: ConfigRef) =
proc listGcUnsafety(s: PSym; onlyWarning: bool; cycleCheck: var IntSet; c: PContext) =
let u = s.gcUnsafetyReason
if u != nil and not cycleCheck.containsOrIncl(u.id):
let msgKind = if onlyWarning: warnGcUnsafe2 else: errGenerated
case u.kind
of skLet, skVar:
message(conf, s.info, msgKind,
message(c, s.info, msgKind,
("'$#' is not GC-safe as it accesses '$#'" &
" which is a global using GC'ed memory") % [s.name.s, u.name.s])
of routineKinds:
# recursive call *always* produces only a warning so the full error
# message is printed:
listGcUnsafety(u, true, cycleCheck, conf)
message(conf, s.info, msgKind,
listGcUnsafety(u, true, cycleCheck, c)
message(c, s.info, msgKind,
"'$#' is not GC-safe as it calls '$#'" %
[s.name.s, u.name.s])
of skParam, skForVar:
message(conf, s.info, msgKind,
message(c, s.info, msgKind,
"'$#' is not GC-safe as it performs an indirect call via '$#'" %
[s.name.s, u.name.s])
else:
message(conf, u.info, msgKind,
message(c, u.info, msgKind,
"'$#' is not GC-safe as it performs an indirect call here" % s.name.s)
proc listGcUnsafety(s: PSym; onlyWarning: bool; conf: ConfigRef) =
proc listGcUnsafety(s: PSym; onlyWarning: bool; c: PContext) =
var cycleCheck = initIntSet()
listGcUnsafety(s, onlyWarning, cycleCheck, conf)
listGcUnsafety(s, onlyWarning, cycleCheck, c)
proc useVar(a: PEffects, n: PNode) =
let s = n.sym
@@ -257,9 +257,9 @@ proc useVar(a: PEffects, n: PNode) =
a.init.add s.id
elif s.id notin a.init:
if {tfNeedsInit, tfNotNil} * s.typ.flags != {}:
message(a.config, n.info, warnProveInit, s.name.s)
message(a.c, n.info, warnProveInit, s.name.s)
else:
message(a.config, n.info, warnUninit, s.name.s)
message(a.c, n.info, warnUninit, s.name.s)
# prevent superfluous warnings about the same variable:
a.init.add s.id
if {sfGlobal, sfThread} * s.flags != {} and s.kind in {skVar, skLet} and
@@ -983,7 +983,7 @@ proc trackProc*(c: PContext; s: PSym, body: PNode) =
s.kind in {skProc, skFunc, skConverter, skMethod}:
var res = s.ast.sons[resultPos].sym # get result symbol
if res.id notin t.init:
message(g.config, body.info, warnProveInit, "result")
message(c, body.info, warnProveInit, "result")
let p = s.ast.sons[pragmasPos]
let raisesSpec = effectSpec(p, wRaises)
if not isNil(raisesSpec):
@@ -1002,13 +1002,13 @@ proc trackProc*(c: PContext; s: PSym, body: PNode) =
if sfThread in s.flags and t.gcUnsafe:
if optThreads in g.config.globalOptions and optThreadAnalysis in g.config.globalOptions:
#localError(s.info, "'$1' is not GC-safe" % s.name.s)
listGcUnsafety(s, onlyWarning=false, g.config)
listGcUnsafety(s, onlyWarning=false, c)
else:
listGcUnsafety(s, onlyWarning=true, g.config)
listGcUnsafety(s, onlyWarning=true, c)
#localError(s.info, warnGcUnsafe2, s.name.s)
if sfNoSideEffect in s.flags and t.hasSideEffect:
when false:
listGcUnsafety(s, onlyWarning=false, g.config)
listGcUnsafety(s, onlyWarning=false, c)
else:
localError(g.config, s.info, "'$1' can have side effects" % s.name.s)
if not t.gcUnsafe:
@@ -1019,7 +1019,7 @@ proc trackProc*(c: PContext; s: PSym, body: PNode) =
s.typ.lockLevel = t.maxLockLevel
elif t.maxLockLevel > s.typ.lockLevel:
#localError(s.info,
message(g.config, s.info, warnLockLevel,
message(c, s.info, warnLockLevel,
"declared lock level is $1, but real lock level is $2" %
[$s.typ.lockLevel, $t.maxLockLevel])
when defined(useDfa):

View File

@@ -337,9 +337,9 @@ proc checkNilable(c: PContext; v: PSym) =
if {sfGlobal, sfImportc} * v.flags == {sfGlobal} and
{tfNotNil, tfNeedsInit} * v.typ.flags != {}:
if v.astdef.isNil:
message(c.config, v.info, warnProveInit, v.name.s)
message(c, v.info, warnProveInit, v.name.s)
elif tfNotNil in v.typ.flags and not v.astdef.typ.isNil and tfNotNil notin v.astdef.typ.flags:
message(c.config, v.info, warnProveInit, v.name.s)
message(c, v.info, warnProveInit, v.name.s)
#include liftdestructors
@@ -511,7 +511,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
addToVarSection(c, result, n, b)
elif tup.kind == tyTuple and def.kind in {nkPar, nkTupleConstr} and
a.kind == nkIdentDefs and a.len > 3:
message(c.config, a.info, warnEachIdentIsTuple)
message(c, a.info, warnEachIdentIsTuple)
for j in 0 .. length-3:
if a[j].kind == nkDotExpr:
@@ -533,7 +533,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
if shadowed != nil:
shadowed.flags.incl(sfShadowed)
if shadowed.kind == skResult and sfGenSym notin v.flags:
message(c.config, a.info, warnResultShadowed)
message(c, a.info, warnResultShadowed)
if a.kind != nkVarTuple:
if def.kind != nkEmpty:
if sfThread in v.flags: localError(c.config, def.info, errThreadvarCannotInit)
@@ -576,7 +576,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
addSon(x, result[i])
vm.setupCompileTimeVar(c.module, c.graph, x)
if v.flags * {sfGlobal, sfThread} == {sfGlobal}:
message(c.config, v.info, hintGlobalVar)
message(c, v.info, hintGlobalVar)
proc semConst(c: PContext, n: PNode): PNode =
result = copyNode(n)
@@ -1714,7 +1714,7 @@ proc semMethodPrototype(c: PContext; s: PSym; n: PNode) =
if x.kind == tyObject and t.len-1 == n.sons[genericParamsPos].len:
foundObj = true
x.methods.add((col,s))
message(c.config, n.info, warnDeprecated, "generic methods are deprecated")
message(c, n.info, warnDeprecated, "generic methods are deprecated")
#if not foundObj:
# message(c.config, n.info, warnDeprecated, "generic method not attachable to object type is deprecated")
else:

View File

@@ -853,9 +853,9 @@ proc semAnyRef(c: PContext; n: PNode; kind: TTypeKind; prev: PType): PType =
let region = semTypeNode(c, ni, nil)
if region.skipTypes({tyGenericInst, tyAlias, tySink}).kind notin {
tyError, tyObject}:
message c.config, n[i].info, errGenerated, "region needs to be an object type"
message c, n[i].info, errGenerated, "region needs to be an object type"
else:
message(c.config, n.info, warnDeprecated, "region for pointer types is deprecated")
message(c, n.info, warnDeprecated, "region for pointer types is deprecated")
addSonSkipIntLit(result, region)
addSonSkipIntLit(result, t)
if tfPartial in result.flags:
@@ -1215,7 +1215,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
"`void` or no return type declaration at all has the same " &
"meaning as the current meaning of `typed` as return type " &
"declaration."
message(c.config, info, warnDeprecated, msg)
message(c, info, warnDeprecated, msg)
r = nil
if r != nil: