From 90d1a3b22954cdf3239d2ef258d0fc615869da4a Mon Sep 17 00:00:00 2001 From: Fengyang Wang Date: Sun, 19 Mar 2017 17:29:01 -0400 Subject: [PATCH] Eliminate keytype, valuetype --- src/guesstype.jl | 87 +++++++++++++++++------------------------------ src/statictype.jl | 2 +- src/variables.jl | 8 ++--- 3 files changed, 35 insertions(+), 62 deletions(-) diff --git a/src/guesstype.jl b/src/guesstype.jl index e2ea8d0..4e58095 100644 --- a/src/guesstype.jl +++ b/src/guesstype.jl @@ -1,14 +1,5 @@ using Base: isexported -keytype(::Type{Any}) = Any -valuetype(::Type{Any}) = Any - -keytype{K,V}(::Type{Associative{K,V}}) = K -valuetype{K,V}(::Type{Associative{K,V}}) = V - -keytype{T<:Associative}(::Type{T}) = keytype(supertype(T)) -valuetype{T<:Associative}(::Type{T}) = valuetype(supertype(T)) - function arraytype_dims(elt, dimst) tuplen = StaticTypeAnalysis.length(dimst) if isnull(tuplen) @@ -88,62 +79,46 @@ function parsetype(ex) end end -function guesstype(ex, ctx::LintContext) - t = typeof(ex) - if t <: Number - return t - end - if t <: AbstractString - return t +function guesstype(ex::Symbol, ctx::LintContext) + stacktop = ctx.callstack[end] + sym = ex + for i in length(stacktop.localvars):-1:1 + if haskey(stacktop.localvars[i], sym) + ret = stacktop.localvars[i][sym].typeactual + return ret + end end - if t == Symbol # check if we have seen it - stacktop = ctx.callstack[end] - sym = ex - for i in length(stacktop.localvars):-1:1 - if haskey(stacktop.localvars[i], sym) - ret = stacktop.localvars[i][sym].typeactual - return ret - end + for i in length(stacktop.localarguments):-1:1 + if haskey(stacktop.localarguments[i], sym) + ret = stacktop.localarguments[i][sym].typeactual + return ret end - for i in length(stacktop.localarguments):-1:1 - if haskey(stacktop.localarguments[i], sym) - ret = stacktop.localarguments[i][sym].typeactual - return ret - end + end + for i in length(ctx.callstack):-1:1 + if sym in ctx.callstack[i].types + return Type end - for i in length(ctx.callstack):-1:1 - if in(sym, ctx.callstack[i].types) - return Type - end - if in(sym, ctx.callstack[i].functions) - return Function - end - if in(sym, ctx.callstack[i].modules) - return Module - end + if sym in ctx.callstack[i].functions + return Function end - val = stdlibobject(ex) - if !isnull(val) - if isa(get(val), Type) - return Type{get(val)} - else - return typeof(get(val)) - end + if sym in ctx.callstack[i].modules + return Module end - return Any - end - - if t == QuoteNode - return typeof(ex.value) end - - if t != Expr - return Any + val = stdlibobject(ex) + if !isnull(val) + if isa(get(val), Type) + return Type{get(val)} + else + return typeof(get(val)) + end end + return Any +end +function guesstype(ex::Expr, ctx::LintContext) ex = ExpressionUtils.expand_trivial_calls(ex) - if isexpr(ex, :tuple) ts = Type[] for a in ex.args @@ -329,3 +304,5 @@ function guesstype(ex, ctx::LintContext) return Any end + +guesstype(ex, ctx::LintContext) = lexicaltypeof(ex) diff --git a/src/statictype.jl b/src/statictype.jl index 981588c..2510158 100644 --- a/src/statictype.jl +++ b/src/statictype.jl @@ -13,7 +13,7 @@ Given types `S` and `T`, return `Nullable(false)` if it is not possible for `s::S == t::T`. Return `Nullable(true)` if it is possible, and `Nullable{Bool}()` if it cannot be determined. -```jldoctest +``jldoctest julia> StaticTypeAnalysis.canequal(Int, Float64) Nullable(true) diff --git a/src/variables.jl b/src/variables.jl index f3ab612..c59cc5c 100644 --- a/src/variables.jl +++ b/src/variables.jl @@ -198,14 +198,10 @@ function lintassignment(ex::Expr, assign_ops::Symbol, ctx::LintContext; islocal msg(ctx, :I672, "iteration works for a number but it may be a typo") end - if rhstype <: Union{Tuple,Set,Array,Range,Enumerate} - rhstype = StaticTypeAnalysis.eltype(rhstype) - elseif rhstype <: Associative - rhstype = Tuple{keytype(rhstype), valuetype(rhstype)} - end + rhstype = StaticTypeAnalysis.eltype(rhstype) # TODO: only when LHS is tuple - if rhstype <: Tuple + if rhstype <: Union{Pair, Tuple} computedlength = StaticTypeAnalysis.length(rhstype) if !isnull(computedlength) && get(computedlength) ≠ tuplelen msg(ctx, :I474, rhstype, "iteration generates tuples, " *