summary refs log tree commit diff stats
path: root/compiler/lookups.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/lookups.nim')
-rw-r--r--compiler/lookups.nim120
1 files changed, 58 insertions, 62 deletions
diff --git a/compiler/lookups.nim b/compiler/lookups.nim
index c409acc59..b6d63d0bd 100644
--- a/compiler/lookups.nim
+++ b/compiler/lookups.nim
@@ -11,23 +11,23 @@
 
 import
   intsets, ast, astalgo, idents, semdata, types, msgs, options, rodread,
-  renderer, wordrecg, idgen, nimfix.prettybase
+  renderer, wordrecg, idgen, nimfix.prettybase, configuration, strutils
 
-proc ensureNoMissingOrUnusedSymbols(scope: PScope)
+proc ensureNoMissingOrUnusedSymbols(c: PContext; scope: PScope)
 
-proc noidentError(n, origin: PNode) =
+proc noidentError(conf: ConfigRef; n, origin: PNode) =
   var m = ""
   if origin != nil:
     m.add "in expression '" & origin.renderTree & "': "
   m.add "identifier expected, but found '" & n.renderTree & "'"
-  localError(n.info, m)
+  localError(conf, n.info, m)
 
-proc considerQuotedIdent*(n: PNode, origin: PNode = nil): PIdent =
+proc considerQuotedIdent*(conf: ConfigRef; n: PNode, origin: PNode = nil): PIdent =
   ## Retrieve a PIdent from a PNode, taking into account accent nodes.
   ## ``origin`` can be nil. If it is not nil, it is used for a better
   ## error message.
   template handleError(n, origin: PNode) =
-    noidentError(n, origin)
+    noidentError(conf, n, origin)
     result = getIdent"<Error>"
 
   case n.kind
@@ -36,7 +36,7 @@ proc considerQuotedIdent*(n: PNode, origin: PNode = nil): PIdent =
   of nkAccQuoted:
     case n.len
     of 0: handleError(n, origin)
-    of 1: result = considerQuotedIdent(n.sons[0], origin)
+    of 1: result = considerQuotedIdent(conf, n.sons[0], origin)
     else:
       var id = ""
       for i in 0..<n.len:
@@ -44,6 +44,7 @@ proc considerQuotedIdent*(n: PNode, origin: PNode = nil): PIdent =
         case x.kind
         of nkIdent: id.add(x.ident.s)
         of nkSym: id.add(x.sym.name.s)
+        of nkLiterals - nkFloatLiterals: id.add(x.renderTree)
         else: handleError(n, origin)
       result = getIdent(id)
   of nkOpenSymChoice, nkClosedSymChoice:
@@ -70,7 +71,7 @@ proc rawCloseScope*(c: PContext) =
   c.currentScope = c.currentScope.parent
 
 proc closeScope*(c: PContext) =
-  ensureNoMissingOrUnusedSymbols(c.currentScope)
+  ensureNoMissingOrUnusedSymbols(c, c.currentScope)
   rawCloseScope(c)
 
 iterator walkScopes*(scope: PScope): PScope =
@@ -79,15 +80,15 @@ iterator walkScopes*(scope: PScope): PScope =
     yield current
     current = current.parent
 
-proc skipAlias*(s: PSym; n: PNode): PSym =
+proc skipAlias*(s: PSym; n: PNode; conf: ConfigRef): PSym =
   if s == nil or s.kind != skAlias:
     result = s
   else:
     result = s.owner
-    if gCmd == cmdPretty:
+    if conf.cmd == cmdPretty:
       prettybase.replaceDeprecated(n.info, s, result)
     else:
-      message(n.info, warnDeprecated, "use " & result.name.s & " instead; " &
+      message(conf, n.info, warnDeprecated, "use " & result.name.s & " instead; " &
               s.name.s)
 
 proc localSearchInScope*(c: PContext, s: PIdent): PSym =
@@ -124,14 +125,14 @@ proc errorSym*(c: PContext, n: PNode): PSym =
   # ensure that 'considerQuotedIdent' can't fail:
   if m.kind == nkDotExpr: m = m.sons[1]
   let ident = if m.kind in {nkIdent, nkSym, nkAccQuoted}:
-      considerQuotedIdent(m)
+      considerQuotedIdent(c.config, m)
     else:
       getIdent("err:" & renderTree(m))
-  result = newSym(skError, ident, getCurrOwner(c), n.info)
+  result = newSym(skError, ident, getCurrOwner(c), n.info, {})
   result.typ = errorType(c)
   incl(result.flags, sfDiscardable)
   # pretend it's imported from some unknown module to prevent cascading errors:
-  if gCmd != cmdInteractive and c.compilesContextId == 0:
+  if c.config.cmd != cmdInteractive and c.compilesContextId == 0:
     c.importTable.addSym(result)
 
 type
@@ -153,7 +154,7 @@ proc getSymRepr*(s: PSym): string =
   else:
     result = s.name.s
 
-proc ensureNoMissingOrUnusedSymbols(scope: PScope) =
+proc ensureNoMissingOrUnusedSymbols(c: PContext; scope: PScope) =
   # check if all symbols have been used and defined:
   var it: TTabIter
   var s = initTabIter(it, scope.symbols)
@@ -163,54 +164,53 @@ proc ensureNoMissingOrUnusedSymbols(scope: PScope) =
       # too many 'implementation of X' errors are annoying
       # and slow 'suggest' down:
       if missingImpls == 0:
-        localError(s.info, errImplOfXexpected, getSymRepr(s))
+        localError(c.config, s.info, "implementation of '$1' expected" % getSymRepr(s))
       inc missingImpls
     elif {sfUsed, sfExported} * s.flags == {} and optHints in s.options:
-      # BUGFIX: check options in s!
       if s.kind notin {skForVar, skParam, skMethod, skUnknown, skGenericParam}:
         # XXX: implicit type params are currently skTypes
         # maybe they can be made skGenericParam as well.
         if s.typ != nil and tfImplicitTypeParam notin s.typ.flags and
            s.typ.kind != tyGenericParam:
-          message(s.info, hintXDeclaredButNotUsed, getSymRepr(s))
+          message(c.config, s.info, hintXDeclaredButNotUsed, getSymRepr(s))
     s = nextIter(it, scope.symbols)
 
-proc wrongRedefinition*(info: TLineInfo, s: string) =
-  if gCmd != cmdInteractive:
-    localError(info, errAttemptToRedefine, s)
+proc wrongRedefinition*(c: PContext; info: TLineInfo, s: string) =
+  if c.config.cmd != cmdInteractive:
+    localError(c.config, info, "redefinition of '$1'" % s)
 
 proc addDecl*(c: PContext, sym: PSym, info: TLineInfo) =
   if not c.currentScope.addUniqueSym(sym):
-    wrongRedefinition(info, sym.name.s)
+    wrongRedefinition(c, info, sym.name.s)
 
 proc addDecl*(c: PContext, sym: PSym) =
   if not c.currentScope.addUniqueSym(sym):
-    wrongRedefinition(sym.info, sym.name.s)
+    wrongRedefinition(c, sym.info, sym.name.s)
 
 proc addPrelimDecl*(c: PContext, sym: PSym) =
   discard c.currentScope.addUniqueSym(sym)
 
-proc addDeclAt*(scope: PScope, sym: PSym) =
+proc addDeclAt*(c: PContext; scope: PScope, sym: PSym) =
   if not scope.addUniqueSym(sym):
-    wrongRedefinition(sym.info, sym.name.s)
+    wrongRedefinition(c, sym.info, sym.name.s)
 
 proc addInterfaceDeclAux(c: PContext, sym: PSym) =
   if sfExported in sym.flags:
     # add to interface:
     if c.module != nil: strTableAdd(c.module.tab, sym)
-    else: internalError(sym.info, "addInterfaceDeclAux")
+    else: internalError(c.config, sym.info, "addInterfaceDeclAux")
 
 proc addInterfaceDeclAt*(c: PContext, scope: PScope, sym: PSym) =
-  addDeclAt(scope, sym)
+  addDeclAt(c, scope, sym)
   addInterfaceDeclAux(c, sym)
 
-proc addOverloadableSymAt*(scope: PScope, fn: PSym) =
+proc addOverloadableSymAt*(c: PContext; scope: PScope, fn: PSym) =
   if fn.kind notin OverloadableSyms:
-    internalError(fn.info, "addOverloadableSymAt")
+    internalError(c.config, fn.info, "addOverloadableSymAt")
     return
   let check = strTableGet(scope.symbols, fn.name)
   if check != nil and check.kind notin OverloadableSyms:
-    wrongRedefinition(fn.info, fn.name.s)
+    wrongRedefinition(c, fn.info, fn.name.s)
   else:
     scope.addSym(fn)
 
@@ -221,12 +221,10 @@ proc addInterfaceDecl*(c: PContext, sym: PSym) =
 
 proc addInterfaceOverloadableSymAt*(c: PContext, scope: PScope, sym: PSym) =
   # it adds the symbol to the interface if appropriate
-  addOverloadableSymAt(scope, sym)
+  addOverloadableSymAt(c, 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]
@@ -254,7 +252,7 @@ proc errorUseQualifier*(c: PContext; info: TLineInfo; s: PSym) =
     err.add candidate.owner.name.s & "." & candidate.name.s
     candidate = nextIdentIter(ti, c.importTable.symbols)
     inc i
-  localError(info, errGenerated, err)
+  localError(c.config, info, errGenerated, err)
 
 proc errorUndeclaredIdentifier*(c: PContext; info: TLineInfo; name: string) =
   var err = "undeclared identifier: '" & name & "'"
@@ -263,13 +261,13 @@ proc errorUndeclaredIdentifier*(c: PContext; info: TLineInfo; name: string) =
     err.add c.recursiveDep
     # prevent excessive errors for 'nim check'
     c.recursiveDep = nil
-  localError(info, errGenerated, err)
+  localError(c.config, info, errGenerated, err)
 
 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)
+    result = searchInScopes(c, n.ident).skipAlias(n, c.config)
     if result == nil:
       fixSpelling(n, n.ident, searchInScopes)
       errorUndeclaredIdentifier(c, n.info, n.ident.s)
@@ -277,14 +275,14 @@ proc lookUp*(c: PContext, n: PNode): PSym =
   of nkSym:
     result = n.sym
   of nkAccQuoted:
-    var ident = considerQuotedIdent(n)
-    result = searchInScopes(c, ident).skipAlias(n)
+    var ident = considerQuotedIdent(c.config, n)
+    result = searchInScopes(c, ident).skipAlias(n, c.config)
     if result == nil:
       fixSpelling(n, ident, searchInScopes)
       errorUndeclaredIdentifier(c, n.info, ident.s)
       result = errorSym(c, n)
   else:
-    internalError(n.info, "lookUp")
+    internalError(c.config, n.info, "lookUp")
     return
   if contains(c.ambiguousSymbols, result.id):
     errorUseQualifier(c, n.info, result)
@@ -298,11 +296,11 @@ proc qualifiedLookUp*(c: PContext, n: PNode, flags: set[TLookupFlag]): PSym =
   const allExceptModule = {low(TSymKind)..high(TSymKind)}-{skModule,skPackage}
   case n.kind
   of nkIdent, nkAccQuoted:
-    var ident = considerQuotedIdent(n)
+    var ident = considerQuotedIdent(c.config, n)
     if checkModule in flags:
-      result = searchInScopes(c, ident).skipAlias(n)
+      result = searchInScopes(c, ident).skipAlias(n, c.config)
     else:
-      result = searchInScopes(c, ident, allExceptModule).skipAlias(n)
+      result = searchInScopes(c, ident, allExceptModule).skipAlias(n, c.config)
     if result == nil and checkPureEnumFields in flags:
       result = strTableGet(c.pureEnumFields, ident)
     if result == nil and checkUndeclared in flags:
@@ -324,12 +322,12 @@ proc qualifiedLookUp*(c: PContext, n: PNode, flags: set[TLookupFlag]): PSym =
       if n.sons[1].kind == nkIdent:
         ident = n.sons[1].ident
       elif n.sons[1].kind == nkAccQuoted:
-        ident = considerQuotedIdent(n.sons[1])
+        ident = considerQuotedIdent(c.config, n.sons[1])
       if ident != nil:
         if m == c.module:
-          result = strTableGet(c.topLevelScope.symbols, ident).skipAlias(n)
+          result = strTableGet(c.topLevelScope.symbols, ident).skipAlias(n, c.config)
         else:
-          result = strTableGet(m.tab, ident).skipAlias(n)
+          result = strTableGet(m.tab, ident).skipAlias(n, c.config)
         if result == nil and checkUndeclared in flags:
           fixSpelling(n.sons[1], ident, searchInScopes)
           errorUndeclaredIdentifier(c, n.sons[1].info, ident.s)
@@ -338,7 +336,7 @@ proc qualifiedLookUp*(c: PContext, n: PNode, flags: set[TLookupFlag]): PSym =
         result = n.sons[1].sym
       elif checkUndeclared in flags and
            n.sons[1].kind notin {nkOpenSymChoice, nkClosedSymChoice}:
-        localError(n.sons[1].info, errIdentifierExpected,
+        localError(c.config, n.sons[1].info, "identifier expected, but got: " &
                    renderTree(n.sons[1]))
         result = errorSym(c, n.sons[1])
   else:
@@ -348,11 +346,11 @@ proc qualifiedLookUp*(c: PContext, n: PNode, flags: set[TLookupFlag]): PSym =
 proc initOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
   case n.kind
   of nkIdent, nkAccQuoted:
-    var ident = considerQuotedIdent(n)
+    var ident = considerQuotedIdent(c.config, n)
     o.scope = c.currentScope
     o.mode = oimNoQualifier
     while true:
-      result = initIdentIter(o.it, o.scope.symbols, ident).skipAlias(n)
+      result = initIdentIter(o.it, o.scope.symbols, ident).skipAlias(n, c.config)
       if result != nil:
         break
       else:
@@ -369,17 +367,17 @@ proc initOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
       if n.sons[1].kind == nkIdent:
         ident = n.sons[1].ident
       elif n.sons[1].kind == nkAccQuoted:
-        ident = considerQuotedIdent(n.sons[1], n)
+        ident = considerQuotedIdent(c.config, n.sons[1], n)
       if ident != nil:
         if o.m == c.module:
           # a module may access its private members:
           result = initIdentIter(o.it, c.topLevelScope.symbols,
-                                 ident).skipAlias(n)
+                                 ident).skipAlias(n, c.config)
           o.mode = oimSelfModule
         else:
-          result = initIdentIter(o.it, o.m.tab, ident).skipAlias(n)
+          result = initIdentIter(o.it, o.m.tab, ident).skipAlias(n, c.config)
       else:
-        noidentError(n.sons[1], n)
+        noidentError(c.config, n.sons[1], n)
         result = errorSym(c, n.sons[1])
   of nkClosedSymChoice, nkOpenSymChoice:
     o.mode = oimSymChoice
@@ -407,18 +405,18 @@ proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
     result = nil
   of oimNoQualifier:
     if o.scope != nil:
-      result = nextIdentIter(o.it, o.scope.symbols).skipAlias(n)
+      result = nextIdentIter(o.it, o.scope.symbols).skipAlias(n, c.config)
       while result == nil:
         o.scope = o.scope.parent
         if o.scope == nil: break
-        result = initIdentIter(o.it, o.scope.symbols, o.it.name).skipAlias(n)
+        result = initIdentIter(o.it, o.scope.symbols, o.it.name).skipAlias(n, c.config)
         # BUGFIX: o.it.name <-> n.ident
     else:
       result = nil
   of oimSelfModule:
-    result = nextIdentIter(o.it, c.topLevelScope.symbols).skipAlias(n)
+    result = nextIdentIter(o.it, c.topLevelScope.symbols).skipAlias(n, c.config)
   of oimOtherModule:
-    result = nextIdentIter(o.it, o.m.tab).skipAlias(n)
+    result = nextIdentIter(o.it, o.m.tab).skipAlias(n, c.config)
   of oimSymChoice:
     if o.symChoiceIndex < sonsLen(n):
       result = n.sons[o.symChoiceIndex].sym
@@ -429,19 +427,19 @@ proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
       o.mode = oimSymChoiceLocalLookup
       o.scope = c.currentScope
       result = firstIdentExcluding(o.it, o.scope.symbols,
-                                   n.sons[0].sym.name, o.inSymChoice).skipAlias(n)
+                                   n.sons[0].sym.name, o.inSymChoice).skipAlias(n, c.config)
       while result == nil:
         o.scope = o.scope.parent
         if o.scope == nil: break
         result = firstIdentExcluding(o.it, o.scope.symbols,
-                                     n.sons[0].sym.name, o.inSymChoice).skipAlias(n)
+                                     n.sons[0].sym.name, o.inSymChoice).skipAlias(n, c.config)
   of oimSymChoiceLocalLookup:
-    result = nextIdentExcluding(o.it, o.scope.symbols, o.inSymChoice).skipAlias(n)
+    result = nextIdentExcluding(o.it, o.scope.symbols, o.inSymChoice).skipAlias(n, c.config)
     while result == nil:
       o.scope = o.scope.parent
       if o.scope == nil: break
       result = firstIdentExcluding(o.it, o.scope.symbols,
-                                   n.sons[0].sym.name, o.inSymChoice).skipAlias(n)
+                                   n.sons[0].sym.name, o.inSymChoice).skipAlias(n, c.config)
 
   if result != nil and result.kind == skStub: loadStub(result)
 
@@ -455,5 +453,3 @@ proc pickSym*(c: PContext, n: PNode; kinds: set[TSymKind];
       else: return nil # ambiguous
     a = nextOverloadIter(o, c, n)
 
-proc isInfixAs*(n: PNode): bool =
-  return n.kind == nkInfix and considerQuotedIdent(n[0]).s == "as"
\ No newline at end of file