⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 check.java

📁 是一款用JAVA 编写的编译器 具有很强的编译功能
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
		      cannotOverride(m, other),		      protectionString(other.flags()));	    return;	}	Type mt = types.memberType(origin.type, m);	Type ot = types.memberType(origin.type, other);	// Error if overriding result type is different	// (or, in the case of generics mode, not a subtype) of	// overridden result type. We have to rename any type parameters	// before comparing types.	List<Type> mtvars = mt.getTypeArguments();	List<Type> otvars = ot.getTypeArguments();	Type mtres = mt.getReturnType();	Type otres = types.subst(ot.getReturnType(), otvars, mtvars);	overrideWarner.warned = false;	boolean resultTypesOK =	    types.returnTypeSubstitutable(mt, ot, otres, overrideWarner);	if (!resultTypesOK) {	    if (!source.allowCovariantReturns() &&		m.owner != origin &&		m.owner.isSubClass(other.owner, types)) {		// allow limited interoperability with covariant returns	    } else {		typeError(TreeInfo.diagnosticPositionFor(m, tree),			  JCDiagnostic.fragment("override.incompatible.ret",					 cannotOverride(m, other)),			  mtres, otres);		return;	    }	} else if (overrideWarner.warned) {	    warnUnchecked(TreeInfo.diagnosticPositionFor(m, tree),			  "prob.found.req",			  JCDiagnostic.fragment("override.unchecked.ret",					      uncheckedOverrides(m, other)),			  mtres, otres);	}		// Error if overriding method throws an exception not reported	// by overridden method.	List<Type> otthrown = types.subst(ot.getThrownTypes(), otvars, mtvars);	List<Type> unhandled = unHandled(mt.getThrownTypes(), otthrown);	if (unhandled.nonEmpty()) {	    log.error(TreeInfo.diagnosticPositionFor(m, tree),		      "override.meth.doesnt.throw",		      cannotOverride(m, other),		      unhandled.head);	    return;	}	// Optional warning if varargs don't agree 	if ((((m.flags() ^ other.flags()) & Flags.VARARGS) != 0)	    && lint.isEnabled(Lint.LintCategory.OVERRIDES)) {	    log.warning(TreeInfo.diagnosticPositionFor(m, tree),			((m.flags() & Flags.VARARGS) != 0)			? "override.varargs.missing"			: "override.varargs.extra",			varargsOverrides(m, other));	} 	// Warn if instance method overrides bridge method (compiler spec ??)	if ((other.flags() & BRIDGE) != 0) {	    log.warning(TreeInfo.diagnosticPositionFor(m, tree), "override.bridge",			uncheckedOverrides(m, other));	}	// Warn if a deprecated method overridden by a non-deprecated one.	if ((other.flags() & DEPRECATED) != 0 	    && (m.flags() & DEPRECATED) == 0 	    && m.outermostClass() != other.outermostClass()	    && !isDeprecatedOverrideIgnorable(other, origin)) {	    warnDeprecated(TreeInfo.diagnosticPositionFor(m, tree), other);	}    }    // where	private boolean isDeprecatedOverrideIgnorable(MethodSymbol m, ClassSymbol origin) {	    // If the method, m, is defined in an interface, then ignore the issue if the method	    // is only inherited via a supertype and also implemented in the supertype,	    // because in that case, we will rediscover the issue when examining the method	    // in the supertype.	    // If the method, m, is not defined in an interface, then the only time we need to	    // address the issue is when the method is the supertype implemementation: any other	    // case, we will have dealt with when examining the supertype classes	    ClassSymbol mc = m.enclClass();	    Type st = types.supertype(origin.type);	    if (st.tag != CLASS)		return true;	    MethodSymbol stimpl = m.implementation((ClassSymbol)st.tsym, types, false);	    if (mc != null && ((mc.flags() & INTERFACE) != 0)) {		List<Type> intfs = types.interfaces(origin.type);		return (intfs.contains(mc.type) ? false : (stimpl != null));	    }	    else		return (stimpl != m);	}    // used to check if there were any unchecked conversions    Warner overrideWarner = new Warner();    /** Check that a class does not inherit two concrete methods     *  with the same signature.     *  @param pos          Position to be used for error reporting.     *  @param site         The class type to be checked.     */    public void checkCompatibleConcretes(DiagnosticPosition pos, Type site) {	Type sup = types.supertype(site);	if (sup.tag != CLASS) return;	for (Type t1 = sup;	     t1.tsym.type.isParameterized();	     t1 = types.supertype(t1)) {	    for (Scope.Entry e1 = t1.tsym.members().elems;		 e1 != null;		 e1 = e1.sibling) {		Symbol s1 = e1.sym;		if (s1.kind != MTH ||		    (s1.flags() & (STATIC|SYNTHETIC|BRIDGE)) != 0 ||		    !s1.isInheritedIn(site.tsym, types) ||		    ((MethodSymbol)s1).implementation(site.tsym,						      types,						      true) != s1)		    continue;		Type st1 = types.memberType(t1, s1);		int s1ArgsLength = st1.getParameterTypes().length();		if (st1 == s1.type) continue;		for (Type t2 = sup;		     t2.tag == CLASS;		     t2 = types.supertype(t2)) {		    for (Scope.Entry e2 = t1.tsym.members().lookup(s1.name);			 e2.scope != null;			 e2 = e2.next()) {			Symbol s2 = e2.sym;			if (s2 == s1 ||			    s2.kind != MTH ||			    (s2.flags() & (STATIC|SYNTHETIC|BRIDGE)) != 0 ||			    s2.type.getParameterTypes().length() != s1ArgsLength ||			    !s2.isInheritedIn(site.tsym, types) ||			    ((MethodSymbol)s2).implementation(site.tsym,							      types,							      true) != s2)			    continue;			Type st2 = types.memberType(t2, s2);			if (types.overrideEquivalent(st1, st2))			    log.error(pos, "concrete.inheritance.conflict",				      s1, t1, s2, t2, sup);		    }		}	    }	}    }    /** Check that classes (or interfaces) do not each define an abstract     *  method with same name and arguments but incompatible return types.     *  @param pos          Position to be used for error reporting.     *  @param t1           The first argument type.     *  @param t2           The second argument type.     */    public boolean checkCompatibleAbstracts(DiagnosticPosition pos,					    Type t1,					    Type t2) {        return checkCompatibleAbstracts(pos, t1, t2,                                        types.makeCompoundType(t1, t2));    }    public boolean checkCompatibleAbstracts(DiagnosticPosition pos,					    Type t1,					    Type t2,					    Type site) {	Symbol sym = firstIncompatibility(t1, t2, site);	if (sym != null) {	    log.error(pos, "types.incompatible.diff.ret",		      t1, t2, sym.name +		      "(" + types.memberType(t2, sym).getParameterTypes() + ")");	    return false;	}	return true;    }    /** Return the first method which is defined with same args     *  but different return types in two given interfaces, or null if none     *  exists.     *  @param t1     The first type.     *  @param t2     The second type.     *  @param site   The most derived type.     *  @returns symbol from t2 that conflicts with one in t1.     */    private Symbol firstIncompatibility(Type t1, Type t2, Type site) {	Map<TypeSymbol,Type> interfaces1 = new HashMap<TypeSymbol,Type>();	closure(t1, interfaces1);	Map<TypeSymbol,Type> interfaces2;	if (t1 == t2)	    interfaces2 = interfaces1;	else	    closure(t2, interfaces1, interfaces2 = new HashMap<TypeSymbol,Type>());	for (Type t3 : interfaces1.values()) {	    for (Type t4 : interfaces2.values()) {		Symbol s = firstDirectIncompatibility(t3, t4, site);		if (s != null) return s;	    }	}	return null;    }    /** Compute all the supertypes of t, indexed by type symbol. */    private void closure(Type t, Map<TypeSymbol,Type> typeMap) {	if (t.tag != CLASS) return;	if (typeMap.put(t.tsym, t) == null) {	    closure(types.supertype(t), typeMap);	    for (Type i : types.interfaces(t))		closure(i, typeMap);	}    }    /** Compute all the supertypes of t, indexed by type symbol (except thise in typesSkip). */    private void closure(Type t, Map<TypeSymbol,Type> typesSkip, Map<TypeSymbol,Type> typeMap) {	if (t.tag != CLASS) return;	if (typesSkip.get(t.tsym) != null) return;	if (typeMap.put(t.tsym, t) == null) {	    closure(types.supertype(t), typesSkip, typeMap);	    for (Type i : types.interfaces(t))		closure(i, typesSkip, typeMap);	}    }    /** Return the first method in t2 that conflicts with a method from t1. */    private Symbol firstDirectIncompatibility(Type t1, Type t2, Type site) {	for (Scope.Entry e1 = t1.tsym.members().elems; e1 != null; e1 = e1.sibling) {	    Symbol s1 = e1.sym;	    Type st1 = null;	    if (s1.kind != MTH || !s1.isInheritedIn(site.tsym, types)) continue;            Symbol impl = ((MethodSymbol)s1).implementation(site.tsym, types, false);            if (impl != null && (impl.flags() & ABSTRACT) == 0) continue;	    for (Scope.Entry e2 = t2.tsym.members().lookup(s1.name); e2.scope != null; e2 = e2.next()) {		Symbol s2 = e2.sym;		if (s1 == s2) continue;		if (s2.kind != MTH || !s2.isInheritedIn(site.tsym, types)) continue;		if (st1 == null) st1 = types.memberType(t1, s1);		Type st2 = types.memberType(t2, s2);		if (types.overrideEquivalent(st1, st2)) {		    List<Type> tvars1 = st1.getTypeArguments();		    List<Type> tvars2 = st2.getTypeArguments();		    Type rt1 = st1.getReturnType();		    Type rt2 = types.subst(st2.getReturnType(), tvars2, tvars1);		    boolean compat =			types.isSameType(rt1, rt2) ||                        rt1.tag >= CLASS && rt2.tag >= CLASS &&                        (types.covariantReturnType(rt1, rt2, Warner.noWarnings) ||                         types.covariantReturnType(rt2, rt1, Warner.noWarnings));		    if (!compat) return s2;		}	    }	}	return null;    }    /** Check that a given method conforms with any method it overrides.     *  @param tree         The tree from which positions are extracted     *			    for errors.     *  @param m            The overriding method.     */    void checkOverride(JCTree tree, MethodSymbol m) {	ClassSymbol origin = (ClassSymbol)m.owner;	if ((origin.flags() & ENUM) != 0 && names.finalize.equals(m.name))	    if (m.overrides(syms.enumFinalFinalize, origin, types, false)) {		log.error(tree.pos(), "enum.no.finalize");		return;	    }	for (Type t = types.supertype(origin.type); t.tag == CLASS;	     t = types.supertype(t)) {	    TypeSymbol c = t.tsym;	    Scope.Entry e = c.members().lookup(m.name);	    while (e.scope != null) {		if (m.overrides(e.sym, origin, types, false))		    checkOverride(tree, m, (MethodSymbol)e.sym, origin);		e = e.next();	    }	}    }    /** Check that all abstract members of given class have definitions.     *  @param pos          Position to be used for error reporting.     *  @param c            The class.     */    void checkAllDefined(DiagnosticPosition pos, ClassSymbol c) {	try {	    MethodSymbol undef = firstUndef(c, c);	    if (undef != null) {                if ((c.flags() & ENUM) != 0 &&                    types.supertype(c.type).tsym == syms.enumSym &&                    (c.flags() & FINAL) == 0) {                    // add the ABSTRACT flag to an enum                    c.flags_field |= ABSTRACT;                } else {                    MethodSymbol undef1 =                        new MethodSymbol(undef.flags(), undef.name,                                         types.memberType(c.type, undef), undef.owner);                    log.error(pos, "does.not.override.abstract",                              c, undef1, undef1.location());                }            }	} catch (CompletionFailure ex) {	    completionError(pos, ex);	}    }//where        /** Return first abstract member of class `c' that is not defined	 *  in `impl', null if there is none.	 */	private MethodSymbol firstUndef(ClassSymbol impl, ClassSymbol c) {	    MethodSymbol undef = null;	    // Do not bother to search in classes that are not abstract,	    // since they cannot have abstract members.	    if (c == impl || (c.flags() & (ABSTRACT | INTERFACE)) != 0) {		Scope s = c.members();		for (Scope.Entry e = s.elems;		     undef == null && e != null;		     e = e.sibling) {		    if (e.sym.kind == MTH &&			(e.sym.flags() & (ABSTRACT|IPROXY)) == ABSTRACT) {			MethodSymbol absmeth = (MethodSymbol)e.sym;			MethodSymbol implmeth = absmeth.implementation(impl, types, true);			if (implmeth == null || implmeth == absmeth)			    undef = absmeth;		    }		}		if (undef == null) {		    Type st = types.supertype(c.type);		    if (st.tag == CLASS)			undef = firstUndef(impl, (ClassSymbol)st.tsym);		}		for (List<Type> l = types.interfaces(c.type);		     undef == null && l.nonEmpty();		     l = l.tail) {		    undef = firstUndef(impl, (ClassSymbol)l.head.tsym);		}	    }	    return undef;	}    /** Check for cyclic references. Issue an error if the     *  symbol of the type referred to has a LOCKED flag set.     *     *  @param pos      Position to be used for error reporting.     *  @param t        The type referred to.     */    void checkNonCyclic(DiagnosticPosition pos, Type t) {	checkNonCyclicInternal(pos, t);    }    void checkNonCyclic(DiagnosticPosition pos, TypeVar t) {        checkNonCyclic1(pos, t, new HashSet<TypeVar>());    }    private void checkNonCyclic1(DiagnosticPosition pos, Type t, Set<TypeVar> seen) {        final TypeVar tv;        if (seen.contains(t)) {            tv = (TypeVar)t;            tv.bound = new ErrorType();            log.error(pos, "cyclic.inheritance", t);        } else if (t.tag == TYPEVAR) {            tv = (TypeVar)t;            seen.add(tv);            for (Type b : types.getBounds(tv))                checkNonCyclic1(pos, b, seen);        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -