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

📄 check.java

📁 是一款用JAVA 编写的编译器 具有很强的编译功能
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
    }    /** 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.     *  @returns        True if the check completed on all attributed classes     */    private boolean checkNonCyclicInternal(DiagnosticPosition pos, Type t) {	boolean complete = true; // was the check complete?	//- System.err.println("checkNonCyclicInternal("+t+");");//DEBUG	Symbol c = t.tsym;	if ((c.flags_field & ACYCLIC) != 0) return true;	if ((c.flags_field & LOCKED) != 0) {	    noteCyclic(pos, (ClassSymbol)c);	} else if (!c.type.isErroneous()) {	    try {		c.flags_field |= LOCKED;		if (c.type.tag == CLASS) {		    ClassType clazz = (ClassType)c.type;		    if (clazz.interfaces_field != null)			for (List<Type> l=clazz.interfaces_field; l.nonEmpty(); l=l.tail)			    complete &= checkNonCyclicInternal(pos, l.head);		    if (clazz.supertype_field != null) {			Type st = clazz.supertype_field;			if (st != null && st.tag == CLASS)			    complete &= checkNonCyclicInternal(pos, st);		    }		    if (c.owner.kind == TYP)			complete &= checkNonCyclicInternal(pos, c.owner.type);		}	    } finally {		c.flags_field &= ~LOCKED;	    }	}	if (complete)	    complete = ((c.flags_field & UNATTRIBUTED) == 0) && c.completer == null;	if (complete) c.flags_field |= ACYCLIC;	return complete;    }    /** Note that we found an inheritance cycle. */    private void noteCyclic(DiagnosticPosition pos, ClassSymbol c) {	log.error(pos, "cyclic.inheritance", c);	for (List<Type> l=types.interfaces(c.type); l.nonEmpty(); l=l.tail)	    l.head = new ErrorType((ClassSymbol)l.head.tsym);	Type st = types.supertype(c.type);	if (st.tag == CLASS)	    ((ClassType)c.type).supertype_field = new ErrorType((ClassSymbol)st.tsym);	c.type = new ErrorType(c);	c.flags_field |= ACYCLIC;    }    /** Check that all methods which implement some     *  method conform to the method they implement.     *  @param tree         The class definition whose members are checked.     */    void checkImplementations(JCClassDecl tree) {	checkImplementations(tree, tree.sym);    }//where        /** Check that all methods which implement some	 *  method in `ic' conform to the method they implement.	 */	void checkImplementations(JCClassDecl tree, ClassSymbol ic) {	    ClassSymbol origin = tree.sym;	    for (List<Type> l = types.closure(ic.type); l.nonEmpty(); l = l.tail) {		ClassSymbol lc = (ClassSymbol)l.head.tsym;		if ((allowGenerics || origin != lc) && (lc.flags() & ABSTRACT) != 0) {		    for (Scope.Entry e=lc.members().elems; e != null; e=e.sibling) {			if (e.sym.kind == MTH &&			    (e.sym.flags() & (STATIC|ABSTRACT)) == ABSTRACT) {			    MethodSymbol absmeth = (MethodSymbol)e.sym;			    MethodSymbol implmeth = absmeth.implementation(origin, types, false);			    if (implmeth != null && implmeth != absmeth &&				(implmeth.owner.flags() & INTERFACE) ==				(origin.flags() & INTERFACE)) {				// don't check if implmeth is in a class, yet				// origin is an interface. This case arises only				// if implmeth is declared in Object. The reason is				// that interfaces really don't inherit from				// Object it's just that the compiler represents				// things that way.				checkOverride(tree, implmeth, absmeth, origin);			    }			}		    }		}	    }	}    /** Check that all abstract methods implemented by a class are     *  mutually compatible.     *  @param pos          Position to be used for error reporting.     *  @param c            The class whose interfaces are checked.     */    void checkCompatibleSupertypes(DiagnosticPosition pos, Type c) {	List<Type> supertypes = types.interfaces(c);	Type supertype = types.supertype(c);	if (supertype.tag == CLASS &&	    (supertype.tsym.flags() & ABSTRACT) != 0)	    supertypes = supertypes.prepend(supertype);	for (List<Type> l = supertypes; l.nonEmpty(); l = l.tail) {	    if (allowGenerics && !l.head.getTypeArguments().isEmpty() &&		!checkCompatibleAbstracts(pos, l.head, l.head, c))		return;	    for (List<Type> m = supertypes; m != l; m = m.tail)		if (!checkCompatibleAbstracts(pos, l.head, m.head, c))		    return;	}	checkCompatibleConcretes(pos, c);    }    /** Check that class c does not implement directly or indirectly     *  the same parameterized interface with two different argument lists.     *  @param pos          Position to be used for error reporting.     *  @param type         The type whose interfaces are checked.     */    void checkClassBounds(DiagnosticPosition pos, Type type) {	checkClassBounds(pos, new HashMap<TypeSymbol,Type>(), type);    }//where        /** Enter all interfaces of type `type' into the hash table `seensofar'	 *  with their class symbol as key and their type as value. Make	 *  sure no class is entered with two different types.	 */	void checkClassBounds(DiagnosticPosition pos,			      Map<TypeSymbol,Type> seensofar,			      Type type) {	    if (type.isErroneous()) return;	    for (List<Type> l = types.interfaces(type); l.nonEmpty(); l = l.tail) {		Type it = l.head;		Type oldit = seensofar.put(it.tsym, it);		if (oldit != null) {		    List<Type> oldparams = oldit.allparams();		    List<Type> newparams = it.allparams();		    if (!types.containsTypeEquivalent(oldparams, newparams))			log.error(pos, "cant.inherit.diff.arg",				  it.tsym, Type.toString(oldparams),				  Type.toString(newparams));		}		checkClassBounds(pos, seensofar, it);	    }	    Type st = types.supertype(type);	    if (st != null) checkClassBounds(pos, seensofar, st);	}    /** Enter interface into into set.     *  If it existed already, issue a "repeated interface" error.     */    void checkNotRepeated(DiagnosticPosition pos, Type it, Set<Type> its) {	if (its.contains(it))	    log.error(pos, "repeated.interface");	else {	    its.add(it);	}    }	/* ************************************************************************* * Check annotations **************************************************************************/    /** Annotation types are restricted to primitives, String, an     *  enum, an annotation, Class, Class<?>, Class<? extends     *  Anything>, arrays of the preceding.     */    void validateAnnotationType(JCTree restype) {        // restype may be null if an error occurred, so don't bother validating it        if (restype != null) {            validateAnnotationType(restype.pos(), restype.type);        }    }    void validateAnnotationType(DiagnosticPosition pos, Type type) {	if (type.isPrimitive()) return;	if (types.isSameType(type, syms.stringType)) return;        if ((type.tsym.flags() & Flags.ENUM) != 0) return;	if ((type.tsym.flags() & Flags.ANNOTATION) != 0) return;	if (types.lowerBound(type).tsym == syms.classType.tsym) return;	if (types.isArray(type) && !types.isArray(types.elemtype(type))) {	    validateAnnotationType(pos, types.elemtype(type));	    return;	}	log.error(pos, "invalid.annotation.member.type");    }    /**     * "It is also a compile-time error if any method declared in an     * annotation type has a signature that is override-equivalent to     * that of any public or protected method declared in class Object     * or in the interface annotation.Annotation."     *     * @jls3 9.6 Annotation Types     */    void validateAnnotationMethod(DiagnosticPosition pos, MethodSymbol m) {        for (Type sup = syms.annotationType; sup.tag == CLASS; sup = types.supertype(sup)) {            Scope s = sup.tsym.members();            for (Scope.Entry e = s.lookup(m.name); e.scope != null; e = e.next()) {                if (e.sym.kind == MTH &&                    (e.sym.flags() & (PUBLIC | PROTECTED)) != 0 &&                    types.overrideEquivalent(m.type, e.sym.type))                    log.error(pos, "intf.annotation.member.clash", e.sym, sup);            }        }    }    /** Check the annotations of a symbol.     */    public void validateAnnotations(List<JCAnnotation> annotations, Symbol s) {	if (skipAnnotations) return;	for (JCAnnotation a : annotations)	    validateAnnotation(a, s);    }    /** Check an annotation of a symbol.     */    public void validateAnnotation(JCAnnotation a, Symbol s) {	validateAnnotation(a);	if (!annotationApplicable(a, s))	    log.error(a.pos(), "annotation.type.not.applicable");	if (a.annotationType.type.tsym == syms.overrideType.tsym) {	    if (!isOverrider(s))		log.error(a.pos(), "method.does.not.override.superclass");	}    }    /** Is s a method symbol that overrides a method in a superclass? */    boolean isOverrider(Symbol s) {        if (s.kind != MTH || s.isStatic())            return false;        MethodSymbol m = (MethodSymbol)s;        TypeSymbol owner = (TypeSymbol)m.owner;        for (Type sup : types.closure(owner.type)) {            if (sup == owner.type)                continue; // skip "this"            Scope scope = sup.tsym.members();            for (Scope.Entry e = scope.lookup(m.name); e.scope != null; e = e.next()) {                if (!e.sym.isStatic() && m.overrides(e.sym, owner, types, true))                    return true;            }        }        return false;    }    /** Is the annotation applicable to the symbol? */    boolean annotationApplicable(JCAnnotation a, Symbol s) {	Attribute.Compound atTarget =	    a.annotationType.type.tsym.attribute(syms.annotationTargetType.tsym);	if (atTarget == null) return true;	Attribute atValue = atTarget.member(names.value);	if (!(atValue instanceof Attribute.Array)) return true; // error recovery	Attribute.Array arr = (Attribute.Array) atValue;	for (Attribute app : arr.values) {	    if (!(app instanceof Attribute.Enum)) return true; // recovery	    Attribute.Enum e = (Attribute.Enum) app;	    if (e.value.name == names.TYPE)		{ if (s.kind == TYP) return true; }	    else if (e.value.name == names.FIELD)		{ if (s.kind == VAR && s.owner.kind != MTH) return true; }	    else if (e.value.name == names.METHOD)		{ if (s.kind == MTH && !s.isConstructor()) return true; }	    else if (e.value.name == names.PARAMETER)		{ if (s.kind == VAR &&		      s.owner.kind == MTH &&		      (s.flags() & PARAMETER) != 0)		    return true;		}	    else if (e.value.name == names.CONSTRUCTOR)		{ if (s.kind == MTH && s.isConstructor()) return true; }	    else if (e.value.name == names.LOCAL_VARIABLE)		{ if (s.kind == VAR && s.owner.kind == MTH &&		      (s.flags() & PARAMETER) == 0)		    return true;		}	    else if (e.value.name == names.ANNOTATION_TYPE)		{ if (s.kind == TYP && (s.flags() & ANNOTATION) != 0)		    return true;		}	    else if (e.value.name == names.PACKAGE)		{ if (s.kind == PCK) return true; }	    else		return true; // recovery	}	return false;    }    /** Check an annotation value.     */    public void validateAnnotation(JCAnnotation a) {        if (a.type.isErroneous()) return;	// collect an inventory of the members	Set<MethodSymbol> members = new HashSet<MethodSymbol>();	for (Scope.Entry e = a.annotationType.type.tsym.members().elems;	     e != null;	     e = e.sibling)	    if (e.sym.kind == MTH)                members.add((MethodSymbol) e.sym);	// count them off as they're annotated	for (JCTree arg : a.args) {	    if (arg.getTag() != JCTree.ASSIGN) continue; // recovery	    JCAssign assign = (JCAssign) arg;	    Symbol m = TreeInfo.symbol(assign.lhs);	    if (m == null || m.type.isErroneous()) continue;	    if (!members.remove(m))		log.error(arg.pos(), "duplicate.annotation.member.value",			  m.name, a.type);	    if (assign.rhs.getTag() == ANNOTATION)		validateAnnotation((JCAnnotation)assign.rhs);	}	// all the remaining ones better have default values	for (MethodSymbol m : members)	    if (m.defaultValue == null && !m.type.isErroneous())		log.error(a.pos(), "annotation.missing.default.value",                           a.type, m.name);	// special case: java.lang.annotation.Target must not have	// repeated values in its value member	if (a.annotationType.type.tsym != syms.annotationTargetType.tsym ||	    a.args.tail == null)	    return;        if (a.args.head.getTag() != JCTree.ASSIGN) return; // error recovery	JCAssign assign = (JCAssign) a.args.head;	Symbol m = TreeInfo.symbol(assign.lhs);	if (m.name != names.value) return;	JCTree rhs = assign.rhs;	if (rhs.getTag() != JCTree.NEWARRAY) return;	JCNewArray na = (JCNewArray) rhs;	Set<Symbol> targets = new HashSet<Symbol>();	for (JCTree elem : na.elems) {	    if (!targets.add(TreeInfo.symbol(elem))) {		log.error(elem.pos(), "repeated.annotation.target");	    }	}    }    void checkDeprecatedAnnotation(DiagnosticPosition pos, Symbol s) {	if (allowAnnotations &&	    lint.isEnabled(Lint.LintCategory.DEP_ANN) &&	    (s.flags() & DEPRECATED) != 0 &&	    !syms.deprecatedType.isErroneous() &&	    s.attribute(syms.deprecatedType.tsym) == null) {	    log.warning(pos, "missing.deprecated.annotation");	}    }/* ************************************************************************* * Check for recursive annotation elements. **************************************************************************/    /** Check for cycles in the graph of annotation elements.     */    void checkNonCyclicElements(JCClassDecl tree) {        if ((tree.sym.flags_field & ANNOTATION) == 0) return;        assert (tree.sym.flags_field & LOCKED) == 0;        try {            tree.sym.flags_field |= LOCKED;            for (JCTree def : tree.defs) {                if (def.getTag() != JCTree.METHODDEF) continue;                JCMethodDecl meth = (JCMethodDecl)def;                checkAnnotationResType(meth.

⌨️ 快捷键说明

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