/** * Cannot call a function X if it is defined in or imported into a scope with a function X * already defined * * <p>The third parameter indicates whether or not we should check that the definition to check * is actually imported into the target scope (it may not be if there is a USE statement with a * Rename or ONLY list). */ private void findAllPotentiallyConflictingDefinitionsInScope( List<Conflict> conflicts, ScopingNode importingScope, boolean shouldCheckIfDefinitionImportedIntoScope) { for (String newName : newNames) { List<PhotranTokenRef> definitionsLocalToScope = collectLocalDefinitions(importingScope); if (isProgramOrSubprogramOrModuleScope(importingScope) && shouldCheckIfDefinitionImportedIntoScope) { // Cannot call a variable X inside a function named X if (importingScope.isNamed(newName)) { if (definitionToCheck == null || definitionsLocalToScope.contains(definitionToCheck.getTokenRef())) { conflicts.add(new Conflict(newName, importingScope.getNameToken().getTokenRef())); } } // Cannot call a variable X inside a function named Y inside a module named X else { ScopingNode parent = importingScope.findNearestAncestor(ScopingNode.class); if (parent != null && parent.isNamed(newName)) { List<PhotranTokenRef> definitionsLocalToParent = collectLocalDefinitions(parent); if (definitionToCheck == null || definitionsLocalToParent.contains(definitionToCheck.getTokenRef())) { conflicts.add(new Conflict(newName, parent.getNameToken().getTokenRef())); } } } } // Cannot call a function X if it is defined in or imported into a scope with a function X // already defined Token newNameToken = definitionToCheck == null ? new FakeToken(scopeOfDefinitionToCheck, newName) : new FakeToken(definitionToCheck.getTokenRef().findToken(), newName); for (PhotranTokenRef conflict : importingScope.manuallyResolveInLocalScope(newNameToken)) { if (definitionsLocalToScope.contains(conflict)) { if (shouldCheckIfDefinitionImportedIntoScope) { if (definitionToCheck == null || definitionsLocalToScope.contains(definitionToCheck.getTokenRef())) { conflicts.add(new Conflict(newName, conflict)); } } else { conflicts.add(new Conflict(newName, conflict)); } } } } }
/** * Check whether the new definition will either conflict with or shadow an existing definition */ private List<PhotranTokenRef> findReferencesToShadowedDefinitions() { List<PhotranTokenRef> referencesToShadowedDefinitions = new LinkedList<PhotranTokenRef>(); for (String newName : newNames) { Token token = definitionToCheck == null ? new FakeToken(scopeOfDefinitionToCheck, newName) : new FakeToken(definitionToCheck.getTokenRef().findToken(), newName); List<PhotranTokenRef> shadowedDefinitions = scopeOfDefinitionToCheck.manuallyResolve(token); // TODO: Does not consider rename or only lists (need to tell if this SPECIFIC definition // will be imported) for (ScopingNode importingScope : scopeOfDefinitionToCheck.findImportingScopes()) { pm.subTask( Messages.bind( Messages.FortranResourceRefactoring_CheckingForReferencesTo, newName, importingScope.describe())); shadowedDefinitions.addAll(importingScope.manuallyResolve(token)); } for (PhotranTokenRef def : shadowedDefinitions) { Definition definition = PhotranVPG.getInstance().getDefinitionFor(def); if (definition != null) referencesToShadowedDefinitions.addAll(definition.findAllReferences(false)); } } return referencesToShadowedDefinitions; }
public CheckForConflictBindings( Definition definitionToCheck, Collection<PhotranTokenRef> allReferences, Collection<String> newNames) { this.definitionToCheck = definitionToCheck; this.scopeOfDefinitionToCheck = definitionToCheck.getTokenRef().findToken().getEnclosingScope(); this.allReferences = allReferences; this.newNames = newNames; }
private void permuteSubroutineInInterfaceBlocks() { for (Definition declaration : getInterfaceDeclarations()) { ASTSubroutineStmtNode subroutineStmt = declaration.getTokenRef().findToken().findNearestAncestor(ASTSubroutineStmtNode.class); if (subroutineStmt != null && subroutineStmt.getSubroutinePars() != null && subroutineStmt.getSubroutinePars().size() == newParameterList.size()) permuteDummyArguments(subroutineStmt); } }
private List<Conflict> findAllPotentiallyConflictingDefinitions() { List<Conflict> conflicts = new ArrayList<Conflict>(); if (definitionToCheck != null) { // Cannot call a main program (or function, etc.) X if it has an internal subprogram named // X, // even if that subprogram is never used (in which case it wouldn't be caught below) if (definitionToCheck.isMainProgram() || definitionToCheck.isSubprogram() || definitionToCheck.isModule()) { findAllPotentiallyConflictingDefinitionsInScope( conflicts, definitionToCheck.getTokenRef().findToken().findNearestAncestor(ScopingNode.class), false); } for (String newName : newNames) { if (definitionToCheck.isInternalSubprogramDefinition() && scopeContainingInternalSubprogram().isNamed(newName)) { conflicts.add( new Conflict( newName, scopeContainingInternalSubprogram().getNameToken().getTokenRef())); } } } for (ScopingNode importingScope : scopeItselfAndAllScopesThatImport(scopeOfDefinitionToCheck)) { pm.subTask( Messages.bind( Messages.FortranResourceRefactoring_CheckingForConflictingDefinitionsIn, importingScope.describe())); findAllPotentiallyConflictingDefinitionsInScope(conflicts, importingScope, true); } return conflicts; }
private ScopingNode scopeContainingInternalSubprogram() { return definitionToCheck.getTokenRef().findToken().getEnclosingScope(); }
private List<PhotranTokenRef> collectLocalDefinitions(ScopingNode importingScope) { List<PhotranTokenRef> definitionsLocalToScope = new ArrayList<PhotranTokenRef>(); for (Definition def : importingScope.getAllDefinitions()) if (def != null && !def.isIntrinsic()) definitionsLocalToScope.add(def.getTokenRef()); return definitionsLocalToScope; }