List of usage examples for org.objectweb.asm Opcodes ACC_FINAL
int ACC_FINAL
To view the source code for org.objectweb.asm Opcodes ACC_FINAL.
Click Source Link
From source file:org.codehaus.groovy.tools.javac.JavaStubGenerator.java
License:Apache License
private void printField(PrintWriter out, FieldNode fieldNode, boolean isInterface) { if ((fieldNode.getModifiers() & Opcodes.ACC_PRIVATE) != 0) return;/*from w w w .j a v a 2s. com*/ printAnnotations(out, fieldNode); if (!isInterface) { printModifiers(out, fieldNode.getModifiers()); } ClassNode type = fieldNode.getType(); printType(out, type); out.print(" "); out.print(fieldNode.getName()); if (isInterface || (fieldNode.getModifiers() & Opcodes.ACC_FINAL) != 0) { out.print(" = "); Expression valueExpr = fieldNode.getInitialValueExpression(); if (valueExpr instanceof ConstantExpression) { valueExpr = Verifier.transformToPrimitiveConstantIfPossible((ConstantExpression) valueExpr); } if (valueExpr instanceof ConstantExpression && fieldNode.isStatic() && fieldNode.isFinal() && ClassHelper.isStaticConstantInitializerType(valueExpr.getType()) && valueExpr.getType().equals(fieldNode.getType())) { // GROOVY-5150 : Initialize value with a dummy constant so that Java cross compiles correctly if (ClassHelper.STRING_TYPE.equals(valueExpr.getType())) { out.print(formatString(valueExpr.getText())); } else if (ClassHelper.char_TYPE.equals(valueExpr.getType())) { out.print("'" + valueExpr.getText() + "'"); } else { ClassNode constantType = valueExpr.getType(); out.print('('); printType(out, type); out.print(") "); out.print(valueExpr.getText()); if (ClassHelper.Long_TYPE.equals(ClassHelper.getWrapper(constantType))) out.print('L'); } } else if (ClassHelper.isPrimitiveType(type)) { String val = type == ClassHelper.boolean_TYPE ? "false" : "0"; out.print("new " + ClassHelper.getWrapper(type) + "((" + type + ")" + val + ")"); } else { out.print("null"); } } out.println(";"); }
From source file:org.codehaus.groovy.tools.javac.JavaStubGenerator.java
License:Apache License
private static void printModifiers(PrintWriter out, int modifiers) { if ((modifiers & Opcodes.ACC_PUBLIC) != 0) out.print("public "); if ((modifiers & Opcodes.ACC_PROTECTED) != 0) out.print("protected "); if ((modifiers & Opcodes.ACC_PRIVATE) != 0) out.print("private "); if ((modifiers & Opcodes.ACC_STATIC) != 0) out.print("static "); if ((modifiers & Opcodes.ACC_SYNCHRONIZED) != 0) out.print("synchronized "); if ((modifiers & Opcodes.ACC_FINAL) != 0) out.print("final "); if ((modifiers & Opcodes.ACC_ABSTRACT) != 0) out.print("abstract "); }
From source file:org.codehaus.groovy.transform.LogASTTransformation.java
License:Apache License
private int lookupLogFieldModifiers(AnnotatedNode targetClass, AnnotationNode logAnnotation) { int modifiers = getVisibility(logAnnotation, targetClass, ClassNode.class, Opcodes.ACC_PRIVATE); return Opcodes.ACC_FINAL | Opcodes.ACC_TRANSIENT | Opcodes.ACC_STATIC | modifiers; }
From source file:org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.java
License:Apache License
/** * Checks whether a property exists on the receiver, or on any of the possible receiver classes (found in the * temporary type information table)/*from w w w.j a v a 2 s . c o m*/ * * @param pexp a property expression * @param readMode if true, look for property read, else for property set * @param visitor if not null, when the property node is found, visit it with the provided visitor * @return true if the property is defined in any of the possible receiver classes */ protected boolean existsProperty(final PropertyExpression pexp, final boolean readMode, final ClassCodeVisitorSupport visitor) { super.visitPropertyExpression(pexp); String propertyName = pexp.getPropertyAsString(); if (propertyName == null) return false; Expression objectExpression = pexp.getObjectExpression(); ClassNode objectExpressionType = getType(objectExpression); List<ClassNode> enclosingTypes = typeCheckingContext.getEnclosingClassNodes(); boolean staticOnlyAccess = isClassClassNodeWrappingConcreteType(objectExpressionType); if (staticOnlyAccess && "this".equals(propertyName)) { // handle "Outer.this" for any level of nesting ClassNode outer = objectExpressionType.getGenericsTypes()[0].getType(); ClassNode found = null; for (ClassNode enclosingType : enclosingTypes) { if (!enclosingType.isStaticClass() && outer.equals(enclosingType.getOuterClass())) { found = enclosingType; break; } } if (found != null) { storeType(pexp, outer); return true; } } boolean foundGetterOrSetter = false; String capName = capitalize(propertyName); Set<ClassNode> handledNodes = new HashSet<>(); List<Receiver<String>> receivers = new LinkedList<>(); addReceivers(receivers, makeOwnerList(objectExpression), pexp.isImplicitThis()); for (Receiver<String> receiver : receivers) { ClassNode testClass = receiver.getType(); if (testClass.isArray() && "length".equals(propertyName)) { storeType(pexp, int_TYPE); if (visitor != null) { PropertyNode length = new PropertyNode("length", Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, int_TYPE, testClass, null, null, null); visitor.visitProperty(length); } return true; } Queue<ClassNode> queue = new LinkedList<>(); queue.add(testClass); if (isPrimitiveType(testClass)) { queue.add(getWrapper(testClass)); } while (!queue.isEmpty()) { ClassNode current = queue.remove(); if (!handledNodes.add(current)) continue; // in case of a lookup on Class we look for instance methods on Class // as well, since in case of a static property access we have the class // itself in the list of receivers already; boolean staticOnly; if (isClassClassNodeWrappingConcreteType(current)) { staticOnly = false; } else { staticOnly = staticOnlyAccess; } FieldNode field = current.getDeclaredField(propertyName); field = allowStaticAccessToMember(field, staticOnly); // skip property/accessor checks for "x.@field" if (field != null && pexp instanceof AttributeExpression) { if (storeField(field, pexp, current, visitor, receiver.getData(), !readMode)) { pexp.removeNodeMetaData(READONLY_PROPERTY); return true; } } // skip property/accessor checks for "field", "this.field", "this.with { field }", etc. in declaring class of field if (field != null && enclosingTypes.contains(current)) { if (storeField(field, pexp, receiver.getType(), visitor, receiver.getData(), !readMode)) { pexp.removeNodeMetaData(READONLY_PROPERTY); return true; } } MethodNode getter = findGetter(current, "get" + capName, pexp.isImplicitThis()); getter = allowStaticAccessToMember(getter, staticOnly); if (getter == null) getter = findGetter(current, "is" + capName, pexp.isImplicitThis()); getter = allowStaticAccessToMember(getter, staticOnly); List<MethodNode> setters = findSetters(current, "set" + capName, false); setters = allowStaticAccessToMember(setters, staticOnly); // need to visit even if we only look for setters for compatibility if (visitor != null && getter != null) visitor.visitMethod(getter); PropertyNode property = current.getProperty(propertyName); property = allowStaticAccessToMember(property, staticOnly); // prefer explicit getter or setter over property if receiver is not 'this' if (property == null || !enclosingTypes.contains(objectExpressionType)) { if (readMode) { if (getter != null) { ClassNode returnType = inferReturnTypeGenerics(current, getter, ArgumentListExpression.EMPTY_ARGUMENTS); storeInferredTypeForPropertyExpression(pexp, returnType); storeTargetMethod(pexp, getter); String delegationData = receiver.getData(); if (delegationData != null) { pexp.putNodeMetaData(IMPLICIT_RECEIVER, delegationData); } return true; } } else { if (!setters.isEmpty()) { if (visitor != null) { if (field != null) { visitor.visitField(field); } else { for (MethodNode setter : setters) { ClassNode setterType = setter.getParameters()[0].getOriginType(); FieldNode virtual = new FieldNode(propertyName, 0, setterType, current, EmptyExpression.INSTANCE); visitor.visitField(virtual); } } } SetterInfo info = new SetterInfo(current, "set" + capName, setters); BinaryExpression enclosingBinaryExpression = typeCheckingContext .getEnclosingBinaryExpression(); if (enclosingBinaryExpression != null) { putSetterInfo(enclosingBinaryExpression.getLeftExpression(), info); } String delegationData = receiver.getData(); if (delegationData != null) { pexp.putNodeMetaData(IMPLICIT_RECEIVER, delegationData); } pexp.removeNodeMetaData(READONLY_PROPERTY); return true; } else if (property == null) { if (field != null && hasAccessToField(typeCheckingContext.getEnclosingClassNode(), field)) { pexp.removeNodeMetaData(READONLY_PROPERTY); } else if (getter != null) { pexp.putNodeMetaData(READONLY_PROPERTY, Boolean.TRUE); } } } } foundGetterOrSetter = (foundGetterOrSetter || !setters.isEmpty() || getter != null); if (property != null && storeProperty(property, pexp, current, visitor, receiver.getData())) return true; if (field != null && storeField(field, pexp, current, visitor, receiver.getData(), !readMode)) return true; // check the super types if (current.getSuperClass() != null) { queue.add(current.getUnresolvedSuperClass()); } for (ClassNode face : current.getAllInterfaces()) { queue.add(GenericsUtils.parameterizeType(current, face)); } } // GROOVY-5568: the property may be defined by DGM List<ClassNode> dgmReceivers = new ArrayList<>(2); dgmReceivers.add(testClass); if (isPrimitiveType(testClass)) dgmReceivers.add(getWrapper(testClass)); for (ClassNode dgmReceiver : dgmReceivers) { List<MethodNode> methods = findDGMMethodsByNameAndArguments(getTransformLoader(), dgmReceiver, "get" + capName, ClassNode.EMPTY_ARRAY); for (MethodNode method : findDGMMethodsByNameAndArguments(getTransformLoader(), dgmReceiver, "is" + capName, ClassNode.EMPTY_ARRAY)) { if (Boolean_TYPE.equals(getWrapper(method.getReturnType()))) methods.add(method); } if (!methods.isEmpty()) { List<MethodNode> bestMethods = chooseBestMethod(dgmReceiver, methods, ClassNode.EMPTY_ARRAY); if (bestMethods.size() == 1) { MethodNode getter = bestMethods.get(0); if (visitor != null) { visitor.visitMethod(getter); } ClassNode returnType = inferReturnTypeGenerics(dgmReceiver, getter, ArgumentListExpression.EMPTY_ARGUMENTS); storeInferredTypeForPropertyExpression(pexp, returnType); if (readMode) storeTargetMethod(pexp, getter); return true; } } } // GROOVY-7996: check if receiver implements get(String)/set(String,Object) or propertyMissing(String) if (!testClass.isArray() && !isPrimitiveType(getUnwrapper(testClass)) && pexp.isImplicitThis() && typeCheckingContext.getEnclosingClosure() != null) { MethodNode mopMethod; if (readMode) { mopMethod = testClass.getMethod("get", new Parameter[] { new Parameter(STRING_TYPE, "name") }); } else { mopMethod = testClass.getMethod("set", new Parameter[] { new Parameter(STRING_TYPE, "name"), new Parameter(OBJECT_TYPE, "value") }); } if (mopMethod == null) mopMethod = testClass.getMethod("propertyMissing", new Parameter[] { new Parameter(STRING_TYPE, "propertyName") }); if (mopMethod != null) { pexp.putNodeMetaData(DYNAMIC_RESOLUTION, Boolean.TRUE); pexp.removeNodeMetaData(DECLARATION_INFERRED_TYPE); pexp.removeNodeMetaData(INFERRED_TYPE); return true; } } } for (Receiver<String> receiver : receivers) { ClassNode testClass = receiver.getType(); ClassNode propertyType = getTypeForMapPropertyExpression(testClass, objectExpressionType, pexp); if (propertyType == null) propertyType = getTypeForListPropertyExpression(testClass, objectExpressionType, pexp); if (propertyType == null) propertyType = getTypeForSpreadExpression(testClass, objectExpressionType, pexp); if (propertyType == null) continue; if (visitor != null) { // TODO: type inference on maps and lists, if possible PropertyNode node = new PropertyNode(propertyName, Opcodes.ACC_PUBLIC, propertyType, receiver.getType(), null, null, null); node.setDeclaringClass(receiver.getType()); visitor.visitProperty(node); } storeType(pexp, propertyType); String delegationData = receiver.getData(); if (delegationData != null) pexp.putNodeMetaData(IMPLICIT_RECEIVER, delegationData); return true; } return foundGetterOrSetter; }
From source file:org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.java
License:Apache License
protected boolean checkCast(final ClassNode targetType, final Expression source) { boolean sourceIsNull = isNullConstant(source); ClassNode expressionType = getType(source); if (targetType.isArray() && expressionType.isArray()) { return checkCast(targetType.getComponentType(), varX("foo", expressionType.getComponentType())); } else if (targetType.equals(char_TYPE) && expressionType == STRING_TYPE && source instanceof ConstantExpression && source.getText().length() == 1) { // ex: (char) 'c' } else if (targetType.equals(Character_TYPE) && (expressionType == STRING_TYPE || sourceIsNull) && (sourceIsNull || source instanceof ConstantExpression && source.getText().length() == 1)) { // ex : (Character) 'c' } else if (isNumberCategory(getWrapper(targetType)) && (isNumberCategory(getWrapper(expressionType)) || char_TYPE == expressionType)) { // ex: short s = (short) 0 } else if (sourceIsNull && !isPrimitiveType(targetType)) { // ex: (Date)null } else if (char_TYPE == targetType && isPrimitiveType(expressionType) && isNumberType(expressionType)) { // char c = (char) ... } else if (sourceIsNull && isPrimitiveType(targetType) && !boolean_TYPE.equals(targetType)) { return false; } else if ((expressionType.getModifiers() & Opcodes.ACC_FINAL) == 0 && targetType.isInterface()) { return true; } else if ((targetType.getModifiers() & Opcodes.ACC_FINAL) == 0 && expressionType.isInterface()) { return true; } else if (!isAssignableTo(targetType, expressionType) && !implementsInterfaceOrIsSubclassOf(expressionType, targetType)) { return false; }//from w w w . j a v a2 s . co m return true; }
From source file:org.codehaus.groovy.transform.trait.TraitComposer.java
License:Apache License
private static void applyTrait(final ClassNode trait, final ClassNode cNode, final TraitHelpersTuple helpers, SourceUnit unit) {/* www . j av a 2 s. c om*/ ClassNode helperClassNode = helpers.getHelper(); ClassNode fieldHelperClassNode = helpers.getFieldHelper(); ClassNode staticFieldHelperClassNode = helpers.getStaticFieldHelper(); Map<String, ClassNode> genericsSpec = GenericsUtils.createGenericsSpec(trait, GenericsUtils.createGenericsSpec(cNode)); for (MethodNode methodNode : helperClassNode.getAllDeclaredMethods()) { String name = methodNode.getName(); Parameter[] helperMethodParams = methodNode.getParameters(); int nParams = helperMethodParams.length; if (nParams > 0 && !methodNode.isAbstract() && ((methodNode.getModifiers() & Opcodes.ACC_STATIC) != 0) && (!name.contains("$") || (methodNode.getModifiers() & Opcodes.ACC_SYNTHETIC) == 0)) { ArgumentListExpression argList = new ArgumentListExpression(); argList.addExpression(new VariableExpression("this")); Parameter[] origParams = new Parameter[nParams - 1]; Parameter[] params = new Parameter[nParams - 1]; System.arraycopy(methodNode.getParameters(), 1, params, 0, params.length); MethodNode originalMethod = trait.getMethod(name, params); Map<String, ClassNode> methodGenericsSpec = Optional.ofNullable(originalMethod) .map(m -> GenericsUtils.addMethodGenerics(m, genericsSpec)).orElse(genericsSpec); for (int i = 1; i < nParams; i += 1) { Parameter parameter = helperMethodParams[i]; ClassNode originType = parameter.getOriginType(); ClassNode fixedType = correctToGenericsSpecRecurse(methodGenericsSpec, originType); Parameter newParam = new Parameter(fixedType, parameter.getName()); List<AnnotationNode> copied = new LinkedList<>(); List<AnnotationNode> notCopied = new LinkedList<>(); GeneralUtils.copyAnnotatedNodeAnnotations(parameter, copied, notCopied); newParam.addAnnotations(copied); params[i - 1] = newParam; origParams[i - 1] = parameter; argList.addExpression(new VariableExpression(newParam)); } createForwarderMethod(trait, cNode, methodNode, originalMethod, helperClassNode, methodGenericsSpec, helperMethodParams, origParams, params, argList, unit); } } MethodCallExpression staticInitCall = new MethodCallExpression(new ClassExpression(helperClassNode), Traits.STATIC_INIT_METHOD, new ArgumentListExpression(new ClassExpression(cNode))); MethodNode staticInitMethod = new MethodNode(Traits.STATIC_INIT_METHOD, Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC, ClassHelper.VOID_TYPE, new Parameter[] { new Parameter(ClassHelper.CLASS_Type, "clazz") }, ClassNode.EMPTY_ARRAY, EmptyStatement.INSTANCE); staticInitMethod.setDeclaringClass(helperClassNode); staticInitCall.setMethodTarget(staticInitMethod); cNode.addStaticInitializerStatements( Collections.<Statement>singletonList(new ExpressionStatement(staticInitCall)), false); if (fieldHelperClassNode != null && !cNode.declaresInterface(fieldHelperClassNode)) { // we should implement the field helper interface too cNode.addInterface(fieldHelperClassNode); // implementation of methods List<MethodNode> declaredMethods = new LinkedList<>(); for (MethodNode declaredMethod : fieldHelperClassNode.getAllDeclaredMethods()) { if (declaredMethod.getName().endsWith(Traits.DIRECT_GETTER_SUFFIX)) { declaredMethods.add(0, declaredMethod); } else { declaredMethods.add(declaredMethod); } } if (staticFieldHelperClassNode != null) { for (MethodNode declaredMethod : staticFieldHelperClassNode.getAllDeclaredMethods()) { if (declaredMethod.getName().endsWith(Traits.DIRECT_GETTER_SUFFIX)) { declaredMethods.add(0, declaredMethod); } else { declaredMethods.add(declaredMethod); } } } for (MethodNode methodNode : declaredMethods) { String fieldName = methodNode.getName(); if (fieldName.endsWith(Traits.DIRECT_GETTER_SUFFIX) || fieldName.endsWith(Traits.DIRECT_SETTER_SUFFIX)) { int suffixIdx = fieldName.lastIndexOf("$"); fieldName = fieldName.substring(0, suffixIdx); String operation = methodNode.getName().substring(suffixIdx + 1); boolean getter = "get".equals(operation); ClassNode returnType = correctToGenericsSpecRecurse(genericsSpec, methodNode.getReturnType()); int fieldMods = 0; int isStatic = 0; boolean publicField = true; FieldNode helperField = null; fieldMods = 0; isStatic = 0; // look first for field with encoded modifier information for (Integer mod : Traits.FIELD_PREFIXES) { helperField = fieldHelperClassNode.getField(String.format("$0x%04x", mod) + fieldName); if (helperField != null) { if ((mod & Opcodes.ACC_STATIC) != 0) isStatic = Opcodes.ACC_STATIC; fieldMods = fieldMods | mod; break; } } if (helperField == null) { // look for possible legacy fields (trait compiled pre 2.4.8) helperField = fieldHelperClassNode .getField(Traits.FIELD_PREFIX + Traits.PUBLIC_FIELD_PREFIX + fieldName); if (helperField == null) { publicField = false; helperField = fieldHelperClassNode .getField(Traits.FIELD_PREFIX + Traits.PRIVATE_FIELD_PREFIX + fieldName); } if (helperField == null) { publicField = true; // try to find a static one helperField = fieldHelperClassNode .getField(Traits.STATIC_FIELD_PREFIX + Traits.PUBLIC_FIELD_PREFIX + fieldName); if (helperField == null) { publicField = false; helperField = fieldHelperClassNode.getField( Traits.STATIC_FIELD_PREFIX + Traits.PRIVATE_FIELD_PREFIX + fieldName); } fieldMods = fieldMods | Opcodes.ACC_STATIC; isStatic = Opcodes.ACC_STATIC; } fieldMods = fieldMods | (publicField ? Opcodes.ACC_PUBLIC : Opcodes.ACC_PRIVATE); } if (getter) { // add field if (helperField != null) { List<AnnotationNode> copied = new LinkedList<>(); List<AnnotationNode> notCopied = new LinkedList<>(); GeneralUtils.copyAnnotatedNodeAnnotations(helperField, copied, notCopied); FieldNode fieldNode = cNode.addField(fieldName, fieldMods, returnType, null); fieldNode.addAnnotations(copied); // getInitialExpression above will be null if not in same source unit // so instead set within (static) initializer if (fieldNode.isFinal()) { String baseName = fieldNode.isStatic() ? Traits.STATIC_INIT_METHOD : Traits.INIT_METHOD; StaticMethodCallExpression mce = callX(helperClassNode, baseName + fieldNode.getName(), args(varX("this"))); if (helperClassNode.hasPossibleStaticMethod(mce.getMethod(), mce.getArguments())) { Statement stmt = stmt( assignX(varX(fieldNode.getName(), fieldNode.getType()), mce)); if (isStatic == 0) { cNode.addObjectInitializerStatements(stmt); } else { List<Statement> staticStatements = new ArrayList<Statement>(); staticStatements.add(stmt); cNode.addStaticInitializerStatements(staticStatements, true); } } } } } Parameter[] newParams; if (getter) { newParams = Parameter.EMPTY_ARRAY; } else { ClassNode originType = methodNode.getParameters()[0].getOriginType(); ClassNode fixedType = originType.isGenericsPlaceHolder() ? ClassHelper.OBJECT_TYPE : correctToGenericsSpecRecurse(genericsSpec, originType); newParams = new Parameter[] { new Parameter(fixedType, "val") }; } Expression fieldExpr = varX(cNode.getField(fieldName)); boolean finalSetter = !getter && (fieldMods & Opcodes.ACC_FINAL) != 0; Statement body = getter ? returnS(fieldExpr) : (finalSetter ? null : stmt(new BinaryExpression(fieldExpr, Token.newSymbol(Types.EQUAL, 0, 0), varX(newParams[0])))); // add getter/setter even though setter not strictly needed for final fields // but add empty body for setter for legacy compatibility MethodNode impl = new MethodNode(methodNode.getName(), Opcodes.ACC_PUBLIC | isStatic, returnType, newParams, ClassNode.EMPTY_ARRAY, body); AnnotationNode an = new AnnotationNode(COMPILESTATIC_CLASSNODE); impl.addAnnotation(an); cNode.addTransform(StaticCompileTransformation.class, an); cNode.addMethod(impl); } } } cNode.addObjectInitializerStatements( new ExpressionStatement(new MethodCallExpression(new ClassExpression(helperClassNode), Traits.INIT_METHOD, new ArgumentListExpression(new VariableExpression("this"))))); }
From source file:org.codehaus.jdt.groovy.internal.compiler.ast.GroovyCompilationUnitDeclaration.java
License:Open Source License
/** * Build JDT TypeDeclarations for the groovy type declarations that were parsed from the source file. *//*from w w w . j av a2s. c om*/ private void createTypeDeclarations(ModuleNode moduleNode) { List<ClassNode> moduleClassNodes = moduleNode.getClasses(); List<TypeDeclaration> typeDeclarations = new ArrayList<TypeDeclaration>(); Map<ClassNode, TypeDeclaration> fromClassNodeToDecl = new HashMap<ClassNode, TypeDeclaration>(); char[] mainName = toMainName(compilationResult.getFileName()); boolean isInner = false; List<ClassNode> classNodes = null; classNodes = moduleClassNodes; Map<ClassNode, List<TypeDeclaration>> innersToRecord = new HashMap<ClassNode, List<TypeDeclaration>>(); for (ClassNode classNode : classNodes) { if (!classNode.isPrimaryClassNode()) { continue; } GroovyTypeDeclaration typeDeclaration = new GroovyTypeDeclaration(compilationResult, classNode); typeDeclaration.annotations = transformAnnotations(classNode.getAnnotations()); // FIXASC duplicates code further down, tidy this up if (classNode instanceof InnerClassNode) { InnerClassNode innerClassNode = (InnerClassNode) classNode; ClassNode outerClass = innerClassNode.getOuterClass(); String outername = outerClass.getNameWithoutPackage(); String newInner = innerClassNode.getNameWithoutPackage().substring(outername.length() + 1); typeDeclaration.name = newInner.toCharArray(); isInner = true; } else { typeDeclaration.name = classNode.getNameWithoutPackage().toCharArray(); isInner = false; } // classNode.getInnerClasses(); // classNode. boolean isInterface = classNode.isInterface(); int mods = classNode.getModifiers(); if ((mods & Opcodes.ACC_ENUM) != 0) { // remove final mods = mods & ~Opcodes.ACC_FINAL; } // FIXASC should this modifier be set? // mods |= Opcodes.ACC_PUBLIC; // FIXASC should not do this for inner classes, just for top level types // FIXASC does this make things visible that shouldn't be? mods = mods & ~(Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED); if (!isInner) { if ((mods & Opcodes.ACC_STATIC) != 0) { mods = mods & ~(Opcodes.ACC_STATIC); } } typeDeclaration.modifiers = mods & ~(isInterface ? Opcodes.ACC_ABSTRACT : 0); if (!(classNode instanceof InnerClassNode)) { if (!CharOperation.equals(typeDeclaration.name, mainName)) { typeDeclaration.bits |= ASTNode.IsSecondaryType; } } fixupSourceLocationsForTypeDeclaration(typeDeclaration, classNode); if (classNode.getGenericsTypes() != null) { GenericsType[] genericInfo = classNode.getGenericsTypes(); // Example case here: Foo<T extends Number & I> // the type parameter is T, the 'type' is Number and the bounds for the type parameter are just the extra bound // I. typeDeclaration.typeParameters = new TypeParameter[genericInfo.length]; for (int tp = 0; tp < genericInfo.length; tp++) { TypeParameter typeParameter = new TypeParameter(); typeParameter.name = genericInfo[tp].getName().toCharArray(); ClassNode[] upperBounds = genericInfo[tp].getUpperBounds(); if (upperBounds != null) { // FIXASC (M3) Positional info for these references? typeParameter.type = createTypeReferenceForClassNode(upperBounds[0]); typeParameter.bounds = (upperBounds.length > 1 ? new TypeReference[upperBounds.length - 1] : null); for (int b = 1, max = upperBounds.length; b < max; b++) { typeParameter.bounds[b - 1] = createTypeReferenceForClassNode(upperBounds[b]); typeParameter.bounds[b - 1].bits |= ASTNode.IsSuperType; } } typeDeclaration.typeParameters[tp] = typeParameter; } } boolean isEnum = (classNode.getModifiers() & Opcodes.ACC_ENUM) != 0; configureSuperClass(typeDeclaration, classNode.getSuperClass(), isEnum); configureSuperInterfaces(typeDeclaration, classNode); typeDeclaration.methods = createMethodAndConstructorDeclarations(classNode, isEnum, compilationResult); typeDeclaration.fields = createFieldDeclarations(classNode); typeDeclaration.properties = classNode.getProperties(); if (classNode instanceof InnerClassNode) { InnerClassNode innerClassNode = (InnerClassNode) classNode; ClassNode outerClass = innerClassNode.getOuterClass(); String outername = outerClass.getNameWithoutPackage(); String newInner = innerClassNode.getNameWithoutPackage().substring(outername.length() + 1); typeDeclaration.name = newInner.toCharArray(); // Record that we need to set the parent of this inner type later List<TypeDeclaration> inners = innersToRecord.get(outerClass); if (inners == null) { inners = new ArrayList<TypeDeclaration>(); innersToRecord.put(outerClass, inners); } inners.add(typeDeclaration); } else { typeDeclarations.add(typeDeclaration); } fromClassNodeToDecl.put(classNode, typeDeclaration); } // For inner types, now attach them to their parents. This was not done earlier as sometimes the types are processed in // such an order that inners are dealt with before outers for (Map.Entry<ClassNode, List<TypeDeclaration>> innersToRecordEntry : innersToRecord.entrySet()) { TypeDeclaration outerTypeDeclaration = fromClassNodeToDecl.get(innersToRecordEntry.getKey()); // Check if there is a problem locating the parent for the inner if (outerTypeDeclaration == null) { throw new GroovyEclipseBug( "Failed to find the type declaration for " + innersToRecordEntry.getKey().getName()); } List<TypeDeclaration> newInnersList = innersToRecordEntry.getValue(); outerTypeDeclaration.memberTypes = newInnersList.toArray(new TypeDeclaration[newInnersList.size()]); } types = typeDeclarations.toArray(new TypeDeclaration[typeDeclarations.size()]); }
From source file:org.elasticsearch.painless.node.SSource.java
License:Apache License
public void write() { // Create the ClassWriter. int classFrames = ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS; int classAccess = Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER | Opcodes.ACC_FINAL; String classBase = BASE_CLASS_TYPE.getInternalName(); String className = CLASS_TYPE.getInternalName(); String classInterfaces[] = reserved.usesScore() ? new String[] { WriterConstants.NEEDS_SCORE_TYPE.getInternalName() } : null;/*from w w w .j a v a2 s . c om*/ ClassWriter writer = new ClassWriter(classFrames); ClassVisitor visitor = writer; // if picky is enabled, turn on some checks. instead of VerifyError at the end, you get a helpful stacktrace. if (settings.isPicky()) { visitor = new SimpleChecksAdapter(visitor); } if (debugStream != null) { visitor = new TraceClassVisitor(visitor, debugStream, null); } visitor.visit(WriterConstants.CLASS_VERSION, classAccess, className, null, classBase, classInterfaces); visitor.visitSource(Location.computeSourceName(name, source), null); // Write the constructor: MethodWriter constructor = new MethodWriter(Opcodes.ACC_PUBLIC, CONSTRUCTOR, visitor, globals.getStatements(), settings); constructor.visitCode(); constructor.loadThis(); constructor.loadArgs(); constructor.invokeConstructor(org.objectweb.asm.Type.getType(Executable.class), CONSTRUCTOR); constructor.returnValue(); constructor.endMethod(); // Write the execute method: MethodWriter execute = new MethodWriter(Opcodes.ACC_PUBLIC, EXECUTE, visitor, globals.getStatements(), settings); execute.visitCode(); write(execute, globals); execute.endMethod(); // Write all functions: for (SFunction function : functions) { function.write(visitor, settings, globals); } // Write all synthetic functions. Note that this process may add more :) while (!globals.getSyntheticMethods().isEmpty()) { List<SFunction> current = new ArrayList<>(globals.getSyntheticMethods().values()); globals.getSyntheticMethods().clear(); for (SFunction function : current) { function.write(visitor, settings, globals); } } // Write the constants if (false == globals.getConstantInitializers().isEmpty()) { Collection<Constant> inits = globals.getConstantInitializers().values(); // Fields for (Constant constant : inits) { visitor.visitField(Opcodes.ACC_FINAL | Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC, constant.name, constant.type.getDescriptor(), null, null).visitEnd(); } // Initialize the constants in a static initializer final MethodWriter clinit = new MethodWriter(Opcodes.ACC_STATIC, WriterConstants.CLINIT, visitor, globals.getStatements(), settings); clinit.visitCode(); for (Constant constant : inits) { constant.initializer.accept(clinit); clinit.putStatic(CLASS_TYPE, constant.name, constant.type); } clinit.returnValue(); clinit.endMethod(); } // End writing the class and store the generated bytes. visitor.visitEnd(); bytes = writer.toByteArray(); }
From source file:org.elasticsearch.painless.PainlessScriptEngine.java
License:Apache License
/** * Generates a stateful factory class that will return script instances. Acts as a middle man between * the {@link ScriptContext#factoryClazz} and the {@link ScriptContext#instanceClazz} when used so that * the stateless factory can be used for caching and the stateful factory can act as a cache for new * script instances. Uses the newInstance method from a {@link ScriptContext#statefulFactoryClazz} to * define the factory method to create new instances of the {@link ScriptContext#instanceClazz}. * @param loader The {@link ClassLoader} that is used to define the factory class and script class. * @param context The {@link ScriptContext}'s semantics are used to define the factory class. * @param <T> The factory class./*from w w w . j ava 2 s.c o m*/ * @return A factory class that will return script instances. */ private <T> Type generateStatefulFactory(Loader loader, ScriptContext<T> context, MainMethodReserved reserved) { int classFrames = ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS; int classAccess = Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER | Opcodes.ACC_FINAL; String interfaceBase = Type.getType(context.statefulFactoryClazz).getInternalName(); String className = interfaceBase + "$StatefulFactory"; String classInterfaces[] = new String[] { interfaceBase }; ClassWriter writer = new ClassWriter(classFrames); writer.visit(WriterConstants.CLASS_VERSION, classAccess, className, null, OBJECT_TYPE.getInternalName(), classInterfaces); Method newFactory = null; for (Method method : context.factoryClazz.getMethods()) { if ("newFactory".equals(method.getName())) { newFactory = method; break; } } for (int count = 0; count < newFactory.getParameterTypes().length; ++count) { writer.visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, "$arg" + count, Type.getType(newFactory.getParameterTypes()[count]).getDescriptor(), null, null).visitEnd(); } org.objectweb.asm.commons.Method base = new org.objectweb.asm.commons.Method("<init>", MethodType.methodType(void.class).toMethodDescriptorString()); org.objectweb.asm.commons.Method init = new org.objectweb.asm.commons.Method("<init>", MethodType.methodType(void.class, newFactory.getParameterTypes()).toMethodDescriptorString()); GeneratorAdapter constructor = new GeneratorAdapter(Opcodes.ASM5, init, writer.visitMethod(Opcodes.ACC_PUBLIC, init.getName(), init.getDescriptor(), null, null)); constructor.visitCode(); constructor.loadThis(); constructor.invokeConstructor(OBJECT_TYPE, base); for (int count = 0; count < newFactory.getParameterTypes().length; ++count) { constructor.loadThis(); constructor.loadArg(count); constructor.putField(Type.getType(className), "$arg" + count, Type.getType(newFactory.getParameterTypes()[count])); } constructor.returnValue(); constructor.endMethod(); Method newInstance = null; for (Method method : context.statefulFactoryClazz.getMethods()) { if ("newInstance".equals(method.getName())) { newInstance = method; break; } } org.objectweb.asm.commons.Method instance = new org.objectweb.asm.commons.Method(newInstance.getName(), MethodType.methodType(newInstance.getReturnType(), newInstance.getParameterTypes()) .toMethodDescriptorString()); List<Class<?>> parameters = new ArrayList<>(Arrays.asList(newFactory.getParameterTypes())); parameters.addAll(Arrays.asList(newInstance.getParameterTypes())); org.objectweb.asm.commons.Method constru = new org.objectweb.asm.commons.Method("<init>", MethodType .methodType(void.class, parameters.toArray(new Class<?>[] {})).toMethodDescriptorString()); GeneratorAdapter adapter = new GeneratorAdapter(Opcodes.ASM5, instance, writer.visitMethod( Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, instance.getName(), instance.getDescriptor(), null, null)); adapter.visitCode(); adapter.newInstance(WriterConstants.CLASS_TYPE); adapter.dup(); for (int count = 0; count < newFactory.getParameterTypes().length; ++count) { adapter.loadThis(); adapter.getField(Type.getType(className), "$arg" + count, Type.getType(newFactory.getParameterTypes()[count])); } adapter.loadArgs(); adapter.invokeConstructor(WriterConstants.CLASS_TYPE, constru); adapter.returnValue(); adapter.endMethod(); writeNeedsMethods(context.statefulFactoryClazz, writer, reserved); writer.visitEnd(); loader.defineFactory(className.replace('/', '.'), writer.toByteArray()); return Type.getType(className); }
From source file:org.elasticsearch.painless.PainlessScriptEngine.java
License:Apache License
/** * Generates a factory class that will return script instances or stateful factories. * Uses the newInstance method from a {@link ScriptContext#factoryClazz} to define the factory method * to create new instances of the {@link ScriptContext#instanceClazz} or uses the newFactory method * to create new factories of the {@link ScriptContext#statefulFactoryClazz}. * @param loader The {@link ClassLoader} that is used to define the factory class and script class. * @param context The {@link ScriptContext}'s semantics are used to define the factory class. * @param classType The type to be instaniated in the newFactory or newInstance method. Depends * on whether a {@link ScriptContext#statefulFactoryClazz} is specified. * @param <T> The factory class.//from ww w .j a v a 2 s .c o m * @return A factory class that will return script instances. */ private <T> T generateFactory(Loader loader, ScriptContext<T> context, MainMethodReserved reserved, Type classType) { int classFrames = ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS; int classAccess = Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER | Opcodes.ACC_FINAL; String interfaceBase = Type.getType(context.factoryClazz).getInternalName(); String className = interfaceBase + "$Factory"; String classInterfaces[] = new String[] { interfaceBase }; ClassWriter writer = new ClassWriter(classFrames); writer.visit(WriterConstants.CLASS_VERSION, classAccess, className, null, OBJECT_TYPE.getInternalName(), classInterfaces); org.objectweb.asm.commons.Method init = new org.objectweb.asm.commons.Method("<init>", MethodType.methodType(void.class).toMethodDescriptorString()); GeneratorAdapter constructor = new GeneratorAdapter(Opcodes.ASM5, init, writer.visitMethod(Opcodes.ACC_PUBLIC, init.getName(), init.getDescriptor(), null, null)); constructor.visitCode(); constructor.loadThis(); constructor.invokeConstructor(OBJECT_TYPE, init); constructor.returnValue(); constructor.endMethod(); Method reflect = null; for (Method method : context.factoryClazz.getMethods()) { if ("newInstance".equals(method.getName())) { reflect = method; break; } else if ("newFactory".equals(method.getName())) { reflect = method; break; } } org.objectweb.asm.commons.Method instance = new org.objectweb.asm.commons.Method(reflect.getName(), MethodType.methodType(reflect.getReturnType(), reflect.getParameterTypes()) .toMethodDescriptorString()); org.objectweb.asm.commons.Method constru = new org.objectweb.asm.commons.Method("<init>", MethodType.methodType(void.class, reflect.getParameterTypes()).toMethodDescriptorString()); GeneratorAdapter adapter = new GeneratorAdapter(Opcodes.ASM5, instance, writer.visitMethod( Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, instance.getName(), instance.getDescriptor(), null, null)); adapter.visitCode(); adapter.newInstance(classType); adapter.dup(); adapter.loadArgs(); adapter.invokeConstructor(classType, constru); adapter.returnValue(); adapter.endMethod(); writeNeedsMethods(context.factoryClazz, writer, reserved); writer.visitEnd(); Class<?> factory = loader.defineFactory(className.replace('/', '.'), writer.toByteArray()); try { return context.factoryClazz.cast(factory.getConstructor().newInstance()); } catch (Exception exception) { // Catch everything to let the user know this is something caused internally. throw new IllegalStateException( "An internal error occurred attempting to define the factory class [" + className + "].", exception); } }