/** * Computes the anonymous simple name from its fully qualified type name. * * @param anonymousQualifiedName * Qualified name which contains the anonymous name. * @return Anonymous simple name. */ static String computeAnonymousName(char[] anonymousQualifiedName) { final String poolName = CharOperation.charToString(anonymousQualifiedName); return poolName.substring(poolName.lastIndexOf(CtType.INNERTTYPE_SEPARATOR) + 1); }
/** * Creates a qualified type name from a two-dimensional array. * * @param typeName * two-dimensional array which represents the qualified name expected. * @return Qualified name. */ static String createQualifiedTypeName(char[][] typeName) { StringBuilder s = new StringBuilder(); for (int i = 0; i < typeName.length - 1; i++) { s.append(CharOperation.charToString(typeName[i])).append("."); } s.append(CharOperation.charToString(typeName[typeName.length - 1])); return s.toString(); }
JDTImportBuilder(CompilationUnitDeclaration declarationUnit, Factory factory) { this.declarationUnit = declarationUnit; this.factory = factory; this.sourceUnit = declarationUnit.compilationResult.compilationUnit; this.filePath = CharOperation.charToString(sourceUnit.getFileName()); // get the CU: it has already been built during model building in JDTBasedSpoonCompiler this.spoonUnit = JDTTreeBuilder.getOrCreateCompilationUnit(declarationUnit, factory); this.imports = new HashSet<>(); }
<T> CtFieldReference<T> getVariableReference(FieldBinding fieldBinding, char[] tokens) { final CtFieldReference<T> ref = getVariableReference(fieldBinding); if (fieldBinding != null) { return ref; } ref.setSimpleName(CharOperation.charToString(tokens)); return ref; }
/** * Creates a JDTCommentBuilder that will insert all comment of the declarationUnit into the Spoon AST * @param declarationUnit the declaration unit * @param factory the Spoon AST */ JDTCommentBuilder(CompilationUnitDeclaration declarationUnit, Factory factory) { this.declarationUnit = declarationUnit; if (declarationUnit.comments == null) { return; } this.factory = factory; this.sourceUnit = declarationUnit.compilationResult.compilationUnit; this.contents = sourceUnit.getContents(); this.filePath = CharOperation.charToString(sourceUnit.getFileName()); this.spoonUnit = JDTTreeBuilder.getOrCreateCompilationUnit(declarationUnit, factory); }
@Override public boolean visit(StringLiteral stringLiteral, BlockScope scope) { context.enter(factory.Code().createLiteral(CharOperation.charToString(stringLiteral.source())), stringLiteral); return true; }
@Override public boolean visit(AnnotationMethodDeclaration annotationTypeDeclaration, ClassScope classScope) { CtAnnotationMethod<Object> ctAnnotationMethod = factory.Core().createAnnotationMethod(); ctAnnotationMethod.setSimpleName(CharOperation.charToString(annotationTypeDeclaration.selector)); context.enter(ctAnnotationMethod, annotationTypeDeclaration); return true; }
private boolean visitTypeParameter(TypeParameter typeParameter, Scope scope) { final CtTypeParameter typeParameterRef = factory.Core().createTypeParameter(); typeParameterRef.setSimpleName(CharOperation.charToString(typeParameter.name)); context.enter(typeParameterRef, typeParameter); return true; }
/** * Searches a type declared in imports. * * @param typeName * Expected type name. * @param imports * Search the type in imports. * @return qualified name of the expected type. */ static String searchType(String typeName, ImportReference[] imports) { if (typeName == null || imports == null) { return null; } for (ImportReference anImport : imports) { final String importType = CharOperation.charToString(anImport.getImportName()[anImport.getImportName().length - 1]); if (typeName.equals(importType)) { return CharOperation.toString(anImport.getImportName()); } } return null; }
@Override public boolean visit(ExtendedStringLiteral extendedStringLiteral, BlockScope scope) { context.enter(factory.Code().createLiteral(CharOperation.charToString(extendedStringLiteral.source())), extendedStringLiteral); return true; }
/** * Searches a type from an entry-point according to a simple name. * * @param type * Entry-point to search. * @param simpleName * Expected type name. * @return type binding. */ static TypeBinding searchTypeBinding(ReferenceBinding type, String simpleName) { if (simpleName == null || type == null) { return null; } if (type.memberTypes() != null) { for (ReferenceBinding memberType : type.memberTypes()) { if (simpleName.equals(CharOperation.charToString(memberType.sourceName()))) { return memberType; } } } return searchTypeBinding(type.superclass(), simpleName); }
@Override public boolean visit(LambdaExpression lambdaExpression, BlockScope blockScope) { CtLambda<?> lambda = factory.Core().createLambda(); final MethodBinding methodBinding = lambdaExpression.getMethodBinding(); if (methodBinding != null) { lambda.setSimpleName(CharOperation.charToString(methodBinding.constantPoolName())); } context.isBuildLambda = true; context.enter(lambda, lambdaExpression); return true; }
/** * Creates a type access from its single name. * * @param singleNameReference * Used to get the simple name of the type. * @return a type access. */ <T> CtTypeAccess<T> createTypeAccessNoClasspath(SingleNameReference singleNameReference) { final CtTypeReference<T> typeReference = jdtTreeBuilder.getFactory().Core().createTypeReference(); if (singleNameReference.binding == null) { typeReference.setSimpleName(CharOperation.charToString(singleNameReference.token)); } else { typeReference.setSimpleName(CharOperation.charToString(singleNameReference.binding.readableName())); } jdtTreeBuilder.getReferencesBuilder().setPackageOrDeclaringType(typeReference, jdtTreeBuilder.getReferencesBuilder().getDeclaringReferenceFromImports(singleNameReference.token)); return jdtTreeBuilder.getFactory().Code().createTypeAccess(typeReference); }
/** * Creates a catch variable from a type reference. * * @param typeReference * Corresponds to the exception type declared in the catch. * @return a catch variable. */ CtCatchVariable<Throwable> createCatchVariable(TypeReference typeReference) { final Argument jdtCatch = (Argument) jdtTreeBuilder.getContextBuilder().stack.peekFirst().node; final Set<CtExtendedModifier> modifiers = getModifiers(jdtCatch.modifiers, false, false); CtCatchVariable<Throwable> result = jdtTreeBuilder.getFactory().Core().createCatchVariable(); result.<CtCatchVariable>setSimpleName(CharOperation.charToString(jdtCatch.name)).setExtendedModifiers(modifiers); if (typeReference instanceof UnionTypeReference) { //do not set type of variable yet. It will be initialized later by visit of multiple types. Each call then ADDs one type return result; } else { CtTypeReference ctTypeReference = jdtTreeBuilder.getReferencesBuilder().<Throwable>getTypeReference(typeReference.resolvedType); return result.<CtCatchVariable>setType(ctTypeReference); } }
@Override public boolean visit(SingleNameReference singleNameReference, BlockScope scope) { if (singleNameReference.binding instanceof FieldBinding) { context.enter(helper.createFieldAccess(singleNameReference), singleNameReference); } else if (singleNameReference.binding instanceof VariableBinding) { context.enter(helper.createVariableAccess(singleNameReference), singleNameReference); } else if (singleNameReference.binding instanceof TypeBinding) { context.enter(factory.Code().createTypeAccessWithoutCloningReference(references.getTypeReference((TypeBinding) singleNameReference.binding)), singleNameReference); } else if (singleNameReference.binding instanceof ProblemBinding) { if (context.stack.peek().element instanceof CtInvocation && Character.isUpperCase(CharOperation.charToString(singleNameReference.token).charAt(0))) { context.enter(helper.createTypeAccessNoClasspath(singleNameReference), singleNameReference); } else { context.enter(helper.createFieldAccessNoClasspath(singleNameReference), singleNameReference); } } else if (singleNameReference.binding == null) { CtExpression access = helper.createVariableAccessNoClasspath(singleNameReference); if (access == null) { access = helper.createTypeAccessNoClasspath(singleNameReference); } context.enter(access, singleNameReference); } return true; }
@Override public boolean visit(LocalDeclaration localDeclaration, BlockScope scope) { CtLocalVariable<Object> v = factory.Core().createLocalVariable(); boolean isVar = localDeclaration.type.isTypeNameVar(scope); if (isVar) { v.setInferred(true); } v.setSimpleName(CharOperation.charToString(localDeclaration.name)); if (localDeclaration.binding != null) { v.setExtendedModifiers(getModifiers(localDeclaration.binding.modifiers, true, false)); } for (CtExtendedModifier extendedModifier : getModifiers(localDeclaration.modifiers, false, false)) { v.addModifier(extendedModifier.getKind()); // avoid to keep implicit AND explicit modifier of the same kind. } context.enter(v, localDeclaration); return true; }
<T> CtExecutableReference<T> getExecutableReference(MessageSend messageSend) { if (messageSend.binding != null) { return getExecutableReference(messageSend.binding); } CtExecutableReference<T> ref = jdtTreeBuilder.getFactory().Core().createExecutableReference(); ref.setSimpleName(CharOperation.charToString(messageSend.selector)); ref.setType(this.<T>getTypeReference(messageSend.expectedType(), true)); if (messageSend.receiver.resolvedType == null) { // It is crisis dude! static context, we don't have much more information. if (messageSend.receiver instanceof SingleNameReference) { ref.setDeclaringType(jdtTreeBuilder.getHelper().createTypeAccessNoClasspath((SingleNameReference) messageSend.receiver).getAccessedType()); } else if (messageSend.receiver instanceof QualifiedNameReference) { ref.setDeclaringType(jdtTreeBuilder.getHelper().createTypeAccessNoClasspath((QualifiedNameReference) messageSend.receiver).getAccessedType()); } } else { ref.setDeclaringType(getTypeReference(messageSend.receiver.resolvedType)); } if (messageSend.arguments != null) { final List<CtTypeReference<?>> parameters = new ArrayList<>(); for (Expression expression : messageSend.arguments) { parameters.add(getTypeReference(expression.resolvedType, true)); } ref.setParameters(parameters); } return ref; }
/** * Creates an executable reference expression. * * @param referenceExpression * Used to get the executable reference. * @return an executable reference expression. */ <T, E extends CtExpression<?>> CtExecutableReferenceExpression<T, E> createExecutableReferenceExpression(ReferenceExpression referenceExpression) { CtExecutableReferenceExpression<T, E> executableRef = jdtTreeBuilder.getFactory().Core().createExecutableReferenceExpression(); CtExecutableReference<T> executableReference = jdtTreeBuilder.getReferencesBuilder().getExecutableReference(referenceExpression.binding); if (executableReference == null) { // No classpath mode. executableReference = jdtTreeBuilder.getFactory().Core().createExecutableReference(); executableReference.setSimpleName(CharOperation.charToString(referenceExpression.selector)); executableReference.setDeclaringType(jdtTreeBuilder.getReferencesBuilder().getTypeReference(referenceExpression.lhs.resolvedType)); } final CtTypeReference<T> declaringType = (CtTypeReference<T>) executableReference.getDeclaringType(); executableReference.setType(declaringType == null ? null : declaringType.clone()); executableRef.setExecutable(executableReference); return executableRef; }
/** * Creates a parameter. If the argument have a type == null, we get the type from its binding. A type == null is possible when * this type is implicit like in a lambda where you don't need to specify the type of parameters. * * @param argument * Used to get the name of the parameter, the modifiers, know if it is a var args parameter. * @return a parameter. */ <T> CtParameter<T> createParameter(Argument argument) { CtParameter<T> p = jdtTreeBuilder.getFactory().Core().createParameter(); p.setSimpleName(CharOperation.charToString(argument.name)); p.setVarArgs(argument.isVarArgs()); p.setExtendedModifiers(getModifiers(argument.modifiers, false, false)); if (argument.binding != null && argument.binding.type != null && argument.type == null) { p.setType(jdtTreeBuilder.getReferencesBuilder().<T>getTypeReference(argument.binding.type)); p.getType().setImplicit(argument.type == null); if (p.getType() instanceof CtArrayTypeReference) { ((CtArrayTypeReference) p.getType()).getComponentType().setImplicit(argument.type == null); } } return p; }
@Override public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) { CtMethod<Object> m = factory.Core().createMethod(); m.setSimpleName(CharOperation.charToString(methodDeclaration.selector)); if (methodDeclaration.binding != null) { m.setExtendedModifiers(getModifiers(methodDeclaration.binding.modifiers, true, true)); } for (CtExtendedModifier extendedModifier : getModifiers(methodDeclaration.modifiers, false, true)) { m.addModifier(extendedModifier.getKind()); // avoid to keep implicit AND explicit modifier of the same kind. } m.setDefaultMethod(methodDeclaration.isDefaultMethod()); context.enter(m, methodDeclaration); // Create block if (!methodDeclaration.isAbstract() && (methodDeclaration.modifiers & ClassFileConstants.AccNative) == 0) { context.enter(getFactory().Core().createBlock(), methodDeclaration); context.exit(methodDeclaration); } // We consider the receiver as a standard argument (i.e. as a parameter) Receiver receiver = methodDeclaration.receiver; if (receiver != null) { receiver.traverse(this, methodDeclaration.scope); } return true; }