FIXME Unhack invariant extraction for named types
332389
public String hackInv(ANamedTypeDeclIR type) {
        ATypeDeclIR tDecl = (ATypeDeclIR) type.parent();

        if (tDecl.getInv() != null) {
            AFuncDeclIR invFunc = (AFuncDeclIR) tDecl.getInv();
            StringBuilder sb = new StringBuilder();
            sb.append("inv ");
            sb.append(invFunc.getFormalParams().get(0).getPattern().toString());
            sb.append(" == ");
            sb.append(invFunc.getName());
            sb.append("(");
            sb.append("&");
            sb.append(invFunc.getFormalParams().get(0).getPattern().toString());
            sb.append(")");
            return sb.toString();
        }
        return "";
    }
94261
function reportUnexpectedUnnamedFunction(node) {
            context.report({
                node,
                messageId: "unnamed",
                data: { name: astUtils.getFunctionNameWithKind(node) }
            });
        }
1310631
function makeTypeChecker(freeTypeVars) {
		if (!freeTypeVars)
			freeTypeVars = []

		var bound_type_params = new Map
		var bound_nodes = []
		freeTypeVars.forEach(function(tp) {
			bound_type_params.put(tp.name, [])
		})

		var callSigMatches = []

		function isPrtyCompatibleWithType(prty, type, path, receiver) {
			if (prty.type === 'node') {
				return isNodeCompatibleWithType(prty.node, type, path, receiver)
			} else {
				var ok = prty.types.some(function(t) {
					return isTypeCompatibleWithType(t, type, null)
				})
				if (!ok) {
					reportError(path, 'expected ' + formatType(type) + ' but found ' + formatUnion(prty.types))
				}
				return ok
			}
		}
		var node_prty_compatible = Object.create(null)
		function isNodeCompatibleWithProperty(node, k, prty, path, receiver) {
			if (prty.meta.origin === LIB_ORIGIN) // there are too many non-portable properties in lib.d.ts
				return true
			if (!receiver)
				receiver = node
			node = node.rep()
			if (node.isAny)
				return true
			if (node.isFree) {
				bound_nodes.push({type: 'type', node: node, bound: prty.type})
				return true
			}
			var name = node.translateName(k)
			var dst = node.properties.get(name)
			if (dst) {
				return isPrtyCompatibleWithType(dst, prty.type, path, receiver)
			} else {
				var protoWithPrty = node.prototypes.filter(function(proto) {
					return proto.properties.has(name)
				})
				protoWithPrty = protoWithPrty.unique(function(proto) { return proto.rep().id })
				if (protoWithPrty.length === 0) {
					if (!prty.optional) {
						reportError(path, 'expected ' + formatType(prty.type) + ' but found nothing')
						return false
					}
					return true
				} else if (protoWithPrty.length === 1) {
					return isPrtyCompatibleWithType(protoWithPrty[0].properties.get(name), prty.type, path, receiver)
				} else {
					var h = node.id + '~' + k + '~' + prty.optional + '.' + canonicalizeType(prty.type)
					if (h in node_prty_compatible)
						return node_prty_compatible[h]
					node_prty_compatible[h] = false	
					var ok = node.prototypes.some(function(proto) {
						return isNodeCompatibleWithProperty(proto, k, prty, null, receiver)
					})
					if (!ok) {
						reportError(path, 'expected ' + prty.type + ' but found [complex type]')
					}
					node_prty_compatible[h] = ok
					return ok
				}
			}
		}
		var node_type_compatible = Object.create(null)
		function isNodeCompatibleWithType(node, type, path, receiver, continueOnError) {
			node = node.rep()
			if (node.isAny) {
				return true
			}
			if (node.isFree) {
				bound_nodes.push({type: 'type', node: node, bound: type})
				return true
			}
			var h = canonicalizeType(type) + "~" + node.id // TODO: include receiver??
			if (h in node_type_compatible) {
				return node_type_compatible[h]
			}
			node_type_compatible[h] = true
			return node_type_compatible[h] = isNodeCompatibleWithTypeX(node, type, path, receiver, continueOnError)
		}
		function isNodeCompatibleWithTypeX(node, type, path, receiver, continueOnError) {
			node = node.rep()
			if (node.isAny || node.primitives.has({type:'value', value:null}))
				return true
			var originalType = type
			if (type.type === 'reference')
				type = resolveTypeRef(type)
			switch (type.type) {
				case 'object':
					var ok = true
					if (!node.isObject) {
						reportError(path, 'expected ' + formatType(originalType) + ' but found ' + formatNodeAsPrimitive(node))
						ok = false
						return false
					}
					if (type.brand && isValidBrand(type.brand)) {
						var hasBrand = !node.brands.isEmpty()
						ok = node.brands.some(type.brand)
						if (!ok) {
							ok = node.prototypes.some(function(proto) {
								return hasBrand |= proto.brands.some(type.brand)
							})
						}
						if (!ok) {
							if (hasBrand) {
								reportError(path, 'expected ' + type.brand + ' but found ' + formatNode(node) + ' [BRAND]')
							} else {
								reportError(path, 'missing prototype for branded type ' + type.brand)
							}
						}
						if (!continueOnError)
							return ok // defer checking of other properties to the constructor check
					}
					for (var k in type.properties) {
						if (!isNodeCompatibleWithProperty(node, k, type.properties[k], qualify(path,k))) {
							ok = false 
							if (!continueOnError) return false
						}
					}
					if (type.numberIndexer) {
						ok &= node.properties.all(function(name,dst) {
							if (!isNumberString(name))
								return true
							return isPrtyCompatibleWithType(dst, type.numberIndexer, qualify(path,'[' + name + ']'), node)
						})
						if (!ok && !continueOnError) return false
					}
					if (type.stringIndexer) {
						ok &= node.properties.all(function(name,dst) {
							// FIXME: enumerability check?
							return isPrtyCompatibleWithType(dst, type.stringIndexer, qualify(path, "['" + name + "']"), node)
						})
						if (!ok && !continueOnError) return false
					}
					if (type.calls.length > 0 && node.functions.isEmpty() && node.call_sigs.isEmpty()) {
						reportError(path, 'expected ' + formatTypeCall(type.calls[0]) + ' but found non-function object')
						ok = false
						if (!continueOnError) return false
					}
					type.calls.forEach(function(sig) {
						callSigMatches.push({
							callsig: sig,
							node: node,
							receiver: receiver,
							path: path
						})
					})
					return ok
				case 'enum':
					var enum_vals = enum_values.get(type.name)
					if (enum_vals.length === 0) {
						return true
					}
					var ok = enum_vals.some(function(v) {
						return isNodeCompatibleWithValue(node, v)
					})
					if (!ok) {
						reportError(path, 'expected ' + type.name + ' but found ' + formatNodeAsPrimitive(node))
					}
					return ok
				case 'any':
				case 'void':
					return true
				case 'number':
				case 'string':
				case 'boolean':
					if (node.primitives.has({type: type.type}))
						return true
					var ok = node.primitives.some(function(t) {
						return t.type === 'value' && typeof t.value === type.type
					})
					if (!ok) {
						reportError(path, 'expected ' + formatType(type) + ' but found ' + formatNodeAsPrimitive(node))
					}
					return ok
				case 'string-const':
					if (node.primitives.has({type: 'value', value: type.value}))
						return true
					if (node.primitives.has({type: 'string'}))
						return true
					reportError(path, 'expected ' + formatType(type) + ' but found ' + formatNodeAsPrimitive(node))
					return false
				case 'node':
					bound_nodes.push({type: 'node', node: type.node, bound: node})
					return true
				case 'type-param':
					if (!bound_type_params.has(type.name))
						throw new Error("Unbound type parameter " + type.name)
					// TODO: check constraint
					bound_type_params.push(type.name, {type: 'node', node: node})
					return true
				case 'opaque-type':
					if (node.primitives.has(type)) {
						return true
					} else {
						reportError(path, "expected generic type " + type.name + " but found " + formatNode(node))
						return false
					}
				default:
					throw new Error("Unexpected type: " + util.inspect(type))
			}
			return true
		}
		function isNodeCompatibleWithValue(node, v) {
			node = node.rep()
			if (v === null)
				return true
			if (v && typeof v === 'object')
				return node === getConcreteObject(v.key)
			if (node.primitives.has({type:'value', value:v}))
				return true
			switch (typeof v) {
				case 'number':
					return node.primitives.has({type:'number'})
				case 'string':
					return node.primitives.has({type:'string'})
				case 'boolean':
					return node.primitives.has({type:'boolean'})
				case 'undefined':
					return node.primitives.has({type:'void'})
				default:
					throw new Error("Unexpected value: " + util.inspect(v))
			}
		}
		var type2type_compatible = Object.create(null)
		function isTypeCompatibleWithType(t1, t2, path, continueOnError) {
			if (t1.type === 'reference' || t2.type === 'reference') {
				var h = canonicalizeType(t1) + '~' + canonicalizeType(t2)
				if (h in type2type_compatible)
					return type2type_compatible[h]
				type2type_compatible[h] = true
				return type2type_compatible[h] = isTypeCompatibleWithTypeX(t1, t2, path, continueOnError)
			}
			return isTypeCompatibleWithTypeX(t1, t2, path, continueOnError)
		}
		function isTypeCompatibleWithTypeX(t1, t2, path, continueOnError) {
			if (t1.type === 'any' || t2.type === 'any')
				return true
			if (t1.type === 'node')
				return isNodeCompatibleWithType(t1.node, t2, path)
			if (t1.type === 'reference' && t2.type === 'reference' && t1.name === t2.name) {
				// Approximate compatibility check on references by simply checking type arguments
				// This not technically not a compatibility check between structural types, but
				// I will expect it will produce more useful error messages, 
				// e.g. "expected string[] but found number[]" 
				var ok = t1.typeArguments.all(function(p1, i) {
					return isTypeCompatibleWithType(p1, t2.typeArguments[i], null)
				})
				if (!ok) {
					reportError(path, 'expected ' + formatType(t2) + ' but found ' + formatType(t1))
				}
				return ok
			}
			if (t1.type === 'reference' && t2.type === 'reference') {
				// expand both references, but cut off the path here, so we don't report
				// a complicated message describing why the two references are incompatible
				// e.g. "expected Promise but found HttpRequest" instead of unfolding both types in the error message
				var ok = isTypeCompatibleWithType(resolveTypeRef(t1), resolveTypeRef(t2), null)
				if (!ok) {
					reportError(path, 'expected ' + formatType(t2) + ' but found ' + formatType(t1))
				}
				return ok
			}
			if (t2.type === 'reference')
				t2 = resolveTypeRef(t2)
			if (t2.type === 'object' && (t1.type !== 'object' && t1.type !== 'reference')) {
				// Coerce t1 to an object. If the compatibility check fails, report the error
				// as simply "expected XX but found number" instead of a complicated message resulting from
				// a structural compatibility check
				var t1o = coerceTypeToObject(t1)
				if (t1o.type === 'object' || t1o.type === 'reference') {
					var ok = isTypeCompatibleWithType(t1o, t2, null)
					if (!ok) {
						reportError(path, 'expected ' + formatType(t2) + ' but found ' + formatType(t1))
					}
					return ok
				}
			}
			switch (t2.type) {
				case 'object':
					var original_t1 = t1
					if (t1.type === 'opaque-type' && t1.constraint)
						t1 = t1.constraint
					if (t1.type === 'reference')
						t1 = resolveTypeRef(t1)
					if (t1.type !== 'object') {
						reportError(path, 'expected ' + formatType(t2) + ' but found ' + formatType(original_t1))
						return false
					}
					var ok = true
					for (var k in t2.properties) {
						if (t1.properties.hasOwnProperty(k)) {
							if (!isTypeCompatibleWithType(t1.properties[k].type, t2.properties[k].type, qualify(path,k))) {
								ok = false
								if (!continueOnError) {
									return false
								}
							}
						}
						else if (t1.numberIndexer && isNumberString(k)) {
							if (!isTypeCompatibleWithType(t1.numberIndexer, t2.properties[k].type, qualify(path, k))) {
								ok = false
								if (!continueOnError)
									return false
							}
						}
						else if (t1.stringIndexer) {
							if (!isTypeCompatibleWithType(t1.stringIndexer, t2.properties[k].type, qualify(path, k))) {
								ok = false
								if (!continueOnError)
									return false
							}	
						}
						else {
							if (!t2.properties[k].optional) {
								reportError(qualify(path,k), 'expected ' + formatType(t2) + ' but found nothing')
								ok = false
								if (!continueOnError)
									return false
							}
						}
					}
					if (t2.numberIndexer) {
						for (var k in t1.properties) {
							if (isNumberString(k)) {
								if (!isTypeCompatibleWithType(t1.properties[k].type, t2.numberIndexer, qualify(path, k))) {
									ok = false
									if (!continueOnError)
										return false
								}
							}
						}
						if (t1.numberIndexer) {
							if (!isTypeCompatibleWithType(t1.numberIndexer, t2.numberIndexer, qualify(path, '[number]'))) {
								ok = false
								if (!continueOnError)
									return false
							}
						}
					}
					if (t2.stringIndexer) {
						for (var k in t1.properties) {
							// TODO: enumerability check?
							if (!isTypeCompatibleWithType(t1.properties[k].type, t2.stringIndexer, qualify(path, k))) {
								ok = false
								if (!continueOnError)
									return false
							}
						}
						if (t1.stringIndexer) {
							if (!isTypeCompatibleWithType(t1.stringIndexer, t2.stringIndexer, qualify(path, '[number]'))) {
								ok = false
								if (!continueOnError)
									return false
							}
						}
					}
					// TODO: calls, brands?
					return ok
				case 'number':
				case 'string':
				case 'boolean':
					var ok = t1.type === t2.type || (t1.type === 'value' && typeof t1.value === t2.type)
					if (!ok) {
						reportError(path, 'expected ' + formatType(t2) + ' but found ' + formatType(t1))
					}
					return ok
				case 'string-const':
					var ok = t1.type === 'string' || (t1.type === 'value' && t1.value === t2.value)
					if (!ok) {
						reportError(path, 'expected ' + formatType(t2) + ' but found ' + formatType(t1))
					}
					return ok
				case 'value':
					var ok = (t1.type === typeof t2.value) || (t1.type === 'value' && t1.value === t2.value)
					if (!ok) {
						reportError(path, 'expected ' + formatType(t2) + ' but found ' + formatType(t1))
					}
					return ok
				case 'enum':
					return true // TODO: check enum type properly
				case 'void':
					return true
				case 'node':
					bound_nodes.push({type: 'type', node: t2.node, bound: t1})
					return true
				case 'type-param':
					if (!bound_type_params.has(t2.name))
						throw new Error("Unbound type parameter " + t2.name)
					// TODO: check constraint
					bound_type_params.push(t2.name, {type: 'type', bound: t1})
					return true
				case 'opaque-type':
					if (t1.type === 'opaque-type' && t1.name === t2.name)
						return true
					reportError(path, 'expected generic type ' + t2.name + ' but found ' + formatType(t1))
					return false
				case 'type-param':
					throw new Error
				default:
					throw new Error("Unexpected type: " + t2.type)
			}
		}
		function isCallCompatibleWithCall(incall, outcall) {
			// TODO: variadic
			incall = widenPolymorphicCallSig(incall) // just approximate tests for polymorphic functions (TODO: proper type check)
			outcall = widenPolymorphicCallSig(outcall)

			// Check that the parameters to outcall can be used in a valid call to incall
			for (var i=0; i<incall.parameters.length; ++i) {
				var iparm = incall.parameters[i]
				if (i < outcall.parameters.length) {
					var oparm = outcall.parameters[i]
					if (!isTypeCompatibleWithType(oparm.type, iparm.type, null, false)) {
						return false
					}
				} else if (!iparm.optional) {
					return false
				}
			}

			// Check that return type from incall is a valid return type from outcall
			return isTypeCompatibleWithType(incall.returnType, outcall.returnType, null, false)
		}
		return {
			isTypeCompatibleWithType: isTypeCompatibleWithType,
			isNodeCompatibleWithType: isNodeCompatibleWithType,
			isPrtyCompatibleWithType: isPrtyCompatibleWithType,
			isNodeCompatibleWithProperty: isNodeCompatibleWithProperty,
			isCallCompatibleWithCall: isCallCompatibleWithCall,
			getBoundTypeParams: function() { return bound_type_params },
			getBoundNodes: function() { return bound_nodes },
			getCallSigMatches: function() { return callSigMatches },
		}
	}
581502
function extraction(o) {
      return _.map(o, function (spec, field) {
        var fn = _.extract(spec, ['mutators', direction]) || _.identity;
        return [field, fn];
      });
    }
127522
def extract_backtrace
      stack = caller
      while (first = stack.first) && first.include?(SELF_PATTERN)
        stack.shift
      end
      stack
    end
465590
def from_type_name(cls, typ, name):
        """"""
        # Try aliases first.
        for k, nt in cls.defined_aliases.items():
            if typ is not None and typ != nt.type: continue
            #print(name, nt.name)
            if name == nt.name:
                if len(k) == 1: return cls(xc=k)
                if len(k) == 2: return cls(x=k[0], c=k[1])
                raise ValueError("Wrong key: %s" % k)

        # At this point, we should have something in the form
        # name="GGA_X_PBE+GGA_C_PBE" or  name=""LDA_XC_TETER93"
        if "+" in name:
            #if typ is not None: raise ValueError("typ: `%s` but name: `%s`" % (typ, name))
            x, c = (s.strip() for s in name.split("+"))
            x, c = LibxcFunc[x], LibxcFunc[c]
            return cls(x=x, c=c)
        else:
            #if typ is not None: raise ValueError("typ: `%s` but name: `%s`" % (typ, name))
            xc = LibxcFunc[name]
            return cls(xc=xc)

        if typ is None:
            raise ValueError("Cannot find name=%s in defined_aliases" % name)
        else:
            raise ValueError("Cannot find type=%s, name=%s in defined_aliases" % (typ, name))
1116640
function getMutations(spec, attr) {
      var fns = compose(extraction, cleanup, stitch)(spec);
      return _.callmap(fns, attr);
    }
185754
function fromUnaryType(t) {
    return UnaryType (t.name)
                     (t.url)
                     (t.supertypes)
                     (t._test ([]))
                     (t._extractors.$1);
  }
119136
function throwErrorOnUndefinedColumnName(keys, extract) {
    var regexRefs = /([a-zA-Z$_][\w$]+)(\s*\.\s*[a-zA-Z$_][\w$]+)*/g, // identifier[.identifier]...
        parts, variable;

    keys = keys.concat(['true', 'false']);

    // search for variable references, excluding property references (with dot operator prefix)
    while ((parts = regexRefs.exec(extract))) {
        variable = parts[1];
        if (keys.indexOf(variable) < 0) {
            throw new ReferenceError(variable + ' not defined.');
        }
    }
}
845735
function fromUncheckedBinaryType(typeConstructor) {
    var t = typeConstructor (Unknown) (Unknown);
    return def (t.name) ({}) ([Type, Type, Type]) (fromBinaryType (t));
  }
1045274
private List<String> diagnoseIndexMismatch(Index theIndex, Index otherIndex) {
        List<String> mismatchedAttrs = new ArrayList<>();

        // Pairs of matching indexes must agree on type (int hash, etc.).
        if (theIndex.getType() != otherIndex.getType()) {
            mismatchedAttrs.add("index type (hash vs tree)");
        }

        // Pairs of matching indexes must agree whether they are (assume)unique.
        if (theIndex.getUnique() != otherIndex.getUnique() ||
                theIndex.getAssumeunique() != otherIndex.getAssumeunique()) {
            mismatchedAttrs.add("UNIQUE attribute");
        }

        // Pairs of matching indexes must agree whether they are partial
        // and if so, agree on the predicate.
        String thePredicateJSON = theIndex.getPredicatejson();
        String otherPredicateJSON = otherIndex.getPredicatejson();
        if (thePredicateJSON == null) {
            if (otherPredicateJSON != null) {
                mismatchedAttrs.add("WHERE predicate");
            }
        }
        else if ( ! thePredicateJSON.equals(otherPredicateJSON)) {
            mismatchedAttrs.add("WHERE predicate");
        }

        // Pairs of matching indexes must agree that they do or do not index
        // expressions and, if so, agree on the expressions.
        String theExprsJSON = theIndex.getExpressionsjson();
        String otherExprsJSON = otherIndex.getExpressionsjson();
        if (theExprsJSON == null) {
            if (otherExprsJSON != null) {
                mismatchedAttrs.add("indexed expression");
            }
        }
        else if ( ! theExprsJSON.equals(otherExprsJSON)) {
            mismatchedAttrs.add("indexed expression");
        }


        // Indexes must agree on the columns they are based on,
        // identifiable by the columns' order in the table.
        CatalogMap<ColumnRef> theColumns = theIndex.getColumns();
        int theColumnCount = theColumns.size();
        CatalogMap<ColumnRef> otherColumns = otherIndex.getColumns();
        if (theColumnCount != otherColumns.size() ) {
            mismatchedAttrs.add("indexed expression");
        }

        Iterator<ColumnRef> theColumnIterator = theColumns.iterator();
        Iterator<ColumnRef> otherColumnIterator = otherColumns.iterator();
        for (int ii = 0 ;ii < theColumnCount; ++ii) {
            int theColIndex = theColumnIterator.next().getColumn().getIndex();
            int otherColIndex = otherColumnIterator.next().getColumn().getIndex();
            if (theColIndex != otherColIndex) {
                mismatchedAttrs.add("indexed expression");
            }
        }

        return mismatchedAttrs;
    }
822465
def _fixup_cdef_enums(string, reg=re.compile(r"=\s*(\d+)\s*<<\s*(\d+)")):
    """"""

    def repl_shift(match):
        shift_by = int(match.group(2))
        value = int(match.group(1))
        int_value = ctypes.c_int(value << shift_by).value
        return "= %s" % str(int_value)
    return reg.sub(repl_shift, string)
1339490
def RawParserUnparserFactory(parser_name, parse_callable, *unparse_callables):
    

    def build_unparse(f):
        @wraps(f)
        def unparse(self, source, *a, **kw):
            node = parse_callable(source)
            return f(node, *a, **kw)
        # a dumb and lazy docstring replacement
        unparse.__doc__ = f.__doc__.replace(
            'ast\n        The AST ',
            'source\n        The source ',
        )
        return unparse

    def build_parse(f):
        @wraps(f)
        def parse(self, source):
            return f(source)
        parse.__name__ = parser_name
        parse.__qualname__ = parser_name
        return parse

    callables = {f.__name__: build_unparse(f) for f in unparse_callables}
    callables['__call__'] = build_parse(parse_callable)
    callables['__module__'] = PKGNAME
    return type(parser_name, (object,), callables)()
349219
def _preprocess_typecheck(argSig, argspecs, slf_or_clsm = False):
    
    # todo: Maybe move also slf-logic here
    vargs = argspecs.varargs
    try:
        kw = argspecs.keywords
    except AttributeError:
        kw = argspecs.varkw
    try:
        kwonly = argspecs.kwonlyargs
    except AttributeError:
        kwonly = None
    if not vargs is None or not kw is None:
        arg_type_lst = list(get_Tuple_params(argSig))
        if not vargs is None:
            vargs_pos = (len(argspecs.args)-1) \
                    if slf_or_clsm else len(argspecs.args)
            # IndexErrors in this section indicate that a child-method was
            # checked against a parent's type-info with the child featuring
            # a more wider type on signature level (e.g. adding vargs)
            try:
                vargs_type = typing.Sequence[arg_type_lst[vargs_pos]]
            except IndexError:
                vargs_type = typing.Sequence[typing.Any]
            try:
                arg_type_lst[vargs_pos] = vargs_type
            except IndexError:
                arg_type_lst.append(vargs_type)
        if not kw is None:
            kw_pos = len(argspecs.args)
            if slf_or_clsm:
                kw_pos -= 1
            if not vargs is None:
                kw_pos += 1
            if not kwonly is None:
                kw_pos += len(kwonly)
            try:
                kw_type = typing.Dict[str, arg_type_lst[kw_pos]]
            except IndexError:
                kw_type = typing.Dict[str, typing.Any]
            try:
                arg_type_lst[kw_pos] = kw_type
            except IndexError:
                arg_type_lst.append(kw_type)
        return typing.Tuple[tuple(arg_type_lst)]
    else:
        return argSig
901575
def op_match_funcdef_handle(self, original, loc, tokens):
        """"""
        if len(tokens) == 3:
            func, args = get_infix_items(tokens)
            cond = None
        elif len(tokens) == 4:
            func, args = get_infix_items(tokens[:-1])
            cond = tokens[-1]
        else:
            raise CoconutInternalException("invalid infix match function definition tokens", tokens)
        name_tokens = [func, args]
        if cond is not None:
            name_tokens.append(cond)
        return self.name_match_funcdef_handle(original, loc, name_tokens)
249634
private static int getFullModifiers(ClassStub data, AsmReferenceResolver resolver) {
        String className = data.className;
        int bound = className.length();
        while (bound > 0) {
            int idx = className.lastIndexOf('$', bound);
            if (idx > 0) {
                ClassNode outerClass = resolver.resolveClassNullable(className.substring(0, idx));
                if (outerClass instanceof DecompiledClassNode) {
                    Integer outerModifiers = ((DecompiledClassNode) outerClass).classData.innerClassModifiers.get(className.substring(idx + 1));
                    if (outerModifiers != null) {
                        return data.accessModifiers | outerModifiers;
                    }
                }
            }
            bound = idx - 1;
        }
        return data.accessModifiers;
    }
437958
function _Type(
    type,       // :: String
    name,       // :: String
    url,        // :: String
    arity,      // :: NonNegativeInteger
    format,
    // :: Nullable ((String -> String, String -> String -> String) -> String)
    supertypes, // :: Array Type
    test,       // :: Any -> Boolean
    tuples      // :: Array (Array3 String (a -> Array b) Type)
  ) {
    var t = Object.create (Type$prototype);
    t._test = test;
    t._extractors = tuples.reduce (function(_extractors, tuple) {
      _extractors[tuple[0]] = tuple[1];
      return _extractors;
    }, {});
    t.arity = arity;  // number of type parameters
    t.extractors = Z.map (B (toArray), t._extractors);
    t.format = format || function(outer, inner) {
      return Z.reduce (function(s, tuple) {
        return s +
               outer (' ') +
               when (tuple[2].arity > 0)
                    (parenthesize (outer))
                    (inner (tuple[0]) (show (tuple[2])));
      }, outer (name), tuples);
    };
    t.keys = tuples.map (function(tuple) { return tuple[0]; });
    t.name = name;
    t.supertypes = supertypes;
    t.type = type;
    t.types = tuples.reduce (function(types, tuple) {
      types[tuple[0]] = tuple[2];
      return types;
    }, {});
    t.url = url;
    return t;
  }