Search in sources :

Example 6 with CtFieldReference

use of spoon.reflect.reference.CtFieldReference in project spoon by INRIA.

the class DefaultJavaPrettyPrinter method visitCtCase.

@Override
@SuppressWarnings("rawtypes")
public <E> void visitCtCase(CtCase<E> caseStatement) {
    enterCtStatement(caseStatement);
    if (caseStatement.getCaseExpression() != null) {
        printer.writeKeyword("case").writeSpace();
        // writing enum case expression
        if (caseStatement.getCaseExpression() instanceof CtFieldAccess) {
            final CtFieldReference variable = ((CtFieldAccess) caseStatement.getCaseExpression()).getVariable();
            // In noclasspath mode, we don't have always the type of the declaring type.
            if (variable.getType() != null && variable.getDeclaringType() != null && variable.getType().getQualifiedName().equals(variable.getDeclaringType().getQualifiedName())) {
                printer.writeIdentifier(variable.getSimpleName());
            } else {
                scan(caseStatement.getCaseExpression());
            }
        } else {
            scan(caseStatement.getCaseExpression());
        }
    } else {
        printer.writeKeyword("default");
    }
    printer.writeSpace().writeSeparator(":").incTab();
    for (CtStatement statement : caseStatement.getStatements()) {
        printer.writeln();
        elementPrinterHelper.writeStatement(statement);
    }
    printer.decTab();
}
Also used : CtFieldAccess(spoon.reflect.code.CtFieldAccess) CtStatement(spoon.reflect.code.CtStatement) CtFieldReference(spoon.reflect.reference.CtFieldReference)

Example 7 with CtFieldReference

use of spoon.reflect.reference.CtFieldReference in project spoon by INRIA.

the class ElementPrinterHelper method writeImports.

/**
 * writes the imports in a specific order (eg all static imports together
 */
public void writeImports(Collection<CtImport> imports) {
    Set<String> setImports = new HashSet<>();
    Set<String> setStaticImports = new HashSet<>();
    for (CtImport ctImport : imports) {
        String importTypeStr;
        switch(ctImport.getImportKind()) {
            case TYPE:
                CtTypeReference typeRef = (CtTypeReference) ctImport.getReference();
                importTypeStr = typeRef.getQualifiedName();
                if (!isJavaLangClasses(importTypeStr)) {
                    setImports.add(importTypeStr);
                }
                break;
            case ALL_TYPES:
                CtPackageReference packageRef = (CtPackageReference) ctImport.getReference();
                importTypeStr = packageRef.getQualifiedName() + ".*";
                if (!isJavaLangClasses(importTypeStr)) {
                    setImports.add(importTypeStr);
                }
                break;
            case METHOD:
                CtExecutableReference execRef = (CtExecutableReference) ctImport.getReference();
                if (execRef.getDeclaringType() != null) {
                    setStaticImports.add(this.removeInnerTypeSeparator(execRef.getDeclaringType().getQualifiedName()) + "." + execRef.getSimpleName());
                }
                break;
            case FIELD:
                CtFieldReference fieldRef = (CtFieldReference) ctImport.getReference();
                setStaticImports.add(this.removeInnerTypeSeparator(fieldRef.getDeclaringType().getQualifiedName()) + "." + fieldRef.getSimpleName());
                break;
            case ALL_STATIC_MEMBERS:
                CtTypeReference typeStarRef = (CtTypeReference) ctImport.getReference();
                importTypeStr = typeStarRef.getQualifiedName();
                if (!isJavaLangClasses(importTypeStr)) {
                    setStaticImports.add(importTypeStr);
                }
                break;
        }
    }
    List<String> sortedImports = new ArrayList<>(setImports);
    Collections.sort(sortedImports);
    boolean isFirst = true;
    for (String importLine : sortedImports) {
        if (isFirst) {
            printer.writeln();
            printer.writeln();
            isFirst = false;
        }
        printer.writeKeyword("import").writeSpace();
        writeQualifiedName(importLine).writeSeparator(";").writeln();
    }
    if (setStaticImports.size() > 0) {
        if (isFirst) {
            printer.writeln();
        }
        printer.writeln();
        List<String> sortedStaticImports = new ArrayList<>(setStaticImports);
        Collections.sort(sortedStaticImports);
        for (String importLine : sortedStaticImports) {
            printer.writeKeyword("import").writeSpace().writeKeyword("static").writeSpace();
            writeQualifiedName(importLine).writeSeparator(";").writeln();
        }
    }
}
Also used : CtImport(spoon.reflect.declaration.CtImport) CtPackageReference(spoon.reflect.reference.CtPackageReference) CtTypeReference(spoon.reflect.reference.CtTypeReference) ArrayList(java.util.ArrayList) CtExecutableReference(spoon.reflect.reference.CtExecutableReference) CtFieldReference(spoon.reflect.reference.CtFieldReference) HashSet(java.util.HashSet)

Example 8 with CtFieldReference

use of spoon.reflect.reference.CtFieldReference in project spoon by INRIA.

the class ElementPrinterHelper method writeAnnotationElement.

/**
 * Writes an annotation element.
 */
public void writeAnnotationElement(Factory factory, Object value) {
    if (value instanceof CtTypeAccess) {
        prettyPrinter.scan((CtTypeAccess) value);
        printer.writeSeparator(".").writeKeyword("class");
    } else if (value instanceof CtFieldReference) {
        prettyPrinter.scan(((CtFieldReference<?>) value).getDeclaringType());
        printer.writeSeparator(".").writeIdentifier(((CtFieldReference<?>) value).getSimpleName());
    } else if (value instanceof CtElement) {
        prettyPrinter.scan((CtElement) value);
    } else if (value instanceof String) {
        printer.writeLiteral("\"" + LiteralHelper.getStringLiteral((String) value, true) + "\"");
    } else if (value instanceof Collection) {
        try (ListPrinter lp = createListPrinter(false, "{", false, true, ",", false, false, "}")) {
            for (Object obj : (Collection<?>) value) {
                lp.printSeparatorIfAppropriate();
                writeAnnotationElement(factory, obj);
            }
        }
    } else if (value instanceof Object[]) {
        try (ListPrinter lp = createListPrinter(false, "{", false, true, ",", false, false, "}")) {
            for (Object obj : (Object[]) value) {
                lp.printSeparatorIfAppropriate();
                writeAnnotationElement(factory, obj);
            }
        }
    } else if (value instanceof Enum) {
        try (Writable c = prettyPrinter.getContext().modify().ignoreGenerics(true)) {
            prettyPrinter.scan(factory.Type().createReference(((Enum<?>) value).getDeclaringClass()));
        }
        printer.writeSeparator(".");
        printer.writeIdentifier(value.toString());
    } else {
        // it probably prints, boolean, number, ...
        printer.writeLiteral(value.toString());
    }
}
Also used : CtElement(spoon.reflect.declaration.CtElement) CtTypeAccess(spoon.reflect.code.CtTypeAccess) CtFieldReference(spoon.reflect.reference.CtFieldReference) Collection(java.util.Collection) Writable(spoon.reflect.visitor.PrintingContext.Writable)

Example 9 with CtFieldReference

use of spoon.reflect.reference.CtFieldReference in project spoon by INRIA.

the class CtRenameLocalVariableRefactoring method detectNameConflicts.

@Override
protected void detectNameConflicts() {
    /*
		 * There can be these conflicts
		 * 1) target variable would shadow before declared variable (parameter, localVariable, catchVariable)
		 * --------------------------------------------------------------------------------------------------
		 */
    PotentialVariableDeclarationFunction potentialDeclarationFnc = new PotentialVariableDeclarationFunction(newName);
    CtVariable<?> var = getTarget().map(potentialDeclarationFnc).first();
    if (var != null) {
        if (var instanceof CtField) {
        /*
				 * we have found a field of same name.
				 * It is not problem, because variables can hide field declaration.
				 * Do nothing - OK
				 */
        } else if (potentialDeclarationFnc.isTypeOnTheWay()) {
            /*
				 * There is a local class declaration between future variable reference and variable declaration `var`.
				 * The found variable declaration `var` can be hidden by target variable with newName
				 * as long as there is no reference to `var` in visibility scope of the target variable.
				 * So search for such `var` reference now
				 */
            CtVariableReference<?> shadowedVar = target.map(new SiblingsFunction().includingSelf(true).mode(Mode.NEXT)).map(new VariableReferenceFunction(var)).first();
            if (shadowedVar != null) {
                // found variable reference, which would be shadowed by variable after rename.
                createNameConflictIssue(var, shadowedVar);
            } else {
            /*
					 * there is no local variable reference, which would be shadowed by variable after rename.
					 * OK
					 */
            }
        } else {
            /*
				 * the found variable is in conflict with target variable with newName
				 */
            createNameConflictIssue(var);
        }
    }
    /*
		 * 2) target variable is shadowed by later declared variable
		 * ---------------------------------------------------------
		 */
    final QueryDriver queryDriver = new QueryDriver();
    getTarget().map(new LocalVariableScopeFunction(queryDriver)).select(new Filter<CtElement>() {

        /**
         * return true for all CtVariables, which are in conflict
         */
        @Override
        public boolean matches(CtElement element) {
            if (element instanceof CtType<?>) {
                CtType<?> localClass = (CtType<?>) element;
                // TODO use faster hasField, implemented using map(new AllFieldsFunction()).select(new NameFilter(newName)).first()!=null
                Collection<CtFieldReference<?>> fields = localClass.getAllFields();
                for (CtFieldReference<?> fieldRef : fields) {
                    if (newName.equals(fieldRef.getSimpleName())) {
                        /*
							 * we have found a local class field, which will shadow input local variable if it's reference is in visibility scope of that field.
							 * Search for target variable reference in visibility scope of this field.
							 * If found than we cannot rename target variable to newName, because that reference would be shadowed
							 */
                        queryDriver.ignoreChildrenOf(element);
                        CtLocalVariableReference<?> shadowedVar = element.map(new LocalVariableReferenceFunction(target)).first();
                        if (shadowedVar != null) {
                            createNameConflictIssue(fieldRef.getFieldDeclaration(), shadowedVar);
                            return true;
                        }
                        return false;
                    }
                }
                return false;
            }
            if (element instanceof CtVariable<?>) {
                CtVariable<?> variable = (CtVariable<?>) element;
                if (newName.equals(variable.getSimpleName()) == false) {
                    // the variable with different name. Ignore it
                    return false;
                }
                // we have found a variable with new name
                if (variable instanceof CtField) {
                    throw new SpoonException("This should not happen. The children of local class which contains a field with new name should be skipped!");
                }
                if (variable instanceof CtCatchVariable || variable instanceof CtLocalVariable || variable instanceof CtParameter) {
                    /*
						 * we have found a catch variable or local variable or parameter with new name.
						 */
                    if (queryDriver.isInContextOfLocalClass()) {
                        /*
							 * We are in context of local class.
							 * This variable would shadow input local variable after rename
							 * so we cannot rename if there exist a local variable reference in variable visibility scope.
							 */
                        queryDriver.ignoreChildrenOf(variable.getParent());
                        CtQueryable searchScope;
                        if (variable instanceof CtLocalVariable) {
                            searchScope = variable.map(new SiblingsFunction().includingSelf(true).mode(Mode.NEXT));
                        } else {
                            searchScope = variable.getParent();
                        }
                        CtLocalVariableReference<?> shadowedVar = searchScope.map(new LocalVariableReferenceFunction(target)).first();
                        if (shadowedVar != null) {
                            // found local variable reference, which would be shadowed by variable after rename.
                            createNameConflictIssue(variable, shadowedVar);
                            return true;
                        }
                        // there is no local variable reference, which would be shadowed by variable after rename.
                        return false;
                    } else {
                        /*
							 * We are not in context of local class.
							 * So this variable is in conflict. Return it
							 */
                        createNameConflictIssue(variable);
                        return true;
                    }
                } else {
                    // Any new variable type???
                    throw new SpoonException("Unexpected variable " + variable.getClass().getName());
                }
            }
            return false;
        }
    }).first();
}
Also used : CtVariableReference(spoon.reflect.reference.CtVariableReference) SiblingsFunction(spoon.reflect.visitor.filter.SiblingsFunction) SpoonException(spoon.SpoonException) CtElement(spoon.reflect.declaration.CtElement) VariableReferenceFunction(spoon.reflect.visitor.filter.VariableReferenceFunction) LocalVariableReferenceFunction(spoon.reflect.visitor.filter.LocalVariableReferenceFunction) CtFieldReference(spoon.reflect.reference.CtFieldReference) CtParameter(spoon.reflect.declaration.CtParameter) CtLocalVariable(spoon.reflect.code.CtLocalVariable) CtType(spoon.reflect.declaration.CtType) Filter(spoon.reflect.visitor.Filter) CtField(spoon.reflect.declaration.CtField) CtQueryable(spoon.reflect.visitor.chain.CtQueryable) CtVariable(spoon.reflect.declaration.CtVariable) PotentialVariableDeclarationFunction(spoon.reflect.visitor.filter.PotentialVariableDeclarationFunction) CtCatchVariable(spoon.reflect.code.CtCatchVariable) LocalVariableScopeFunction(spoon.reflect.visitor.filter.LocalVariableScopeFunction) LocalVariableReferenceFunction(spoon.reflect.visitor.filter.LocalVariableReferenceFunction)

Example 10 with CtFieldReference

use of spoon.reflect.reference.CtFieldReference in project spoon by INRIA.

the class FieldAccessTest method testFieldAccessAutoExplicit.

@Test
public void testFieldAccessAutoExplicit() throws Exception {
    CtClass mouse = (CtClass) ModelUtils.buildClass(Mouse.class);
    CtMethod method = mouse.filterChildren((CtMethod m) -> "meth1".equals(m.getSimpleName())).first();
    CtFieldReference ageFR = method.filterChildren((CtFieldReference fr) -> "age".equals(fr.getSimpleName())).first();
    // first is the field printed with implicit "this."
    assertEquals("age", ageFR.getParent().toString());
    // add local variable declaration which hides the field declaration
    method.getBody().insertBegin((CtStatement) mouse.getFactory().createCodeSnippetStatement("int age = 1").compile());
    // now the field access must use explicit "this."
    assertEquals("this.age", ageFR.getParent().toString());
}
Also used : CtClass(spoon.reflect.declaration.CtClass) CtFieldReference(spoon.reflect.reference.CtFieldReference) CtMethod(spoon.reflect.declaration.CtMethod) Test(org.junit.Test)

Aggregations

CtFieldReference (spoon.reflect.reference.CtFieldReference)18 Test (org.junit.Test)9 CtTypeReference (spoon.reflect.reference.CtTypeReference)6 Launcher (spoon.Launcher)5 CtField (spoon.reflect.declaration.CtField)5 CtFieldAccess (spoon.reflect.code.CtFieldAccess)4 CtClass (spoon.reflect.declaration.CtClass)4 CtElement (spoon.reflect.declaration.CtElement)4 CtMethod (spoon.reflect.declaration.CtMethod)4 CtExecutableReference (spoon.reflect.reference.CtExecutableReference)4 CtInvocation (spoon.reflect.code.CtInvocation)3 CtImport (spoon.reflect.declaration.CtImport)3 ParentNotInitializedException (spoon.reflect.declaration.ParentNotInitializedException)3 Factory (spoon.reflect.factory.Factory)3 Field (java.lang.reflect.Field)2 ArrayList (java.util.ArrayList)2 Collection (java.util.Collection)2 HashSet (java.util.HashSet)2 SpoonException (spoon.SpoonException)2 MetamodelPropertyField (spoon.reflect.annotations.MetamodelPropertyField)2