Skip to content

Commit

Permalink
Inspection - check if module namespace prefix is same as module file …
Browse files Browse the repository at this point in the history
…name

Closes ligasgr#104
  • Loading branch information
arnostv committed May 25, 2014
1 parent e3ac550 commit 25de05c
Show file tree
Hide file tree
Showing 9 changed files with 209 additions and 0 deletions.
1 change: 1 addition & 0 deletions CONTRIBUTORS
Expand Up @@ -9,3 +9,4 @@ Dirk Kirsten <dk@basex.org> - Issue #91 - Live templates
Mateusz Rudnicki <nicklamer@gmail.com> - Issue #93 - Enhance next/previous method navigation
Arnost Valicek <arnost.valicek@gmail.com> - Issue #21 - Unused variables highlighting
Arnost Valicek <arnost.valicek@gmail.com> - Issue #100 - Optimize imports in xquery files
Arnost Valicek <arnost.valicek@gmail.com> - Issue #104 - Inspection - check if module namespace prefix is same as module file name
@@ -0,0 +1,85 @@
/*
* Copyright 2013-2014 Grzegorz Ligas <ligasgr@gmail.com> and other contributors
* (see the CONTRIBUTORS file).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.intellij.xquery.inspection.namespaceprefix;

import com.intellij.codeInspection.InspectionManager;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.psi.PsiFile;
import org.apache.commons.lang.StringUtils;
import org.intellij.xquery.psi.XQueryFile;
import org.intellij.xquery.psi.XQueryModuleDecl;
import org.intellij.xquery.psi.XQueryNamespacePrefix;
import org.intellij.xquery.psi.XQueryURILiteral;

import static com.intellij.codeInspection.ProblemHighlightType.GENERIC_ERROR_OR_WARNING;
import static org.apache.commons.lang.StringUtils.uncapitalize;
import static org.intellij.xquery.util.StringUtils.removeQuotOrAposIfNeeded;

public class NamespacePrefixFromFileName extends LocalInspectionTool {

@Override
public ProblemDescriptor[] checkFile(PsiFile file, InspectionManager manager, boolean isOnTheFly) {
if (!(file instanceof XQueryFile)) {
return null;
}

final XQueryModuleDecl moduleDeclaration = ((XQueryFile) file).getModuleDeclaration();

if (!namespacePrefixIsDerivedFromFileName(moduleDeclaration)) {
ProblemDescriptor[] problemDescriptors = new ProblemDescriptor[1];
problemDescriptors[0] = manager.createProblemDescriptor(moduleDeclaration.getNamespacePrefix(), "Namespace prefix should be derived from file name part in URI", (LocalQuickFix) null,
GENERIC_ERROR_OR_WARNING, true);

return problemDescriptors;
} else {
return null;
}
}

private boolean namespacePrefixIsDerivedFromFileName(XQueryModuleDecl moduleDeclaration) {
final XQueryNamespacePrefix namespacePrefix = moduleDeclaration.getNamespacePrefix();
final XQueryURILiteral uriLiteral = moduleDeclaration.getURILiteral();

final String prefix = uncapitalize(namespacePrefix.getText());
final String filename = uncapitalize(filenameFromNamespaceURI(removeQuotOrAposIfNeeded(uriLiteral.getText())));

if (filename == null || prefix == null) {
return true;
} else {
return StringUtils.equals(prefix, filename);
}
}

private static String filenameFromNamespaceURI(String namespaceURI) {
final int lastSlash = namespaceURI.lastIndexOf("/");
if (lastSlash == -1) {
return null;
}

final String fileName = namespaceURI.substring(lastSlash + 1);
final int lastDot = fileName.lastIndexOf(".");

if (lastDot == -1) {
return fileName;
} else {
return fileName.substring(0, lastDot);
}
}
}
4 changes: 4 additions & 0 deletions src/main/resources/META-INF/plugin.xml
Expand Up @@ -76,6 +76,10 @@
<localInspection enabledByDefault="true" shortName="UnusedVariable" groupName="XQuery"
displayName="Unused variable"
implementationClass="org.intellij.xquery.inspection.variable.UnusedVariableInspection"/>
<localInspection enabledByDefault="false" shortName="NamespacePrefixFromFileName" groupName="XQuery"
displayName="Namespace prefix derived from file name"
implementationClass="org.intellij.xquery.inspection.namespaceprefix.NamespacePrefixFromFileName"/>

<codeInsight.parameterInfo language="XQuery" implementationClass="org.intellij.xquery.completion.function.parameters.XQueryParameterInfoHandler" />
<lang.documentationProvider language="XQuery" implementationClass="org.intellij.xquery.documentation.XQueryDocumentationProvider"/>
<projectConfigurable instance="org.intellij.xquery.settings.XQueryConfigurable"/>
Expand Down
@@ -0,0 +1,33 @@
<!--
~ Copyright 2013-2014 Grzegorz Ligas <ligasgr@gmail.com> and other contributors
~ (see the CONTRIBUTORS file).
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->

<html>
<body>
<font face="verdana" size="-1">
This inspection checks if namespace prefix is derived from file name part in namespace URI.
Inspection expects that URI is based on real file name. File extension should not be part of namespace prefix.
For example in module with namespace URI <code><b>my://sample/namespace/myFirstModule.xq</b></code> namespace prefix should be <code><b>myModuleOne</b></code>.
<pre>
module namespace <b>myFirstModule</b> = "my://sample/namespace/<b>myFirstModule</b>.xq";

declare function myFirstModule:someFunction() {
fn:true()
};
</pre>
</font>
</body>
</html>
@@ -0,0 +1,62 @@
/*
* Copyright 2013-2014 Grzegorz Ligas <ligasgr@gmail.com> and other contributors
* (see the CONTRIBUTORS file).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.intellij.xquery.inspection.namespaceprefix;

import com.intellij.codeInspection.LocalInspectionTool;
import org.intellij.xquery.BaseFunctionalTestCase;

import java.util.ArrayList;
import java.util.Collection;

public class NamespacePrefixFromFileNameTest extends BaseFunctionalTestCase {

@Override
protected String getTestDataPath() {
return "src/testFunctional/testData/org/intellij/xquery/inspection/namespaceprefix/";
}


public void testModuleNamespaceSameAsFilename() {
executeTest();
}

public void testModuleNamespaceDifferentThanFilename() {
executeTest();
}

public void testModuleNamespaceSameAsFilenameCaseSensitive() {
executeTest();
}

public void testModuleNamespaceSameAsFilenameWithoutExtension() {
executeTest();
}

private void executeTest() {
executeTest(getDefaultFileName());
}

private void executeTest(String filename) {
Collection<Class<? extends LocalInspectionTool>> inspections = new ArrayList<Class<? extends
LocalInspectionTool>>();
inspections.add(NamespacePrefixFromFileName.class);
myFixture.enableInspections(inspections);

myFixture.testHighlighting(true, false, false, filename);
}
}
@@ -0,0 +1,6 @@
module namespace <warning descr="Namespace prefix should be derived from file name part in URI">someOtherNamespace</warning> = "my://sample/namespace/ModuleNamespaceDifferentThanFilename.xq";


declare function someOtherNamespace:someFunction() {
fn:true()
};
@@ -0,0 +1,6 @@
module namespace moduleNamespaceSameAsFilename = "my://sample/namespace/ModuleNamespaceSameAsFilename.xq";


declare function moduleNamespaceSameAsFilename:someFunction() {
fn:true()
};
@@ -0,0 +1,6 @@
module namespace ModuleNamespaceSameAsFilenameCaseSensitive = "my://sample/namespace/ModuleNamespaceSameAsFilenameCaseSensitive.xq";


declare function ModuleNamespaceSameAsFilenameCaseSensitive:someFunction() {
fn:true()
};
@@ -0,0 +1,6 @@
module namespace moduleNamespaceSameAsFilenameWithoutExtension = "my://sample/namespace/moduleNamespaceSameAsFilenameWithoutExtension";


declare function moduleNamespaceSameAsFilenameWithoutExtension:someFunction() {
fn:true()
};

0 comments on commit 25de05c

Please sign in to comment.