com.sun.tools.javac.util.List Java Examples

The following examples show how to use com.sun.tools.javac.util.List. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Analyzer.java    From openjdk-jdk9 with GNU General Public License v2.0 6 votes vote down vote up
@Override
void process(JCNewClass oldTree, JCNewClass newTree, boolean hasErrors) {
    if (!hasErrors) {
        List<Type> inferredArgs, explicitArgs;
        if (oldTree.def != null) {
            inferredArgs = newTree.def.implementing.nonEmpty()
                              ? newTree.def.implementing.get(0).type.getTypeArguments()
                              : newTree.def.extending.type.getTypeArguments();
            explicitArgs = oldTree.def.implementing.nonEmpty()
                              ? oldTree.def.implementing.get(0).type.getTypeArguments()
                              : oldTree.def.extending.type.getTypeArguments();
        } else {
            inferredArgs = newTree.type.getTypeArguments();
            explicitArgs = oldTree.type.getTypeArguments();
        }
        for (Type t : inferredArgs) {
            if (!types.isSameType(t, explicitArgs.head)) {
                return;
            }
            explicitArgs = explicitArgs.tail;
        }
        //exact match
        log.warning(oldTree.clazz, "diamond.redundant.args");
    }
}
 
Example #2
Source File: Check.java    From openjdk-8-source with GNU General Public License v2.0 6 votes vote down vote up
private void checkSymbol(DiagnosticPosition pos, Symbol sym) {
    if (sym != null && sym.kind == TYP) {
        Env<AttrContext> classEnv = enter.getEnv((TypeSymbol)sym);
        if (classEnv != null) {
            DiagnosticSource prevSource = log.currentSource();
            try {
                log.useSource(classEnv.toplevel.sourcefile);
                scan(classEnv.tree);
            }
            finally {
                log.useSource(prevSource.getFile());
            }
        } else if (sym.kind == TYP) {
            checkClass(pos, sym, List.<JCTree>nil());
        }
    } else {
        //not completed yet
        partialCheck = true;
    }
}
 
Example #3
Source File: JavacParser.java    From openjdk-jdk8u-backup with GNU General Public License v2.0 6 votes vote down vote up
protected JCVariableDecl formalParameter(boolean lambdaParameter) {
    JCModifiers mods = optFinal(Flags.PARAMETER);
    // need to distinguish between vararg annos and array annos
    // look at typeAnnotationsPushedBack comment
    this.permitTypeAnnotationsPushBack = true;
    JCExpression type = parseType();
    this.permitTypeAnnotationsPushBack = false;

    if (token.kind == ELLIPSIS) {
        List<JCAnnotation> varargsAnnos = typeAnnotationsPushedBack;
        typeAnnotationsPushedBack = List.nil();
        checkVarargs();
        mods.flags |= Flags.VARARGS;
        // insert var arg type annotations
        type = insertAnnotationsToMostInner(type, varargsAnnos, true);
        nextToken();
    } else {
        // if not a var arg, then typeAnnotationsPushedBack should be null
        if (typeAnnotationsPushedBack.nonEmpty()) {
            reportSyntaxError(typeAnnotationsPushedBack.head.pos,
                    "illegal.start.of.type");
        }
        typeAnnotationsPushedBack = List.nil();
    }
    return variableDeclaratorId(mods, type, lambdaParameter);
}
 
Example #4
Source File: Check.java    From TencentKona-8 with GNU General Public License v2.0 6 votes vote down vote up
/** Check that all methods which implement some
 *  method in `ic' conform to the method they implement.
 */
void checkImplementations(JCTree tree, ClassSymbol origin, ClassSymbol ic) {
    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);
                    }
                }
            }
        }
    }
}
 
Example #5
Source File: Check.java    From lua-for-android with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
/** Check that all methods which implement some
 *  method in `ic' conform to the method they implement.
 */
void checkImplementations(JCTree tree, ClassSymbol origin, ClassSymbol ic) {
    for (List<Type> l = types.closure(ic.type); l.nonEmpty(); l = l.tail) {
        ClassSymbol lc = (ClassSymbol)l.head.tsym;
        if ((lc.flags() & ABSTRACT) != 0) {
            for (Symbol sym : lc.members().getSymbols(NON_RECURSIVE)) {
                if (sym.kind == MTH &&
                    (sym.flags() & (STATIC|ABSTRACT)) == ABSTRACT) {
                    MethodSymbol absmeth = (MethodSymbol)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);
                    }
                }
            }
        }
    }
}
 
Example #6
Source File: ExecutableMemberDocImpl.java    From openjdk-jdk8u with GNU General Public License v2.0 6 votes vote down vote up
private String makeSignature(boolean full) {
    StringBuilder result = new StringBuilder();
    result.append("(");
    for (List<Type> types = sym.type.getParameterTypes(); types.nonEmpty(); ) {
        Type t = types.head;
        result.append(TypeMaker.getTypeString(env, t, full));
        types = types.tail;
        if (types.nonEmpty()) {
            result.append(", ");
        }
    }
    if (isVarArgs()) {
        int len = result.length();
        result.replace(len - 2, len, "...");
    }
    result.append(")");
    return result.toString();
}
 
Example #7
Source File: PostFlowAnalysis.java    From netbeans with Apache License 2.0 6 votes vote down vote up
private void checkThis(DiagnosticPosition pos, TypeSymbol c) {
    if (checkThis && currentClass != c) {
        List<Pair<TypeSymbol, Symbol>> ots = outerThisStack;
        if (ots.isEmpty()) {
            log.error(pos, new Error("compiler", "no.encl.instance.of.type.in.scope", c)); //NOI18N
            return;
        }
        Pair<TypeSymbol, Symbol> ot = ots.head;
        TypeSymbol otc = ot.fst;
        while (otc != c) {
            do {
                ots = ots.tail;
                if (ots.isEmpty()) {
                    log.error(pos, new Error("compiler", "no.encl.instance.of.type.in.scope", c)); //NOI18N
                    return;
                }
                ot = ots.head;
            } while (ot.snd != otc);
            if (otc.owner.kind != Kinds.Kind.PCK && !otc.hasOuterInstance()) {
                log.error(pos, new Error("compiler", "cant.ref.before.ctor.called", c)); //NOI18N
                return;
            }
            otc = ot.fst;
        }
    }
}
 
Example #8
Source File: ExtensionTransformer.java    From manifold with Apache License 2.0 6 votes vote down vote up
@Override
public void visitLambda( JCTree.JCLambda tree )
{
  super.visitLambda( tree );

  if( _tp.isGenerate() && !shouldProcessForGeneration() )
  {
    // Don't process tree during GENERATE, unless the tree was generated e.g., a bridge method
    return;
  }

  tree.type = eraseStructureType( tree.type );
  ArrayList<Type> types = new ArrayList<>();
  for( Type target: IDynamicJdk.instance().getTargets( tree ) )
  {
    types.add( eraseStructureType( target ) );
  }
  IDynamicJdk.instance().setTargets( tree, List.from( types ) );
}
 
Example #9
Source File: HandleTable.java    From sqlitemagic with Apache License 2.0 6 votes vote down vote up
private void generateBulkMethod(JavacTreeMaker maker, JavacNode tableElement,
                                Set<String> allStaticMethodNames, String methodName,
                                String callClassName, String tableClassName,
                                CollectionType collectionType) {
  final String invokeKey = getCreateInvokeKey(callClassName, tableClassName);
  if (!allStaticMethodNames.contains(methodName)) {
    final JCTree.JCAnnotation invokesAnnotation = maker.Annotation(chainDotsString(tableElement, Invokes.class.getCanonicalName()),
        List.<JCTree.JCExpression>of(maker.Literal(invokeKey)));
    final JCTree.JCModifiers mods = maker.Modifiers(PUBLIC_STATIC, List.of(invokesAnnotation));
    final Name name = tableElement.toName(methodName);
    final JCTree.JCExpression returnType = getMagicMethodReturnType(tableElement, callClassName, tableClassName);
    final JCTree.JCExpression tableClassType = chainDotsString(tableElement, tableElement.getPackageDeclaration() + "." + tableClassName);
    final JCTree.JCExpression paramType = maker.TypeApply(collectionType.genericType(tableElement), List.of(tableClassType));
    long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, tableElement.getContext());
    final JCTree.JCVariableDecl param = maker.VarDef(maker.Modifiers(flags), tableElement.toName("o"), paramType, null);
    final JCTree.JCBlock body = defaultMagicMethodBody(maker, tableElement);
    final JCTree.JCMethodDecl method = maker.MethodDef(mods, name, returnType,
        List.<JCTree.JCTypeParameter>nil(),
        List.of(param),
        List.<JCTree.JCExpression>nil(),
        body,
        null);
    injectMethod(tableElement, recursiveSetGeneratedBy(method, tableElement.get(), tableElement.getContext()));
  }
}
 
Example #10
Source File: TransTypes.java    From TencentKona-8 with GNU General Public License v2.0 6 votes vote down vote up
private List<VarSymbol> createBridgeParams(MethodSymbol impl, MethodSymbol bridge,
        Type bridgeType) {
    List<VarSymbol> bridgeParams = null;
    if (impl.params != null) {
        bridgeParams = List.nil();
        List<VarSymbol> implParams = impl.params;
        Type.MethodType mType = (Type.MethodType)bridgeType;
        List<Type> argTypes = mType.argtypes;
        while (implParams.nonEmpty() && argTypes.nonEmpty()) {
            VarSymbol param = new VarSymbol(implParams.head.flags() | SYNTHETIC | PARAMETER,
                    implParams.head.name, argTypes.head, bridge);
            param.setAttributes(implParams.head);
            bridgeParams = bridgeParams.append(param);
            implParams = implParams.tail;
            argTypes = argTypes.tail;
        }
    }
    return bridgeParams;
}
 
Example #11
Source File: TransTypes.java    From javaide with GNU General Public License v3.0 6 votes vote down vote up
private void addOverrideBridges(DiagnosticPosition pos,
                                MethodSymbol impl,
                                MethodSymbol member,
                                ClassSymbol c,
                                ListBuffer<JCTree> bridges) {
    Type implErasure = impl.erasure(types);
    long flags = (impl.flags() & AccessFlags) | SYNTHETIC | BRIDGE | OVERRIDE_BRIDGE;
    member = new MethodSymbol(flags, member.name, member.type, c);
    JCMethodDecl md = make.MethodDef(member, null);
    JCExpression receiver = make.Super(types.supertype(c.type).tsym.erasure(types), c);
    Type calltype = erasure(impl.type.getReturnType());
    JCExpression call =
        make.Apply(null,
                   make.Select(receiver, impl).setType(calltype),
                   translateArgs(make.Idents(md.params),
                                 implErasure.getParameterTypes(), null))
        .setType(calltype);
    JCStatement stat = (member.getReturnType().tag == VOID)
        ? make.Exec(call)
        : make.Return(coerce(call, member.erasure(types).getReturnType()));
    md.body = make.Block(0, List.of(stat));
    c.members().enter(member);
    bridges.append(md);
}
 
Example #12
Source File: DocletInvoker.java    From hottub with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Let doclet check that all options are OK. Returning true means
 * options are OK.  If method does not exist, assume true.
 */
public boolean validOptions(List<String[]> optlist) {
    Object retVal;
    String options[][] = optlist.toArray(new String[optlist.length()][]);
    String methodName = "validOptions";
    DocErrorReporter reporter = messager;
    Class<?>[] paramTypes = { String[][].class, DocErrorReporter.class };
    Object[] params = { options, reporter };
    try {
        retVal = invoke(methodName, Boolean.TRUE, paramTypes, params);
    } catch (DocletInvokeException exc) {
        return false;
    }
    if (retVal instanceof Boolean) {
        return ((Boolean)retVal).booleanValue();
    } else {
        messager.error(Messager.NOPOS, "main.must_return_boolean",
                       docletClassName, methodName);
        return false;
    }
}
 
Example #13
Source File: JavacProcessingEnvironment.java    From openjdk-jdk8u-backup with GNU General Public License v2.0 6 votes vote down vote up
/** Create a round (common code). */
private Round(Context context, int number, int priorErrors, int priorWarnings,
        Log.DeferredDiagnosticHandler deferredDiagnosticHandler) {
    this.context = context;
    this.number = number;

    compiler = JavaCompiler.instance(context);
    log = Log.instance(context);
    log.nerrors = priorErrors;
    log.nwarnings = priorWarnings;
    if (number == 1) {
        Assert.checkNonNull(deferredDiagnosticHandler);
        this.deferredDiagnosticHandler = deferredDiagnosticHandler;
    } else {
        this.deferredDiagnosticHandler = new Log.DeferredDiagnosticHandler(log);
    }

    // the following is for the benefit of JavacProcessingEnvironment.getContext()
    JavacProcessingEnvironment.this.context = context;

    // the following will be populated as needed
    topLevelClasses  = List.nil();
    packageInfoFiles = List.nil();
}
 
Example #14
Source File: Types.java    From javaide with GNU General Public License v3.0 5 votes vote down vote up
@Override
public List<Type> visitTypeVar(TypeVar t, Void ignored) {
    if (t.bound.isCompound())
        return interfaces(t.bound);

    if (t.bound.isInterface())
        return List.of(t.bound);

    return List.nil();
}
 
Example #15
Source File: ClassWriter.java    From lua-for-android with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
void writeFields(Scope s) {
    // process them in reverse sibling order;
    // i.e., process them in declaration order.
    List<VarSymbol> vars = List.nil();
    for (Symbol sym : s.getSymbols(NON_RECURSIVE)) {
        if (sym.kind == VAR) vars = vars.prepend((VarSymbol)sym);
    }
    while (vars.nonEmpty()) {
        writeField(vars.head);
        vars = vars.tail;
    }
}
 
Example #16
Source File: Types.java    From java-n-IDE-for-Android with Apache License 2.0 5 votes vote down vote up
public TypeVar substBound(TypeVar t, List<Type> from, List<Type> to) {
    Type bound1 = subst(t.bound, from, to);
    if (bound1 == t.bound)
        return t;
    else {
        // create new type variable without bounds
        TypeVar tv = new TypeVar(t.tsym, null, syms.botType);
        // the new bound should use the new type variable in place
        // of the old
        tv.bound = subst(bound1, List.<Type>of(t), List.<Type>of(tv));
        return tv;
    }
}
 
Example #17
Source File: TList.java    From openjdk-8 with GNU General Public License v2.0 5 votes vote down vote up
void test_listIterator() {
    System.err.println("test listIterator()");
    for (Map.Entry<java.util.List<String>,List<String>> e: examples.entrySet()) {
        java.util.List<String> ref = e.getKey();
        List<String> l = e.getValue();
        if (!equal(l.listIterator(), ref.listIterator()))
            throw new AssertionError();
    }
}
 
Example #18
Source File: JavacParser.java    From openjdk-jdk8u-backup with GNU General Public License v2.0 5 votes vote down vote up
public JCExpression parseType(List<JCAnnotation> annotations) {
    JCExpression result = unannotatedType();

    if (annotations.nonEmpty()) {
        result = insertAnnotationsToMostInner(result, annotations, false);
    }

    return result;
}
 
Example #19
Source File: Tokens.java    From jdk8u60 with GNU General Public License v2.0 5 votes vote down vote up
Token(TokenKind kind, int pos, int endPos, List<Comment> comments) {
    this.kind = kind;
    this.pos = pos;
    this.endPos = endPos;
    this.comments = comments;
    checkKind();
}
 
Example #20
Source File: TreeCopier.java    From lua-for-android with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
public <T extends JCTree> List<T> copy(List<T> trees, P p) {
    if (trees == null)
        return null;
    ListBuffer<T> lb = new ListBuffer<>();
    for (T tree: trees)
        lb.append(copy(tree, p));
    return lb.toList();
}
 
Example #21
Source File: TypeAnnotations.java    From openjdk-jdk9 with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Determine whether an annotation is a declaration annotation,
 * a type annotation, or both.
 */
public AnnotationType annotationTargetType(Attribute.Compound a, Symbol s) {
    List<Attribute> targets = annotationTargets(a.type.tsym);
    return (targets == null) ?
            AnnotationType.DECLARATION :
            targets.stream()
                    .map(attr -> targetToAnnotationType(attr, s))
                    .reduce(AnnotationType.NONE, this::combineAnnotationType);
}
 
Example #22
Source File: JavacProcessingEnvironment.java    From openjdk-8 with GNU General Public License v2.0 5 votes vote down vote up
/** Create a new round. */
private Round(Round prev,
        Set<JavaFileObject> newSourceFiles, Map<String,JavaFileObject> newClassFiles) {
    this(prev.nextContext(),
            prev.number+1,
            prev.compiler.log.nerrors,
            prev.compiler.log.nwarnings,
            null);
    this.genClassFiles = prev.genClassFiles;

    List<JCCompilationUnit> parsedFiles = compiler.parseFiles(newSourceFiles);
    roots = cleanTrees(prev.roots).appendList(parsedFiles);

    // Check for errors after parsing
    if (unrecoverableError())
        return;

    enterClassFiles(genClassFiles);
    List<ClassSymbol> newClasses = enterClassFiles(newClassFiles);
    genClassFiles.putAll(newClassFiles);
    enterTrees(roots);

    if (unrecoverableError())
        return;

    topLevelClasses = join(
            getTopLevelClasses(parsedFiles),
            getTopLevelClassesFromClasses(newClasses));

    packageInfoFiles = join(
            getPackageInfoFiles(parsedFiles),
            getPackageInfoFilesFromClasses(newClasses));

    findAnnotationsPresent();
}
 
Example #23
Source File: StringConcat.java    From lua-for-android with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
private void appendString(JCTree tree) {
    Type t = tree.type.baseType();
    if (!t.isPrimitive() && t.tsym != syms.stringType.tsym) {
        t = syms.objectType;
    }

    Assert.checkNull(t.constValue());
    Symbol method = sbAppends.get(t);
    if (method == null) {
        method = rs.resolveInternalMethod(tree.pos(), gen.getAttrEnv(), syms.stringBuilderType, names.append, List.of(t), null);
        sbAppends.put(t, method);
    }

    gen.getItems().makeMemberItem(method, false).invoke();
}
 
Example #24
Source File: JavacTrees.java    From hottub with GNU General Public License v2.0 5 votes vote down vote up
/** @see com.sun.tools.javadoc.ClassDocImpl */
private boolean hasParameterTypes(MethodSymbol method, List<Type> paramTypes) {
    if (paramTypes == null)
        return true;

    if (method.params().size() != paramTypes.size())
        return false;

    List<Type> methodParamTypes = types.erasureRecursive(method.asType()).getParameterTypes();

    return (Type.isErroneous(paramTypes))
        ? fuzzyMatch(paramTypes, methodParamTypes)
        : types.isSameTypes(paramTypes, methodParamTypes);
}
 
Example #25
Source File: DCTree.java    From openjdk-jdk8u with GNU General Public License v2.0 5 votes vote down vote up
public DCDocComment(Comment comment,
        List<DCTree> firstSentence, List<DCTree> body, List<DCTree> tags) {
    this.comment = comment;
    this.firstSentence = firstSentence;
    this.body = body;
    this.tags = tags;
}
 
Example #26
Source File: JavacParser.java    From openjdk-jdk8u-backup with GNU General Public License v2.0 5 votes vote down vote up
/** CatchClause     = CATCH "(" FormalParameter ")" Block
 * TODO: the "FormalParameter" is not correct, it uses the special "catchTypes" rule below.
 */
protected JCCatch catchClause() {
    int pos = token.pos;
    accept(CATCH);
    accept(LPAREN);
    JCModifiers mods = optFinal(Flags.PARAMETER);
    List<JCExpression> catchTypes = catchTypes();
    JCExpression paramType = catchTypes.size() > 1 ?
            toP(F.at(catchTypes.head.getStartPosition()).TypeUnion(catchTypes)) :
            catchTypes.head;
    JCVariableDecl formal = variableDeclaratorId(mods, paramType);
    accept(RPAREN);
    JCBlock body = block();
    return F.at(pos).Catch(formal, body);
}
 
Example #27
Source File: Check.java    From jdk8u60 with GNU General Public License v2.0 5 votes vote down vote up
@Override
public void visitClassDef(JCClassDecl tree) {
    List<JCTree> supertypes = List.nil();
    if (tree.getExtendsClause() != null) {
        supertypes = supertypes.prepend(tree.getExtendsClause());
    }
    if (tree.getImplementsClause() != null) {
        for (JCTree intf : tree.getImplementsClause()) {
            supertypes = supertypes.prepend(intf);
        }
    }
    checkClass(tree.pos(), tree.sym, supertypes);
}
 
Example #28
Source File: JavacParser.java    From javaide with GNU General Public License v3.0 5 votes vote down vote up
private JCErroneous syntaxError(int pos, List<JCTree> errs, String key, Token... args) {
    setErrorEndPos(pos);
    JCErroneous err = F.at(pos).Erroneous(errs);
    reportSyntaxError(err, key, (Object[])args);
    if (errs != null) {
        JCTree last = errs.last();
        if (last != null)
            storeEnd(last, pos);
    }
    return toP(err);
}
 
Example #29
Source File: Attr.java    From javaide with GNU General Public License v3.0 5 votes vote down vote up
public void visitForeachLoop(JCEnhancedForLoop tree) {
    Env<AttrContext> loopEnv =
        env.dup(env.tree, env.info.dup(env.info.scope.dup()));
    attribStat(tree.var, loopEnv);
    Type exprType = types.upperBound(attribExpr(tree.expr, loopEnv));
    chk.checkNonVoid(tree.pos(), exprType);
    Type elemtype = types.elemtype(exprType); // perhaps expr is an array?
    if (elemtype == null) {
        // or perhaps expr implements Iterable<T>?
        Type base = types.asSuper(exprType, syms.iterableType.tsym);
        if (base == null) {
            log.error(tree.expr.pos(),
                    "foreach.not.applicable.to.type",
                    exprType,
                    diags.fragment("type.req.array.or.iterable"));
            elemtype = types.createErrorType(exprType);
        } else {
            List<Type> iterableParams = base.allparams();
            elemtype = iterableParams.isEmpty()
                ? syms.objectType
                : types.upperBound(iterableParams.head);
        }
    }
    chk.checkType(tree.expr.pos(), elemtype, tree.var.sym.type);
    loopEnv.tree = tree; // before, we were not in loop!
    attribStat(tree.body, loopEnv);
    loopEnv.info.scope.leave();
    result = null;
}
 
Example #30
Source File: DocCommentParser.java    From lua-for-android with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
/**
 * Read a single block tag, including its content.
 * Standard tags parse their content appropriately.
 * Non-standard tags are represented by {@link UnknownBlockTag}.
 */
protected DCTree blockTag() {
    int p = bp;
    try {
        nextChar();
        if (isIdentifierStart(ch)) {
            Name name = readTagName();
            TagParser tp = tagParsers.get(name);
            if (tp == null) {
                List<DCTree> content = blockContent();
                return m.at(p).newUnknownBlockTagTree(name, content);
            } else {
                switch (tp.getKind()) {
                    case BLOCK:
                        return tp.parse(p);
                    case INLINE:
                        return erroneous("dc.bad.inline.tag", p);
                }
            }
        }
        blockContent();

        return erroneous("dc.no.tag.name", p);
    } catch (ParseException e) {
        blockContent();
        return erroneous(e.getMessage(), p);
    }
}