Search in sources :

Example 1 with HashSet

use of dyvil.collection.mutable.HashSet in project Dyvil by Dyvil.

the class MatchExpr method check.

@Override
public void check(MarkerList markers, IContext context) {
    if (this.matchedValue != null) {
        this.matchedValue.check(markers, context);
    }
    final Set<Object> values = new HashSet<>(this.caseCount);
    for (int i = 0; i < this.caseCount; i++) {
        final MatchCase matchCase = this.cases[i];
        final Pattern pattern = matchCase.pattern;
        matchCase.check(markers, context);
        for (int j = 0, subPatterns = pattern.subPatterns(); j < subPatterns; j++) {
            final Pattern subPattern = pattern.subPattern(j);
            final Object constantValue = subPattern.constantValue();
            if (constantValue != null && !values.add(constantValue)) {
                markers.add(Markers.semanticError(subPattern.getPosition(), "match.case.duplicate", constantValue));
            }
        }
    }
}
Also used : Pattern(dyvilx.tools.compiler.ast.pattern.Pattern) HashSet(dyvil.collection.mutable.HashSet)

Example 2 with HashSet

use of dyvil.collection.mutable.HashSet in project Dyvil by Dyvil.

the class CodeMethod method write.

@Override
public void write(ClassWriter writer) throws BytecodeException {
    final boolean interfaceClass = this.enclosingClass.isInterface();
    final long flags = ModifierUtil.getFlags(this);
    final String ownerClassName = this.enclosingClass.getInternalName();
    final String mangledName = this.getInternalName();
    final String descriptor = this.getDescriptor();
    final String signature = this.needsSignature() ? this.getSignature() : null;
    final String[] exceptionTypes = this.getInternalExceptions();
    MethodWriter methodWriter = new MethodWriterImpl(writer, writer.visitMethod(ModifierUtil.getJavaModifiers(flags), mangledName, descriptor, signature, exceptionTypes));
    if (!this.isStatic()) {
        methodWriter.setThisType(ownerClassName);
    }
    this.writeAnnotations(methodWriter, flags);
    this.writeParameters(methodWriter);
    final Label start = new Label();
    final Label end = new Label();
    if (this.value != null) {
        methodWriter.visitCode();
        methodWriter.visitLabel(start);
        this.value.writeExpression(methodWriter, this.type);
        methodWriter.visitLabel(end);
        methodWriter.visitEnd(this.type);
    } else if (this.hasModifier(Modifiers.STATIC | Modifiers.ABSTRACT)) {
        // no value, but no abstract flag
        methodWriter.visitCode();
        methodWriter.visitTypeInsn(Opcodes.NEW, "java/lang/AbstractMethodError");
        methodWriter.visitInsn(Opcodes.DUP);
        methodWriter.visitLdcInsn(ClassFormat.internalToPackage(ownerClassName) + '.' + mangledName + descriptor);
        methodWriter.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/AbstractMethodError", "<init>", "(Ljava/lang/String;)V", false);
        methodWriter.visitInsn(Opcodes.ATHROW);
        methodWriter.visitEnd(this.type);
    }
    if (!this.isStatic()) {
        methodWriter.visitLocalVariable("this", 'L' + ownerClassName + ';', null, start, end, 0);
    }
    this.parameters.writeLocals(methodWriter, start, end);
    if (this.overrideMethods == null) {
        return;
    }
    final int lineNumber = this.lineNumber();
    final int opcode = this.getInvokeOpcode();
    final int bridgeModifiers = Modifiers.PUBLIC | Modifiers.SYNTHETIC | Modifiers.BRIDGE | (this.isStatic() ? Modifiers.STATIC : 0);
    /*
		 * Contains entries in the format 'mangledName(paramTypes)returnType'
		 * Used to ensure unique bridge methods
		 */
    final Set<String> descriptors = new HashSet<>(1 + this.overrideMethods.size());
    descriptors.add(mangledName + descriptor);
    for (IMethod overrideMethod : this.overrideMethods) {
        final String overrideDescriptor = overrideMethod.getDescriptor();
        final String overrideMangledName = overrideMethod.getInternalName();
        final String overrideEntry = overrideMangledName + overrideDescriptor;
        // generated
        if (descriptors.contains(overrideEntry)) {
            continue;
        }
        descriptors.add(overrideEntry);
        // Generate a bridge method
        methodWriter = new MethodWriterImpl(writer, writer.visitMethod(bridgeModifiers, overrideMangledName, overrideDescriptor, null, exceptionTypes));
        methodWriter.visitCode();
        if (!this.isStatic()) {
            methodWriter.setThisType(ownerClassName);
            methodWriter.visitVarInsn(Opcodes.ALOAD, 0);
        }
        // Generate Parameters and load arguments
        this.writeBridgeParameters(methodWriter, overrideMethod);
        // Generate Type Parameters and load reified type arguments
        this.writeBridgeTypeParameters(methodWriter, overrideMethod);
        final IType overrideReturnType = overrideMethod.getType();
        methodWriter.visitLineNumber(lineNumber);
        methodWriter.visitMethodInsn(opcode, ownerClassName, mangledName, descriptor, interfaceClass);
        this.type.writeCast(methodWriter, overrideReturnType, lineNumber);
        methodWriter.visitInsn(overrideReturnType.getReturnOpcode());
        methodWriter.visitEnd();
    }
}
Also used : MethodWriterImpl(dyvilx.tools.compiler.backend.MethodWriterImpl) MethodWriter(dyvilx.tools.compiler.backend.MethodWriter) Label(dyvilx.tools.asm.Label) HashSet(dyvil.collection.mutable.HashSet) IType(dyvilx.tools.compiler.ast.type.IType)

Aggregations

HashSet (dyvil.collection.mutable.HashSet)2 Label (dyvilx.tools.asm.Label)1 Pattern (dyvilx.tools.compiler.ast.pattern.Pattern)1 IType (dyvilx.tools.compiler.ast.type.IType)1 MethodWriter (dyvilx.tools.compiler.backend.MethodWriter)1 MethodWriterImpl (dyvilx.tools.compiler.backend.MethodWriterImpl)1