Search in sources :

Example 16 with CtField

use of spoon.reflect.declaration.CtField in project spoon by INRIA.

the class PackageTest method testGetFQNInNoClassPath.

@Test
public void testGetFQNInNoClassPath() {
    // contract: CtPackageReference simple name is also the fully qualified name of its referenced package, even in noclasspath
    final Launcher spoon = new Launcher();
    spoon.addInputResource("./src/test/resources/noclasspath/TorIntegration.java");
    spoon.getEnvironment().setNoClasspath(true);
    spoon.buildModel();
    CtClass torClass = spoon.getFactory().Class().get("com.duckduckgo.mobile.android.util.TorIntegration");
    CtField field = torClass.getField("orbotHelper");
    CtPackageReference fieldPkg = field.getType().getPackage();
    assertEquals("info.guardianproject.onionkit.ui", fieldPkg.getSimpleName());
    assertEquals("info.guardianproject.onionkit.ui", fieldPkg.getQualifiedName());
}
Also used : CtClass(spoon.reflect.declaration.CtClass) CtPackageReference(spoon.reflect.reference.CtPackageReference) CtField(spoon.reflect.declaration.CtField) Launcher(spoon.Launcher) Test(org.junit.Test)

Example 17 with CtField

use of spoon.reflect.declaration.CtField in project spoon by INRIA.

the class CloneReferenceTest method testGetDeclarationOfFieldAfterClone.

@Test
public void testGetDeclarationOfFieldAfterClone() throws Exception {
    // contract: all field references of the clone point to the old class
    // behaviour changed on https://github.com/INRIA/spoon/pull/1215
    Launcher spoon = new Launcher();
    String name = "field";
    spoon.addInputResource("./src/test/resources/noclasspath/A2.java");
    spoon.getEnvironment().setComplianceLevel(8);
    spoon.getEnvironment().setNoClasspath(true);
    spoon.buildModel();
    final CtClass<Object> a = spoon.getFactory().Class().get("A2");
    // test before clone
    CtField oldVar1 = (CtField) findVariable(a, name);
    CtField oldVar2 = (CtField) findReference(a, name).getDeclaration();
    assertTrue(oldVar1 == oldVar2);
    CtClass b = a.clone();
    // test after clone
    CtField var1 = (CtField) findVariable(b, name);
    CtVariableReference refVar1 = findReference(b, name);
    CtField var2 = (CtField) refVar1.getDeclaration();
    assertTrue(var1 != var2);
    assertTrue(var2 == oldVar1);
    assertTrue(var1.getParent(CtClass.class) == b);
}
Also used : CtClass(spoon.reflect.declaration.CtClass) CtVariableReference(spoon.reflect.reference.CtVariableReference) CtField(spoon.reflect.declaration.CtField) Launcher(spoon.Launcher) Test(org.junit.Test)

Example 18 with CtField

use of spoon.reflect.declaration.CtField 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 19 with CtField

use of spoon.reflect.declaration.CtField in project spoon by INRIA.

the class AccessibleVariablesFinder method getVariable.

private List<CtVariable> getVariable(final CtElement parent) {
    final List<CtVariable> variables = new ArrayList<>();
    if (parent == null) {
        return variables;
    }
    class VariableScanner extends CtInheritanceScanner {

        @Override
        public void visitCtStatementList(CtStatementList e) {
            for (int i = 0; i < e.getStatements().size(); i++) {
                CtStatement ctStatement = e.getStatements().get(i);
                if (ctStatement.getPosition() == null) {
                }
                if (ctStatement.getPosition() != null && ctStatement.getPosition().getSourceStart() > expression.getPosition().getSourceEnd()) {
                    break;
                }
                if (ctStatement instanceof CtVariable) {
                    variables.add((CtVariable) ctStatement);
                }
            }
            super.visitCtStatementList(e);
        }

        @Override
        public <T> void scanCtType(CtType<T> type) {
            List<CtField<?>> fields = type.getFields();
            for (int i = 0; i < fields.size(); i++) {
                CtField<?> ctField = fields.get(i);
                if (ctField.hasModifier(ModifierKind.PUBLIC) || ctField.hasModifier(ModifierKind.PROTECTED)) {
                    variables.add(ctField);
                } else if (ctField.hasModifier(ModifierKind.PRIVATE)) {
                    if (expression.hasParent(type)) {
                        variables.add(ctField);
                    }
                } else if (expression.getParent(CtPackage.class).equals(type.getParent(CtPackage.class))) {
                    // default visibility
                    variables.add(ctField);
                }
            }
            CtTypeReference<?> superclass = type.getSuperclass();
            if (superclass != null) {
                variables.addAll(getVariable(superclass.getTypeDeclaration()));
            }
            Set<CtTypeReference<?>> superInterfaces = type.getSuperInterfaces();
            for (Iterator<CtTypeReference<?>> iterator = superInterfaces.iterator(); iterator.hasNext(); ) {
                CtTypeReference<?> typeReference = iterator.next();
                variables.addAll(getVariable(typeReference.getTypeDeclaration()));
            }
            super.scanCtType(type);
        }

        @Override
        public void visitCtTryWithResource(CtTryWithResource e) {
            variables.addAll(e.getResources());
            super.visitCtTryWithResource(e);
        }

        @Override
        public void scanCtExecutable(CtExecutable e) {
            variables.addAll(e.getParameters());
            super.scanCtExecutable(e);
        }

        @Override
        public void visitCtFor(CtFor e) {
            for (CtStatement ctStatement : e.getForInit()) {
                this.scan(ctStatement);
            }
            super.visitCtFor(e);
        }

        @Override
        public void visitCtForEach(CtForEach e) {
            variables.add(e.getVariable());
            super.visitCtForEach(e);
        }

        @Override
        public void visitCtMethod(CtMethod e) {
            this.scan(e.getBody());
            super.visitCtMethod(e);
        }

        @Override
        public void visitCtLocalVariable(CtLocalVariable e) {
            variables.add(e);
            super.visitCtLocalVariable(e);
        }

        @Override
        public void visitCtCatch(CtCatch e) {
            variables.add(e.getParameter());
            super.visitCtCatch(e);
        }
    }
    new VariableScanner().scan(parent);
    return variables;
}
Also used : ArrayList(java.util.ArrayList) CtLocalVariable(spoon.reflect.code.CtLocalVariable) CtExecutable(spoon.reflect.declaration.CtExecutable) CtForEach(spoon.reflect.code.CtForEach) CtType(spoon.reflect.declaration.CtType) CtStatement(spoon.reflect.code.CtStatement) CtField(spoon.reflect.declaration.CtField) CtTypeReference(spoon.reflect.reference.CtTypeReference) CtVariable(spoon.reflect.declaration.CtVariable) CtStatementList(spoon.reflect.code.CtStatementList) CtPackage(spoon.reflect.declaration.CtPackage) CtTryWithResource(spoon.reflect.code.CtTryWithResource) CtCatch(spoon.reflect.code.CtCatch) CtFor(spoon.reflect.code.CtFor) CtMethod(spoon.reflect.declaration.CtMethod)

Example 20 with CtField

use of spoon.reflect.declaration.CtField in project spoon by INRIA.

the class FactoryTest method testCtModel.

@Test
public void testCtModel() throws Exception {
    SpoonAPI spoon = new Launcher();
    spoon.addInputResource("src/test/java/spoon/test/factory/testclasses");
    spoon.buildModel();
    CtModel model = spoon.getModel();
    // contains Foo and Foo.@Bar
    assertEquals(1, model.getAllTypes().size());
    // [, spoon, spoon.test, spoon.test.factory, spoon.test.factory.testclasses]
    assertEquals(5, model.getAllPackages().size());
    // add to itself is fine
    model.getRootPackage().addPackage(model.getRootPackage());
    assertEquals(1, model.getAllTypes().size());
    assertEquals(5, model.getAllPackages().size());
    model.getRootPackage().getPackage("spoon").addPackage(model.getRootPackage().getPackage("spoon"));
    assertEquals(1, model.getAllTypes().size());
    assertEquals(5, model.getAllPackages().size());
    model.getRootPackage().addPackage(model.getRootPackage().getPackage("spoon"));
    assertEquals(1, model.getAllTypes().size());
    assertEquals(5, model.getAllPackages().size());
    CtPackage p = model.getElements(new NamedElementFilter<>(CtPackage.class, "spoon")).get(0).clone();
    // if we change the implem, merge is impossible
    CtField f = spoon.getFactory().Core().createField();
    f.setSimpleName("foo");
    f.setType(spoon.getFactory().Type().BYTE);
    p.getElements(new NamedElementFilter<>(CtPackage.class, "testclasses")).get(0).getType("Foo").addField(f);
    try {
        model.getRootPackage().addPackage(p);
        fail("no exception thrown");
    } catch (IllegalStateException success) {
    }
    model.processWith(new AbstractProcessor<CtType>() {

        @Override
        public void process(CtType element) {
            element.delete();
        }
    });
    assertEquals(0, model.getAllTypes().size());
}
Also used : CtType(spoon.reflect.declaration.CtType) CtField(spoon.reflect.declaration.CtField) NamedElementFilter(spoon.reflect.visitor.filter.NamedElementFilter) Launcher(spoon.Launcher) CtPackage(spoon.reflect.declaration.CtPackage) CtModel(spoon.reflect.CtModel) SpoonAPI(spoon.SpoonAPI) Test(org.junit.Test)

Aggregations

CtField (spoon.reflect.declaration.CtField)39 Test (org.junit.Test)20 Launcher (spoon.Launcher)16 CtType (spoon.reflect.declaration.CtType)16 CtMethod (spoon.reflect.declaration.CtMethod)13 CtTypeReference (spoon.reflect.reference.CtTypeReference)12 ArrayList (java.util.ArrayList)8 CtElement (spoon.reflect.declaration.CtElement)8 CtClass (spoon.reflect.declaration.CtClass)6 CtTypeMember (spoon.reflect.declaration.CtTypeMember)6 Factory (spoon.reflect.factory.Factory)6 List (java.util.List)5 SpoonException (spoon.SpoonException)5 CtExecutable (spoon.reflect.declaration.CtExecutable)5 CtPackage (spoon.reflect.declaration.CtPackage)5 CtParameter (spoon.reflect.declaration.CtParameter)5 CtLocalVariable (spoon.reflect.code.CtLocalVariable)4 CtFieldReference (spoon.reflect.reference.CtFieldReference)4 TypeFilter (spoon.reflect.visitor.filter.TypeFilter)4 Set (java.util.Set)3