List of usage examples for org.objectweb.asm Opcodes TABLESWITCH
int TABLESWITCH
To view the source code for org.objectweb.asm Opcodes TABLESWITCH.
Click Source Link
From source file:com.android.tools.lint.checks.ApiDetector.java
License:Apache License
@SuppressWarnings("rawtypes") // ASM API @Override/*from w ww .ja va 2 s. c o m*/ public void checkClass(@NonNull final ClassContext context, @NonNull ClassNode classNode) { if (mApiDatabase == null) { return; } if (AOSP_BUILD && classNode.name.startsWith("android/support/")) { //$NON-NLS-1$ return; } // Requires util package (add prebuilts/tools/common/asm-tools/asm-debug-all-4.0.jar) //classNode.accept(new TraceClassVisitor(new PrintWriter(System.out))); int classMinSdk = getClassMinSdk(context, classNode); if (classMinSdk == -1) { classMinSdk = getMinSdk(context); } List methodList = classNode.methods; if (methodList.isEmpty()) { return; } boolean checkCalls = context.isEnabled(UNSUPPORTED) || context.isEnabled(INLINED); boolean checkMethods = context.isEnabled(OVERRIDE) && context.getMainProject().getBuildSdk() >= 1; String frameworkParent = null; if (checkMethods) { LintDriver driver = context.getDriver(); String owner = classNode.superName; while (owner != null) { // For virtual dispatch, walk up the inheritance chain checking // each inherited method if ((owner.startsWith("android/") //$NON-NLS-1$ && !owner.startsWith("android/support/")) //$NON-NLS-1$ || owner.startsWith("java/") //$NON-NLS-1$ || owner.startsWith("javax/")) { //$NON-NLS-1$ frameworkParent = owner; break; } owner = driver.getSuperClass(owner); } if (frameworkParent == null) { checkMethods = false; } } if (checkCalls) { // Check implements/extends if (classNode.superName != null) { String signature = classNode.superName; checkExtendsClass(context, classNode, classMinSdk, signature); } if (classNode.interfaces != null) { @SuppressWarnings("unchecked") // ASM API List<String> interfaceList = classNode.interfaces; for (String signature : interfaceList) { checkExtendsClass(context, classNode, classMinSdk, signature); } } } for (Object m : methodList) { MethodNode method = (MethodNode) m; int minSdk = getLocalMinSdk(method.invisibleAnnotations); if (minSdk == -1) { minSdk = classMinSdk; } InsnList nodes = method.instructions; if (checkMethods && Character.isJavaIdentifierStart(method.name.charAt(0))) { int buildSdk = context.getMainProject().getBuildSdk(); String name = method.name; assert frameworkParent != null; int api = mApiDatabase.getCallVersion(frameworkParent, name, method.desc); if (api > buildSdk && buildSdk != -1) { // TODO: Don't complain if it's annotated with @Override; that means // somehow the build target isn't correct. String fqcn; String owner = classNode.name; if (CONSTRUCTOR_NAME.equals(name)) { fqcn = "new " + ClassContext.getFqcn(owner); //$NON-NLS-1$ } else { fqcn = ClassContext.getFqcn(owner) + '#' + name; } String message = String.format( "This method is not overriding anything with the current build " + "target, but will in API level %1$d (current target is %2$d): %3$s", api, buildSdk, fqcn); Location location = context.getLocation(method, classNode); context.report(OVERRIDE, method, null, location, message, null); } } if (!checkCalls) { continue; } if (CHECK_DECLARATIONS) { // Check types in parameter list and types of local variables List localVariables = method.localVariables; if (localVariables != null) { for (Object v : localVariables) { LocalVariableNode var = (LocalVariableNode) v; String desc = var.desc; if (desc.charAt(0) == 'L') { // "Lpackage/Class;" => "package/Bar" String className = desc.substring(1, desc.length() - 1); int api = mApiDatabase.getClassVersion(className); if (api > minSdk) { String fqcn = ClassContext.getFqcn(className); String message = String.format( "Class requires API level %1$d (current min is %2$d): %3$s", api, minSdk, fqcn); report(context, message, var.start, method, className.substring(className.lastIndexOf('/') + 1), null, SearchHints.create(NEAREST).matchJavaSymbol()); } } } } // Check return type // The parameter types are already handled as local variables so we can skip // right to the return type. // Check types in parameter list String signature = method.desc; if (signature != null) { int args = signature.indexOf(')'); if (args != -1 && signature.charAt(args + 1) == 'L') { String type = signature.substring(args + 2, signature.length() - 1); int api = mApiDatabase.getClassVersion(type); if (api > minSdk) { String fqcn = ClassContext.getFqcn(type); String message = String.format( "Class requires API level %1$d (current min is %2$d): %3$s", api, minSdk, fqcn); AbstractInsnNode first = nodes.size() > 0 ? nodes.get(0) : null; report(context, message, first, method, method.name, null, SearchHints.create(BACKWARD).matchJavaSymbol()); } } } } for (int i = 0, n = nodes.size(); i < n; i++) { AbstractInsnNode instruction = nodes.get(i); int type = instruction.getType(); if (type == AbstractInsnNode.METHOD_INSN) { MethodInsnNode node = (MethodInsnNode) instruction; String name = node.name; String owner = node.owner; String desc = node.desc; // No need to check methods in this local class; we know they // won't be an API match if (node.getOpcode() == Opcodes.INVOKEVIRTUAL && owner.equals(classNode.name)) { owner = classNode.superName; } boolean checkingSuperClass = false; while (owner != null) { int api = mApiDatabase.getCallVersion(owner, name, desc); if (api > minSdk) { if (method.name.startsWith(SWITCH_TABLE_PREFIX)) { // We're in a compiler-generated method to generate an // array indexed by enum ordinal values to enum values. The enum // itself must be requiring a higher API number than is // currently used, but the call site for the switch statement // will also be referencing it, so no need to report these // calls. break; } if (!checkingSuperClass && node.getOpcode() == Opcodes.INVOKEVIRTUAL && methodDefinedLocally(classNode, name, desc)) { break; } String fqcn; if (CONSTRUCTOR_NAME.equals(name)) { fqcn = "new " + ClassContext.getFqcn(owner); //$NON-NLS-1$ } else { fqcn = ClassContext.getFqcn(owner) + '#' + name; } String message = String.format( "Call requires API level %1$d (current min is %2$d): %3$s", api, minSdk, fqcn); if (name.equals(ORDINAL_METHOD) && instruction.getNext() != null && instruction.getNext().getNext() != null && instruction.getNext().getOpcode() == Opcodes.IALOAD && instruction.getNext().getNext().getOpcode() == Opcodes.TABLESWITCH) { message = String.format( "Enum for switch requires API level %1$d " + "(current min is %2$d): %3$s", api, minSdk, ClassContext.getFqcn(owner)); } report(context, message, node, method, name, null, SearchHints.create(FORWARD).matchJavaSymbol()); } // For virtual dispatch, walk up the inheritance chain checking // each inherited method if (owner.startsWith("android/") //$NON-NLS-1$ || owner.startsWith("javax/")) { //$NON-NLS-1$ // The API map has already inlined all inherited methods // so no need to keep checking up the chain // -- unless it's the support library which is also in // the android/ namespace: if (owner.startsWith("android/support/")) { //$NON-NLS-1$ owner = context.getDriver().getSuperClass(owner); } else { owner = null; } } else if (owner.startsWith("java/")) { //$NON-NLS-1$ if (owner.equals(LocaleDetector.DATE_FORMAT_OWNER)) { checkSimpleDateFormat(context, method, node, minSdk); } // Already inlined; see comment above owner = null; } else if (node.getOpcode() == Opcodes.INVOKEVIRTUAL) { owner = context.getDriver().getSuperClass(owner); } else if (node.getOpcode() == Opcodes.INVOKESTATIC && api == -1) { // Inherit through static classes as well owner = context.getDriver().getSuperClass(owner); } else { owner = null; } checkingSuperClass = true; } } else if (type == AbstractInsnNode.FIELD_INSN) { FieldInsnNode node = (FieldInsnNode) instruction; String name = node.name; String owner = node.owner; int api = mApiDatabase.getFieldVersion(owner, name); if (api > minSdk) { if (method.name.startsWith(SWITCH_TABLE_PREFIX)) { checkSwitchBlock(context, classNode, node, method, name, owner, api, minSdk); continue; } String fqcn = ClassContext.getFqcn(owner) + '#' + name; if (mPendingFields != null) { mPendingFields.remove(fqcn); } String message = String.format("Field requires API level %1$d (current min is %2$d): %3$s", api, minSdk, fqcn); report(context, message, node, method, name, null, SearchHints.create(FORWARD).matchJavaSymbol()); } } else if (type == AbstractInsnNode.LDC_INSN) { LdcInsnNode node = (LdcInsnNode) instruction; if (node.cst instanceof Type) { Type t = (Type) node.cst; String className = t.getInternalName(); int api = mApiDatabase.getClassVersion(className); if (api > minSdk) { String fqcn = ClassContext.getFqcn(className); String message = String.format( "Class requires API level %1$d (current min is %2$d): %3$s", api, minSdk, fqcn); report(context, message, node, method, className.substring(className.lastIndexOf('/') + 1), null, SearchHints.create(FORWARD).matchJavaSymbol()); } } } } } }
From source file:com.codename1.tools.translator.bytecodes.SwitchInstruction.java
License:Open Source License
public SwitchInstruction(Label dflt, int[] keys, Label[] labels) { super(Opcodes.TABLESWITCH); this.dflt = dflt; this.keys = keys; this.labels = labels; for (int iter = 0; iter < keys.length; iter++) { LabelInstruction.labelIsUsed(labels[iter]); }/* ww w . ja v a2 s.co m*/ LabelInstruction.labelIsUsed(dflt); }
From source file:com.gargoylesoftware.js.nashorn.internal.ir.debug.NashornTextifier.java
License:Open Source License
@Override public void visitTableSwitchInsn(final int min, final int max, final Label dflt, final Label... labels) { final StringBuilder sb = new StringBuilder(); appendOpcode(sb, Opcodes.TABLESWITCH).append(' '); for (int i = 0; i < labels.length; ++i) { sb.append(tab3).append(min + i).append(": "); final String to = appendLabel(sb, labels[i]); graph.addEdge(currentBlock, to); sb.append('\n'); }/* w w w. j av a2 s .co m*/ sb.append(tab3).append("default: "); appendLabel(sb, dflt); sb.append('\n'); addText(sb); }
From source file:com.mebigfatguy.baremetal4j.Sourcifier.java
License:Apache License
public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) { lines.add(//from w w w . j ava 2 s.c o m "\t\tBCO = " + String.format("%05d", byteOffset) + "; // " + Printer.OPCODES[Opcodes.TABLESWITCH]); byteOffset += 1; }
From source file:com.trigersoft.jaque.expression.ExpressionMethodVisitor.java
License:Apache License
@Override public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) { throw notLambda(Opcodes.TABLESWITCH); }
From source file:de.loskutov.bco.asm.CommentedASMifierClassVisitor.java
License:Open Source License
@Override public void visitTableSwitchInsn(final int min, final int max, final Label dflt, final Label... labels) { addIndex(Opcodes.TABLESWITCH); super.visitTableSwitchInsn(min, max, dflt, labels); }
From source file:de.unisb.cs.st.javaslicer.common.classRepresentation.instructions.TableSwitchInstruction.java
License:Open Source License
public TableSwitchInstruction(final ReadMethod readMethod, final int lineNumber, final int min, @SuppressWarnings("unused") final int max, final LabelMarker defaultHandler, final LabelMarker[] handlers) { super(readMethod, Opcodes.TABLESWITCH, lineNumber); // in initialization, defaultHandler and handlers is null... //assert min + handlers.length - 1 == max; this.min = min; this.defaultHandler = defaultHandler; this.handlers = handlers; }
From source file:de.unisb.cs.st.javaslicer.common.classRepresentation.instructions.TableSwitchInstruction.java
License:Open Source License
private TableSwitchInstruction(final ReadMethod readMethod, final int min, final int lineNumber, final LabelMarker defaultHandler, final LabelMarker[] handlers, final int index) { super(readMethod, Opcodes.TABLESWITCH, lineNumber, index); this.min = min; this.defaultHandler = defaultHandler; this.handlers = handlers; }
From source file:de.unisb.cs.st.javaslicer.common.classRepresentation.instructions.TableSwitchInstruction2.java
License:Open Source License
public TableSwitchInstruction2(final ReadMethod readMethod, final int lineNumber, final int min, @SuppressWarnings("unused") final int max, final int defaultHandler, final int[] handlers) { super(readMethod, Opcodes.TABLESWITCH, lineNumber); // in initialization, defaultHandler and handlers is null... //assert min + handlers.length - 1 == max; this.min = min; this.defaultHandler = defaultHandler; this.handlers = handlers; }
From source file:de.unisb.cs.st.javaslicer.common.classRepresentation.instructions.TableSwitchInstruction2.java
License:Open Source License
public TableSwitchInstruction2(final ReadMethod readMethod, final int min, final int lineNumber, final int defaultHandler, final int[] handlers, final int index) { super(readMethod, Opcodes.TABLESWITCH, lineNumber, index); this.min = min; this.defaultHandler = defaultHandler; this.handlers = handlers; }