Merge branch 'master' of git.labs.intellij.net:idea/community

This commit is contained in:
irengrig
2010-01-22 17:59:07 +03:00
54 changed files with 4017 additions and 799 deletions
Binary file not shown.
@@ -375,7 +375,7 @@ public class GuessManagerImpl extends GuessManager {
private static class ExpressionTypeInstructionVisitor extends InstructionVisitor {
private Map<PsiExpression, PsiType> myResult;
private PsiElement myForPlace;
private final PsiElement myForPlace;
private ExpressionTypeInstructionVisitor(PsiElement forPlace) {
myForPlace = forPlace;
@@ -56,4 +56,6 @@ public interface DfaMemoryState {
boolean checkNotNullable(DfaValue value);
boolean canBeNaN(DfaValue dfaValue);
boolean isNotNull(DfaVariableValue dfaVar);
}
@@ -471,7 +471,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
return false;
}
private boolean isNotNull(DfaVariableValue dfaVar) {
public boolean isNotNull(DfaVariableValue dfaVar) {
DfaConstValue dfaNull = myFactory.getConstFactory().getNull();
int c1Index = getOrCreateEqClassIndex(dfaVar);
int c2Index = getOrCreateEqClassIndex(dfaNull);
@@ -32,6 +32,7 @@ import com.intellij.codeInspection.dataFlow.instructions.AssignInstruction;
import com.intellij.codeInspection.dataFlow.instructions.Instruction;
import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
import com.intellij.codeInspection.dataFlow.value.DfaValue;
import gnu.trove.THashSet;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.NotNull;
@@ -76,7 +77,29 @@ public class DfaUtil {
final Collection<PsiExpression> expressions = value == null ? null : value.get(variable);
return expressions == null ? Collections.<PsiExpression>emptyList() : expressions;
}
public static enum Nullness {
NOT_NULL,NULL,UNKNOWN
}
// TRUE->not null, FALSE->null, null->unknown
@NotNull
public static Nullness checkNullness(@Nullable final PsiVariable variable, @Nullable final PsiElement context) {
if (variable == null || context == null) return Nullness.UNKNOWN;
final PsiElement codeBlock = getEnclosingCodeBlock(variable, context);
if (codeBlock == null) {
return Nullness.UNKNOWN;
}
final ValuableInstructionVisitor visitor = new ValuableInstructionVisitor(context);
RunnerResult result = new ValuableDataFlowRunner().analyzeMethod(codeBlock, visitor);
if (result != RunnerResult.OK) {
return Nullness.UNKNOWN;
}
if (visitor.myNulls.contains(variable)) return Nullness.NULL;
if (visitor.myNotNulls.contains(variable)) return Nullness.NOT_NULL;
return Nullness.UNKNOWN;
}
@Nullable
public static PsiCodeBlock getTopmostBlockInSameClass(@NotNull PsiElement position) {
PsiCodeBlock block = PsiTreeUtil.getParentOfType(position, PsiCodeBlock.class, false, PsiMember.class, PsiFile.class);
@@ -198,6 +221,8 @@ public class DfaUtil {
private static class ValuableInstructionVisitor extends StandardInstructionVisitor {
final MultiValuesMap<PsiVariable, PsiExpression> myValues = new MultiValuesMap<PsiVariable, PsiExpression>(true);
final Set<PsiVariable> myNulls = new THashSet<PsiVariable>();
final Set<PsiVariable> myNotNulls = new THashSet<PsiVariable>();
private final PsiElement myContext;
public ValuableInstructionVisitor(PsiElement context) {
@@ -216,6 +241,15 @@ public class DfaUtil {
myValues.put(variableValue.getPsiVariable(), psiExpression);
}
}
DfaValue value = instruction.getValue();
if (value instanceof DfaVariableValue) {
if (memState.isNotNull((DfaVariableValue)value)) {
myNotNulls.add(((DfaVariableValue)value).getPsiVariable());
}
if (memState.isNull(value)) {
myNulls.add(((DfaVariableValue)value).getPsiVariable());
}
}
}
return super.visitPush(instruction, runner, memState);
}
@@ -87,13 +87,15 @@ public class UnusedLibrariesInspection extends DescriptorProviderInspection {
});
libraryRoots.addAll(Arrays.asList(LibraryUtil.getLibraryRoots(modules.toArray(new Module[modules.size()]), false, false)));
}
GlobalSearchScope searchScope = null;
GlobalSearchScope searchScope;
try {
@NonNls final String libsName = "libs";
searchScope = GlobalSearchScope.filterScope(project, new NamedScope(libsName, PackageSetFactory.getInstance().compile("lib:*..*")));
}
catch (ParsingException e) {
//can't be
LOG.error(e);
return;
}
final AnalysisScope analysisScope = new AnalysisScope(searchScope, project);
analysisScope.setSearchInLibraries(true);
@@ -536,7 +536,7 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx implements Disposable {
}
private void checkModifierListOwner(PsiElement child) {
if (child instanceof PsiModifierListOwner) {
if (child instanceof PsiClass || child instanceof PsiMethod) {
PsiModifierList modifierList = ((PsiModifierListOwner)child).getModifierList();
if (modifierList != null && modifierList.getAnnotations().length > 0) {
myModificationTracker.incAnnotationModificationCounter();
@@ -29,7 +29,11 @@ public class MoveClassesHandler extends MoveClassesOrPackagesHandlerBase {
for(PsiElement element: elements) {
PsiFile parentFile;
if (element instanceof PsiJavaFile) {
if (((PsiJavaFile)element).getClasses().length == 0) return false;
final PsiClass[] classes = ((PsiJavaFile)element).getClasses();
if (classes.length == 0) return false;
for (PsiClass aClass : classes) {
if (aClass instanceof JspClass) return false;
}
parentFile = (PsiFile)element;
} else {
if (element instanceof JspClass) return false;
@@ -388,12 +388,20 @@ public class MoveInstanceMethodProcessor extends BaseRefactoringProcessor{
@Override public void visitReferenceExpression(PsiReferenceExpression expression) {
try {
final PsiExpression qualifier = expression.getQualifierExpression();
final PsiElement resolved = expression.resolve();
if (qualifier instanceof PsiReferenceExpression && ((PsiReferenceExpression)qualifier).isReferenceTo(myTargetVariable)) {
if (resolved instanceof PsiField) {
for (PsiParameter parameter : myMethod.getParameterList().getParameters()) {
if (Comparing.strEqual(parameter.getName(), ((PsiField)resolved).getName())) {
qualifier.replace(factory.createExpressionFromText("this", null));
return;
}
}
}
//Target is a field, replace target.m -> m
qualifier.delete();
return;
}
final PsiElement resolved = expression.resolve();
if (myTargetVariable.equals(resolved)) {
PsiThisExpression thisExpression = (PsiThisExpression)factory.createExpressionFromText("this", null);
expression.replace(thisExpression);
@@ -0,0 +1,12 @@
public class Test {
private Bar bar = new Bar();
public void <caret>foo(int x) {
bar.x = x;
}
private static class Bar {
private int x;
}
}
@@ -0,0 +1,12 @@
public class Test {
private Bar bar = new Bar();
private static class Bar {
private int x;
public void foo(int x) {
this.x = x;
}
}
}
@@ -0,0 +1,12 @@
public class Test {
private Bar bar = new Bar();
public void <caret>foo(int y) {
bar.x = y;
}
private static class Bar {
private int x;
}
}
@@ -0,0 +1,12 @@
public class Test {
private Bar bar = new Bar();
private static class Bar {
private int x;
public void foo(int y) {
x = y;
}
}
}
@@ -57,6 +57,14 @@ public class MoveInstanceMethodTest extends LightCodeInsightTestCase {
doTest(true, 0);
}
public void testQualifyFieldAccess() throws Exception {
doTest(false, 0);
}
public void testStripFieldQualifier() throws Exception {
doTest(false, 0);
}
private void doTest(boolean isTargetParameter, final int targetIndex) throws Exception {
doTest(isTargetParameter, targetIndex, null);
}
@@ -162,7 +162,7 @@ public class ClassInheritorsSearch extends ExtensibleQueryFactory<PsiClass, Clas
if (CommonClassNames.JAVA_LANG_OBJECT.equals(qname)) {
return AllClassesSearch.search(searchScope, baseClass.getProject(), parameters.getNameCondition()).forEach(new Processor<PsiClass>() {
public boolean process(PsiClass aClass) {
ProgressManager.getInstance().checkCanceled();
ProgressManager.checkCanceled();
return consumer.process(aClass);
}
});
@@ -173,7 +173,7 @@ public class ClassInheritorsSearch extends ExtensibleQueryFactory<PsiClass, Clas
final Set<PsiClass> processed = new HashSet<PsiClass>();
final Processor<PsiClass> processor = new Processor<PsiClass>() {
public boolean process(final PsiClass candidate) {
ProgressManager.getInstance().checkCanceled();
ProgressManager.checkCanceled();
final Ref<Boolean> result = new Ref<Boolean>();
ApplicationManager.getApplication().runReadAction(new Runnable() {
+128
View File
@@ -0,0 +1,128 @@
#include "stdafx.h"
#include "IdeaWin32.h"
#include "jni_util.h"
#include "windows.h"
jfieldID nameId;
HANDLE FindFileInner(JNIEnv *env, jstring path, LPWIN32_FIND_DATA lpData) {
const jchar* str = env->GetStringChars(path, 0);
HANDLE h = FindFirstFile((LPCWSTR)str, lpData);
env->ReleaseStringChars(path, str);
return h;
}
bool CopyObjectArray(JNIEnv *env, jobjectArray dst, jobjectArray src,
jint count)
{
int i;
for (i=0; i<count; i++) {
jobject p = env->GetObjectArrayElement(src, i);
env->SetObjectArrayElement(dst, i, p);
env->DeleteLocalRef(p);
}
return true;
}
static LONGLONG
fileTimeToInt64 (const FILETIME * time)
{
ULARGE_INTEGER _time;
_time.LowPart = time->dwLowDateTime;
_time.HighPart = time->dwHighDateTime;
return _time.QuadPart;
}
jfieldID nameID;
jfieldID attributesID;
jfieldID timestampID;
jobject CreateFileInfo(JNIEnv *env, LPWIN32_FIND_DATA lpData, jclass cls) {
jobject o = env->AllocObject(cls);
if (o == NULL) {
return NULL;
}
jstring fileName = env->NewString((jchar*)lpData->cFileName, (jsize)wcslen(lpData->cFileName));
if (fileName == NULL) {
return NULL;
}
env->SetObjectField(o, nameID, fileName);
env->SetIntField(o, attributesID, lpData->dwFileAttributes);
env->SetLongField(o, timestampID, fileTimeToInt64(&lpData->ftLastWriteTime));
return o;
}
JNIEXPORT void JNICALL Java_com_intellij_openapi_vfs_impl_win32_FileInfo_initIDs(JNIEnv *env, jclass cls) {
nameID = env->GetFieldID(cls, "name", "Ljava/lang/String;");
attributesID = env->GetFieldID(cls, "attributes", "I");
timestampID = env->GetFieldID(cls, "timestamp", "J");
}
JNIEXPORT jobject JNICALL Java_com_intellij_openapi_vfs_impl_win32_IdeaWin32_getInfo(JNIEnv *env, jobject method, jstring path) {
WIN32_FIND_DATA data;
HANDLE h = FindFileInner(env, path, &data);
if (h == INVALID_HANDLE_VALUE) {
return NULL;
}
FindClose(h);
jclass infoClass = env->FindClass("com/intellij/openapi/vfs/impl/win32/FileInfo");
return CreateFileInfo(env, &data, infoClass);
}
JNIEXPORT jobjectArray JNICALL Java_com_intellij_openapi_vfs_impl_win32_IdeaWin32_listChildren(JNIEnv *env, jobject method, jstring path)
{
WIN32_FIND_DATA data;
HANDLE h = FindFileInner(env, path, &data);
if (h == INVALID_HANDLE_VALUE) {
return NULL;
}
jobjectArray rv, old;
int len, maxlen;
len = 0;
maxlen = 16;
jclass infoClass = env->FindClass("com/intellij/openapi/vfs/impl/win32/FileInfo");
rv = env->NewObjectArray(maxlen, infoClass, NULL);
if (rv == NULL) goto error;
do {
if (len == maxlen) {
old = rv;
rv = env->NewObjectArray(maxlen <<= 1,
infoClass, NULL);
if (rv == NULL) goto error;
if (!CopyObjectArray(env, rv, old, len)) goto error;
env->DeleteLocalRef(old);
}
jobject o = CreateFileInfo(env, &data, infoClass);
env->SetObjectArrayElement(rv, len++, o);
env->DeleteLocalRef(o);
}
while (FindNextFile(h, &data));
FindClose(h);
old = rv;
rv = env->NewObjectArray(len, infoClass, NULL);
if (rv == NULL) goto error;
if (!CopyObjectArray(env, rv, old, len)) goto error;
return rv;
error:
FindClose(h);
return NULL;
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
+15
View File
@@ -0,0 +1,15 @@
#include "jni.h"
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT void JNICALL Java_com_intellij_openapi_vfs_impl_win32_FileInfo_initIDs(JNIEnv *env, jclass cls);
JNIEXPORT jobject JNICALL Java_com_intellij_openapi_vfs_impl_win32_IdeaWin32_getInfo(JNIEnv *env, jobject method, jstring path);
JNIEXPORT jobjectArray JNICALL Java_com_intellij_openapi_vfs_impl_win32_IdeaWin32_listChildren(JNIEnv *env, jobject method, jstring path);
#ifdef __cplusplus
}
#endif
+230
View File
@@ -0,0 +1,230 @@
<?xml version="1.0" encoding="windows-1251"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Name="IdeaWin32"
ProjectGUID="{D1A0CC4B-C100-46E4-918A-958626AE1ACF}"
RootNamespace="IdeaWin32"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;IDEAWIN32_EXPORTS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
DisableLanguageExtensions="false"
UsePrecompiledHeader="2"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;IDEAWIN32_EXPORTS"
RuntimeLibrary="2"
UsePrecompiledHeader="2"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\IdeaWin32.cpp"
>
</File>
<File
RelativePath=".\IdeaWin32.h"
>
</File>
<File
RelativePath=".\stdafx.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\stdafx.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
<File
RelativePath=".\ReadMe.txt"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
+31
View File
@@ -0,0 +1,31 @@
/*
* Copyright 1997 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
#ifndef _JLONG_H_
#define _JLONG_H_
#include "jlong_md.h"
#endif
+93
View File
@@ -0,0 +1,93 @@
/*
* Copyright 1997-2002 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
#ifndef _WIN32_JLONG_MD_H_
#define _WIN32_JLONG_MD_H_
/* Make sure ptrdiff_t is defined */
#include <stddef.h>
#define jlong_high(a) ((jint)((a)>>32))
#define jlong_low(a) ((jint)(a))
#define jlong_add(a, b) ((a) + (b))
#define jlong_and(a, b) ((a) & (b))
#define jlong_div(a, b) ((a) / (b))
#define jlong_mul(a, b) ((a) * (b))
#define jlong_neg(a) (-(a))
#define jlong_not(a) (~(a))
#define jlong_or(a, b) ((a) | (b))
#define jlong_shl(a, n) ((a) << (n))
#define jlong_shr(a, n) ((a) >> (n))
#define jlong_sub(a, b) ((a) - (b))
#define jlong_xor(a, b) ((a) ^ (b))
#define jlong_rem(a,b) ((a) % (b))
/* comparison operators */
#define jlong_ltz(ll) ((ll) < 0)
#define jlong_gez(ll) ((ll) >= 0)
#define jlong_gtz(ll) ((ll) > 0)
#define jlong_eqz(a) ((a) == 0)
#define jlong_eq(a, b) ((a) == (b))
#define jlong_ne(a,b) ((a) != (b))
#define jlong_ge(a,b) ((a) >= (b))
#define jlong_le(a,b) ((a) <= (b))
#define jlong_lt(a,b) ((a) < (b))
#define jlong_gt(a,b) ((a) > (b))
#define jlong_zero ((jlong) 0)
#define jlong_one ((jlong) 1)
#define jlong_minus_one ((jlong) -1)
/* For static variables initialized to zero */
#define jlong_zero_init ((jlong) 0)
#ifdef _WIN64
#define jlong_to_ptr(a) ((void*)(a))
#define ptr_to_jlong(a) ((jlong)(a))
#else
/* Double casting to avoid warning messages looking for casting of */
/* smaller sizes into pointers */
#define jlong_to_ptr(a) ((void*)(int)(a))
#define ptr_to_jlong(a) ((jlong)(int)(a))
#endif
#define jint_to_jlong(a) ((jlong)(a))
#define jlong_to_jint(a) ((jint)(a))
/* Useful on machines where jlong and jdouble have different endianness. */
#define jlong_to_jdouble_bits(a)
#define jdouble_to_jlong_bits(a)
#define jlong_to_int(a) ((int)(a))
#define int_to_jlong(a) ((jlong)(a))
#define jlong_to_uint(a) ((unsigned int)(a))
#define uint_to_jlong(a) ((jlong)(a))
#define jlong_to_ptrdiff(a) ((ptrdiff_t)(a))
#define ptrdiff_to_jlong(a) ((jlong)(a))
#define jlong_to_size(a) ((size_t)(a))
#define size_to_jlong(a) ((jlong)(a))
#define long_to_jlong(a) ((jlong)(a))
#endif
File diff suppressed because it is too large Load Diff
+19
View File
@@ -0,0 +1,19 @@
/*
* @(#)jni_md.h 1.15 05/11/17
*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
#ifndef _JAVASOFT_JNI_MD_H_
#define _JAVASOFT_JNI_MD_H_
#define JNIEXPORT __declspec(dllexport)
#define JNIIMPORT __declspec(dllimport)
#define JNICALL __stdcall
typedef long jint;
typedef __int64 jlong;
typedef signed char jbyte;
#endif /* !_JAVASOFT_JNI_MD_H_ */
+347
View File
@@ -0,0 +1,347 @@
/*
* Copyright 1997-2004 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
#ifndef JNI_UTIL_H
#define JNI_UTIL_H
#include "jni.h"
#include "jlong.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* This file contains utility functions that can be implemented in pure JNI.
*
* Caution: Callers of functions declared in this file should be
* particularly aware of the fact that these functions are convenience
* functions, and as such are often compound operations, each one of
* which may throw an exception. Therefore, the functions this file
* will often return silently if an exception has occured, and callers
* must check for exception themselves.
*/
/* Throw a Java exception by name. Similar to SignalError. */
JNIEXPORT void JNICALL
JNU_ThrowByName(JNIEnv *env, const char *name, const char *msg);
/* Throw common exceptions */
JNIEXPORT void JNICALL
JNU_ThrowNullPointerException(JNIEnv *env, const char *msg);
JNIEXPORT void JNICALL
JNU_ThrowArrayIndexOutOfBoundsException(JNIEnv *env, const char *msg);
JNIEXPORT void JNICALL
JNU_ThrowOutOfMemoryError(JNIEnv *env, const char *msg);
JNIEXPORT void JNICALL
JNU_ThrowIllegalArgumentException(JNIEnv *env, const char *msg);
JNIEXPORT void JNICALL
JNU_ThrowIllegalAccessError(JNIEnv *env, const char *msg);
JNIEXPORT void JNICALL
JNU_ThrowIllegalAccessException(JNIEnv *env, const char *msg);
JNIEXPORT void JNICALL
JNU_ThrowInternalError(JNIEnv *env, const char *msg);
JNIEXPORT void JNICALL
JNU_ThrowIOException(JNIEnv *env, const char *msg);
JNIEXPORT void JNICALL
JNU_ThrowNoSuchFieldException(JNIEnv *env, const char *msg);
JNIEXPORT void JNICALL
JNU_ThrowNoSuchMethodException(JNIEnv *env, const char *msg);
JNIEXPORT void JNICALL
JNU_ThrowClassNotFoundException(JNIEnv *env, const char *msg);
JNIEXPORT void JNICALL
JNU_ThrowNumberFormatException(JNIEnv *env, const char *msg);
JNIEXPORT void JNICALL
JNU_ThrowNoSuchFieldError(JNIEnv *env, const char *msg);
JNIEXPORT void JNICALL
JNU_ThrowNoSuchMethodError(JNIEnv *env, const char *msg);
JNIEXPORT void JNICALL
JNU_ThrowStringIndexOutOfBoundsException(JNIEnv *env, const char *msg);
JNIEXPORT void JNICALL
JNU_ThrowInstantiationException(JNIEnv *env, const char *msg);
/* Throw an exception by name, using the string returned by
* JVM_LastErrorString for the detail string. If the last-error
* string is NULL, use the given default detail string.
*/
JNIEXPORT void JNICALL
JNU_ThrowByNameWithLastError(JNIEnv *env, const char *name,
const char *defaultMessage);
/* Throw an IOException, using the last-error string for the detail
* string. If the last-error string is NULL, use the given default
* detail string.
*/
JNIEXPORT void JNICALL
JNU_ThrowIOExceptionWithLastError(JNIEnv *env, const char *defaultDetail);
/* Convert between Java strings and i18n C strings */
JNIEXPORT jstring
NewStringPlatform(JNIEnv *env, const char *str);
JNIEXPORT const char *
GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy);
JNIEXPORT jstring JNICALL
JNU_NewStringPlatform(JNIEnv *env, const char *str);
JNIEXPORT const char * JNICALL
JNU_GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy);
JNIEXPORT void JNICALL
JNU_ReleaseStringPlatformChars(JNIEnv *env, jstring jstr, const char *str);
/* Class constants */
JNIEXPORT jclass JNICALL
JNU_ClassString(JNIEnv *env);
JNIEXPORT jclass JNICALL
JNU_ClassClass(JNIEnv *env);
JNIEXPORT jclass JNICALL
JNU_ClassObject(JNIEnv *env);
JNIEXPORT jclass JNICALL
JNU_ClassThrowable(JNIEnv *env);
/* Copy count number of arguments from src to dst. Array bounds
* and ArrayStoreException are checked.
*/
JNIEXPORT jint JNICALL
JNU_CopyObjectArray(JNIEnv *env, jobjectArray dst, jobjectArray src,
jint count);
/* Invoke a object-returning static method, based on class name,
* method name, and signature string.
*
* The caller should check for exceptions by setting hasException
* argument. If the caller is not interested in whether an exception
* has occurred, pass in NULL.
*/
JNIEXPORT jvalue JNICALL
JNU_CallStaticMethodByName(JNIEnv *env,
jboolean *hasException,
const char *class_name,
const char *name,
const char *signature,
...);
/* Invoke an instance method by name.
*/
JNIEXPORT jvalue JNICALL
JNU_CallMethodByName(JNIEnv *env,
jboolean *hasException,
jobject obj,
const char *name,
const char *signature,
...);
JNIEXPORT jvalue JNICALL
JNU_CallMethodByNameV(JNIEnv *env,
jboolean *hasException,
jobject obj,
const char *name,
const char *signature,
va_list args);
/* Construct a new object of class, specifying the class by name,
* and specififying which constructor to run and what arguments to
* pass to it.
*
* The method will return an initialized instance if successful.
* It will return NULL if an error has occured (for example if
* it ran out of memory) and the appropriate Java exception will
* have been thrown.
*/
JNIEXPORT jobject JNICALL
JNU_NewObjectByName(JNIEnv *env, const char *class_name,
const char *constructor_sig, ...);
/* returns:
* 0: object is not an instance of the class named by classname.
* 1: object is an instance of the class named by classname.
* -1: the class named by classname cannot be found. An exception
* has been thrown.
*/
JNIEXPORT jint JNICALL
JNU_IsInstanceOfByName(JNIEnv *env, jobject object, char *classname);
/* Get or set class and instance fields.
* Note that set functions take a variable number of arguments,
* but only one argument of the appropriate type can be passed.
* For example, to set an integer field i to 100:
*
* JNU_SetFieldByName(env, &exc, obj, "i", "I", 100);
*
* To set a float field f to 12.3:
*
* JNU_SetFieldByName(env, &exc, obj, "f", "F", 12.3);
*
* The caller should check for exceptions by setting hasException
* argument. If the caller is not interested in whether an exception
* has occurred, pass in NULL.
*/
JNIEXPORT jvalue JNICALL
JNU_GetFieldByName(JNIEnv *env,
jboolean *hasException,
jobject obj,
const char *name,
const char *sig);
JNIEXPORT void JNICALL
JNU_SetFieldByName(JNIEnv *env,
jboolean *hasException,
jobject obj,
const char *name,
const char *sig,
...);
JNIEXPORT jvalue JNICALL
JNU_GetStaticFieldByName(JNIEnv *env,
jboolean *hasException,
const char *classname,
const char *name,
const char *sig);
JNIEXPORT void JNICALL
JNU_SetStaticFieldByName(JNIEnv *env,
jboolean *hasException,
const char *classname,
const char *name,
const char *sig,
...);
/*
* Calls the .equals method.
*/
JNIEXPORT jboolean JNICALL
JNU_Equals(JNIEnv *env, jobject object1, jobject object2);
/************************************************************************
* Thread calls
*
* Convenience thread-related calls on the java.lang.Object class.
*/
JNIEXPORT void JNICALL
JNU_MonitorWait(JNIEnv *env, jobject object, jlong timeout);
JNIEXPORT void JNICALL
JNU_Notify(JNIEnv *env, jobject object);
JNIEXPORT void JNICALL
JNU_NotifyAll(JNIEnv *env, jobject object);
/************************************************************************
* Miscellaneous utilities used by the class libraries
*/
#define IS_NULL(obj) ((obj) == NULL)
#define JNU_IsNull(env,obj) ((obj) == NULL)
/************************************************************************
* Debugging utilities
*/
JNIEXPORT void JNICALL
JNU_PrintString(JNIEnv *env, char *hdr, jstring string);
JNIEXPORT void JNICALL
JNU_PrintClass(JNIEnv *env, char *hdr, jobject object);
JNIEXPORT jstring JNICALL
JNU_ToString(JNIEnv *env, jobject object);
/*
* Package shorthand for use by native libraries
*/
#define JNU_JAVAPKG "java/lang/"
#define JNU_JAVAIOPKG "java/io/"
#define JNU_JAVANETPKG "java/net/"
/*
* Check if the current thread is attached to the VM, and returns
* the JNIEnv of the specified version if the thread is attached.
*
* If the current thread is not attached, this function returns 0.
*
* If the current thread is attached, this function returns the
* JNI environment, or returns (void *)JNI_ERR if the specified
* version is not supported.
*/
JNIEXPORT void * JNICALL
JNU_GetEnv(JavaVM *vm, jint version);
/*
* Warning free access to pointers stored in Java long fields.
*/
#define JNU_GetLongFieldAsPtr(env,obj,id) \
(jlong_to_ptr((*(env))->GetLongField((env),(obj),(id))))
#define JNU_SetLongFieldFromPtr(env,obj,id,val) \
(*(env))->SetLongField((env),(obj),(id),ptr_to_jlong(val))
/*
* Internal use only.
*/
enum {
NO_ENCODING_YET = 0, /* "sun.jnu.encoding" not yet set */
NO_FAST_ENCODING, /* Platform encoding is not fast */
FAST_8859_1, /* ISO-8859-1 */
FAST_CP1252, /* MS-DOS Cp1252 */
FAST_646_US /* US-ASCII : ISO646-US */
};
jstring nativeNewStringPlatform(JNIEnv *env, const char *str);
char* nativeGetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy);
int getFastEncoding();
void initializeEncoding();
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* JNI_UTIL_H */
+8
View File
@@ -0,0 +1,8 @@
// stdafx.cpp : source file that includes just the standard includes
// IdeaWin32.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file
+28
View File
@@ -0,0 +1,28 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
// Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef WINVER // Allow use of features specific to Windows XP or later.
#define WINVER 0x0501 // Change this to the appropriate value to target other versions of Windows.
#endif
#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later.
#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
#endif
#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later.
#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
#endif
#ifndef _WIN32_IE // Allow use of features specific to IE 6.0 or later.
#define _WIN32_IE 0x0600 // Change this to the appropriate value to target other versions of IE.
#endif
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
@@ -131,6 +131,7 @@ public class AnalysisScope {
myModules = null;
myScope = scope;
myType = CUSTOM;
mySearchInLibraries = scope instanceof GlobalSearchScope && ((GlobalSearchScope)scope).isSearchInLibraries();
}
public AnalysisScope(@NotNull Project project, @NotNull Collection<VirtualFile> virtualFiles) {
@@ -198,6 +199,11 @@ public class AnalysisScope {
public boolean contains(VirtualFile file) {
if (myFilesSet == null) {
if (myType == CUSTOM) {
// optimization
if (myScope instanceof GlobalSearchScope) return ((GlobalSearchScope)myScope).contains(file);
if (myScope instanceof LocalSearchScope) return ((LocalSearchScope)myScope).isInScope(file);
}
if (myType == PROJECT) { //optimization
final ProjectFileIndex index = ProjectRootManager.getInstance(myProject).getFileIndex();
return index.isInContent(file) && (myIncludeTestSource || !index.isInTestSourceContent(file));
@@ -19,6 +19,7 @@ package com.intellij.codeInsight.intention;
import com.intellij.CommonBundle;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.CustomLoadingExtensionPointBean;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
@@ -29,7 +30,7 @@ import java.util.Locale;
import java.util.ResourceBundle;
public class IntentionActionBean extends CustomLoadingExtensionPointBean {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.intention.IntentionActionBean");
@Tag("className")
public String className;
@Tag("category")
@@ -45,6 +46,9 @@ public class IntentionActionBean extends CustomLoadingExtensionPointBean {
public String[] getCategories() {
if (categoryKey != null) {
final String baseName = bundleName != null ? bundleName : ((IdeaPluginDescriptor)myPluginDescriptor).getResourceBundleBaseName();
if (baseName == null) {
LOG.error("No resource bundle specified for "+myPluginDescriptor);
}
final ResourceBundle bundle = ResourceBundle.getBundle(baseName, Locale.getDefault(), myPluginDescriptor.getPluginClassLoader());
final String[] keys = categoryKey.split("/");
@@ -54,7 +54,7 @@ public class AnalysisUIOptions implements PersistentStateComponent<AnalysisUIOpt
public boolean FILTER_RESOLVED_ITEMS = true;
public boolean ANALYZE_TEST_SOURCES = true;
public boolean SHOW_DIFF_WITH_PREVIOUS_RUN = false;
public int SCOPE_TYPE = 1;
public int SCOPE_TYPE = AnalysisScope.PROJECT;
public String CUSTOM_SCOPE_NAME = "";
private final AutoScrollToSourceHandler myAutoScrollToSourceHandler;
public boolean SHOW_ONLY_DIFF = false;
@@ -143,7 +143,6 @@ public class BaseAnalysisActionDialog extends DialogWrapper {
ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
boolean searchInLib = file != null && (fileIndex.isInLibraryClasses(file) || fileIndex.isInLibrarySource(file));
String preselect = StringUtil.isEmptyOrSpaces(myAnalysisOptions.CUSTOM_SCOPE_NAME)
? FindSettings.getInstance().getDefaultScopeName()
: myAnalysisOptions.CUSTOM_SCOPE_NAME;
@@ -153,6 +152,7 @@ public class BaseAnalysisActionDialog extends DialogWrapper {
if (GlobalSearchScope.allScope(myProject).getDisplayName().equals(preselect)) {
myAnalysisOptions.SCOPE_TYPE = AnalysisScope.CUSTOM;
myAnalysisOptions.CUSTOM_SCOPE_NAME = preselect;
searchInLib = true;
}
//custom scope
@@ -217,11 +217,6 @@ public class BaseAnalysisActionDialog extends DialogWrapper {
return null;
}
protected void doOKAction() {
myAnalysisOptions.CUSTOM_SCOPE_NAME = myScopeCombo.getSelectedScopeName();
super.doOKAction();
}
public boolean isInspectTestSources(){
return myInspectTestSource.isSelected();
}
@@ -276,6 +271,8 @@ public class BaseAnalysisActionDialog extends DialogWrapper {
}
uiOptions.ANALYZE_TEST_SOURCES = isInspectTestSources();
scope.setIncludeTestSource(isInspectTestSources());
FindSettings.getInstance().setDefaultScopeName(scope.getDisplayName());
return scope;
}
}
@@ -1,24 +1,24 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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 com.intellij.codeInsight.template.impl;
import com.intellij.codeInsight.CodeInsightActionHandler;
import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.codeInsight.completion.impl.CamelHumpMatcher;
import com.intellij.codeInsight.hint.HintManager;
import com.intellij.codeInsight.lookup.*;
import com.intellij.codeInsight.lookup.impl.LookupImpl;
@@ -35,8 +35,9 @@ import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class ListTemplatesHandler implements CodeInsightActionHandler{
public class ListTemplatesHandler implements CodeInsightActionHandler {
public void invoke(@NotNull final Project project, @NotNull final Editor editor, @NotNull PsiFile file) {
if (!file.isWritable()) return;
EditorUtil.fillVirtualSpaceUntilCaret(editor);
@@ -51,11 +52,11 @@ public class ListTemplatesHandler implements CodeInsightActionHandler{
matchingTemplates.add(template);
}
}
if (matchingTemplates.size() == 0) {
String text = prefix.length() == 0
? CodeInsightBundle.message("templates.no.defined")
: CodeInsightBundle.message("templates.no.defined.with.prefix", prefix);
? CodeInsightBundle.message("templates.no.defined")
: CodeInsightBundle.message("templates.no.defined.with.prefix", prefix);
HintManager.getInstance().showErrorHint(editor, text);
return;
}
@@ -65,27 +66,42 @@ public class ListTemplatesHandler implements CodeInsightActionHandler{
public static void showTemplatesLookup(final Project project, final Editor editor, String prefix, List<TemplateImpl> matchingTemplates) {
ArrayList<LookupItem> array = new ArrayList<LookupItem>();
for (TemplateImpl template: matchingTemplates) {
for (TemplateImpl template : matchingTemplates) {
array.add(new LookupItem(template, template.getKey()));
}
LookupElement[] items = array.toArray(new LookupElement[array.size()]);
final LookupImpl lookup = (LookupImpl) LookupManager.getInstance(project).createLookup(editor, items, prefix, LookupArranger.DEFAULT);
lookup.addLookupListener(
new LookupAdapter() {
public void itemSelected(LookupEvent event) {
final LookupElement lookupElement = event.getItem();
if (lookupElement != null) {
final TemplateImpl template = (TemplateImpl)lookupElement.getObject();
new WriteCommandAction(project) {
protected void run(Result result) throws Throwable {
((TemplateManagerImpl) TemplateManager.getInstance(project)).startTemplateWithPrefix(editor, template, null);
}
}.execute();
}
}
}
);
final LookupImpl lookup = (LookupImpl)LookupManager.getInstance(project).createLookup(editor, items, prefix, LookupArranger.DEFAULT);
lookup.addLookupListener(new MyLookupAdapter(project, editor, null));
lookup.show();
}
private static String computePrefix(TemplateImpl template, String argument) {
String key = template.getKey();
if (argument == null) {
return key;
}
if (key.length() > 0 && Character.isJavaIdentifierPart(key.charAt(key.length() - 1))) {
return key + ' ' + argument;
}
return key + argument;
}
public static void showTemplatesLookup(final Project project,
final Editor editor,
Map<TemplateImpl, String> template2Argument) {
ArrayList<LookupItem> array = new ArrayList<LookupItem>();
for (TemplateImpl template : template2Argument.keySet()) {
String argument = template2Argument.get(template);
String prefix = computePrefix(template, argument);
LookupItem item = new LookupItem(template, prefix);
item.setPrefixMatcher(new CamelHumpMatcher(prefix));
array.add(item);
}
LookupElement[] items = array.toArray(new LookupElement[array.size()]);
final LookupImpl lookup = (LookupImpl)LookupManager.getInstance(project).createLookup(editor, items, null, LookupArranger.DEFAULT);
lookup.addLookupListener(new MyLookupAdapter(project, editor, template2Argument));
lookup.show();
}
@@ -93,10 +109,10 @@ public class ListTemplatesHandler implements CodeInsightActionHandler{
return true;
}
private static String getPrefix(Document document, int offset) {
private String getPrefix(Document document, int offset) {
CharSequence chars = document.getCharsSequence();
int start = offset;
while(true){
while (true) {
if (start == 0) break;
char c = chars.charAt(start - 1);
if (!isInPrefix(c)) break;
@@ -105,7 +121,29 @@ public class ListTemplatesHandler implements CodeInsightActionHandler{
return chars.subSequence(start, offset).toString();
}
private static boolean isInPrefix(final char c) {
private boolean isInPrefix(final char c) {
return Character.isJavaIdentifierPart(c) || c == '.';
}
private static class MyLookupAdapter extends LookupAdapter {
private final Project myProject;
private final Editor myEditor;
private final Map<TemplateImpl, String> myTemplate2Argument;
public MyLookupAdapter(Project project, Editor editor, Map<TemplateImpl, String> template2Argument) {
myProject = project;
myEditor = editor;
myTemplate2Argument = template2Argument;
}
public void itemSelected(LookupEvent event) {
final TemplateImpl template = (TemplateImpl)event.getItem().getObject();
final String argument = myTemplate2Argument != null ? myTemplate2Argument.get(template) : null;
new WriteCommandAction(myProject) {
protected void run(Result result) throws Throwable {
((TemplateManagerImpl)TemplateManager.getInstance(myProject)).startTemplateWithPrefix(myEditor, template, null, argument);
}
}.execute();
}
}
}
@@ -88,6 +88,7 @@ public class TemplateImpl extends Template implements SchemeElement {
@NonNls public static final String SELECTION = "SELECTION";
@NonNls public static final String SELECTION_START = "SELECTION_START";
@NonNls public static final String SELECTION_END = "SELECTION_END";
@NonNls public static final String ARG = "ARG";
public static final Set<String> INTERNAL_VARS_SET = new HashSet<String>(Arrays.asList(
END, SELECTION, SELECTION_START, SELECTION_END));
@@ -381,6 +382,13 @@ public class TemplateImpl extends Template implements SchemeElement {
return false;
}
public boolean hasArgument() {
for (Variable v : myVariables) {
if (v.getName().equals(ARG)) return true;
}
return false;
}
public void setId(final String id) {
myId = id;
}
@@ -36,6 +36,7 @@ import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.util.PairProcessor;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -59,7 +60,8 @@ public class TemplateManagerImpl extends TemplateManager implements ProjectCompo
myDisposables.clear();
}
public void initComponent() { }
public void initComponent() {
}
public void projectClosed() {
}
@@ -133,12 +135,17 @@ public class TemplateManagerImpl extends TemplateManager implements ProjectCompo
startTemplate(editor, selectionString, template, null, null);
}
public void startTemplate(@NotNull Editor editor, @NotNull Template template, TemplateEditingListener listener,
public void startTemplate(@NotNull Editor editor,
@NotNull Template template,
TemplateEditingListener listener,
final PairProcessor<String, String> processor) {
startTemplate(editor, null, template, listener, processor);
}
private void startTemplate(final Editor editor, final String selectionString, final Template template, TemplateEditingListener listener,
private void startTemplate(final Editor editor,
final String selectionString,
final Template template,
TemplateEditingListener listener,
final PairProcessor<String, String> processor) {
final TemplateState templateState = initTemplateState(editor);
@@ -147,23 +154,21 @@ public class TemplateManagerImpl extends TemplateManager implements ProjectCompo
if (listener != null) {
templateState.addTemplateStateListener(listener);
}
CommandProcessor.getInstance().executeCommand(
myProject, new Runnable() {
public void run() {
if (selectionString != null) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
EditorModificationUtil.deleteSelectedText(editor);
}
});
} else {
editor.getSelectionModel().removeSelection();
}
templateState.start((TemplateImpl) template, processor);
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
public void run() {
if (selectionString != null) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
EditorModificationUtil.deleteSelectedText(editor);
}
});
}
},
CodeInsightBundle.message("insert.code.template.command"), null
);
else {
editor.getSelectionModel().removeSelection();
}
templateState.start((TemplateImpl)template, processor, null);
}
}, CodeInsightBundle.message("insert.code.template.command"), null);
if (shouldSkipInTests()) {
if (!templateState.isFinished()) templateState.gotoEnd();
@@ -178,6 +183,23 @@ public class TemplateManagerImpl extends TemplateManager implements ProjectCompo
startTemplate(editor, null, template, listener, null);
}
private static int passArgumentBack(CharSequence text, int caretOffset) {
int i = caretOffset - 1;
for (; i >= 0; i--) {
char c = text.charAt(i);
if (!Character.isJavaIdentifierPart(c)) {
break;
}
}
return i + 1;
}
private static <T, U> void addToMap(@NotNull Map<T, U> map, @NotNull Collection<? extends T> keys, U value) {
for (T key : keys) {
map.put(key, value);
}
}
public boolean startTemplate(final Editor editor, char shortcutChar, final PairProcessor<String, String> processor) {
final Document document = editor.getDocument();
PsiFile file = PsiUtilBase.getPsiFileInEditor(editor, myProject);
@@ -185,10 +207,69 @@ public class TemplateManagerImpl extends TemplateManager implements ProjectCompo
TemplateSettings templateSettings = TemplateSettings.getInstance();
CharSequence text = document.getCharsSequence();
final int caretOffset = editor.getCaretModel().getOffset();
String key = null;
List<TemplateImpl> candidatesWithoutArgument = findMatchingTemplates(text, caretOffset, shortcutChar, templateSettings, false);
int argumentOffset = passArgumentBack(text, caretOffset);
String argument = null;
if (argumentOffset >= 0) {
argument = text.subSequence(argumentOffset, caretOffset).toString();
if (argumentOffset > 0 && text.charAt(argumentOffset - 1) == ' ') {
if (argumentOffset - 2 >= 0 && Character.isJavaIdentifierPart(text.charAt(argumentOffset - 2))) {
argumentOffset--;
}
}
}
List<TemplateImpl> candidatesWithArgument = findMatchingTemplates(text, argumentOffset, shortcutChar, templateSettings, true);
if (candidatesWithArgument.isEmpty() && candidatesWithoutArgument.isEmpty()) return false;
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
public void run() {
PsiDocumentManager.getInstance(myProject).commitDocument(document);
}
}, "", null);
candidatesWithoutArgument = filterApplicableCandidates(file, caretOffset, candidatesWithoutArgument);
candidatesWithArgument = filterApplicableCandidates(file, argumentOffset, candidatesWithArgument);
Map<TemplateImpl, String> candidate2Argument = new HashMap<TemplateImpl, String>();
addToMap(candidate2Argument, candidatesWithoutArgument, null);
addToMap(candidate2Argument, candidatesWithArgument, argument);
if (candidate2Argument.isEmpty()) {
return false;
}
if (!FileDocumentManager.getInstance().requestWriting(editor.getDocument(), myProject)) {
return false;
}
if (candidate2Argument.size() == 1) {
TemplateImpl template = candidate2Argument.keySet().iterator().next();
if (candidatesWithoutArgument.size() == 1) {
int templateStart = caretOffset - template.getKey().length();
startTemplateWithPrefix(editor, template, templateStart, processor, null);
}
else {
int templateStart = argumentOffset - template.getKey().length();
startTemplateWithPrefix(editor, template, templateStart, processor, argument);
}
}
else {
ListTemplatesHandler.showTemplatesLookup(myProject, editor, candidate2Argument);
}
return true;
}
private static List<TemplateImpl> findMatchingTemplates(CharSequence text,
int caretOffset,
char shortcutChar,
TemplateSettings settings,
boolean hasArgument) {
String key;
List<TemplateImpl> candidates = Collections.emptyList();
for (int i = templateSettings.getMaxKeyLength(); i >= 1 ; i--) {
for (int i = settings.getMaxKeyLength(); i >= 1; i--) {
int wordStart = caretOffset - i;
if (wordStart < 0) {
continue;
@@ -200,63 +281,47 @@ public class TemplateManagerImpl extends TemplateManager implements ProjectCompo
}
}
candidates = templateSettings.collectMatchingCandidates(key, shortcutChar);
candidates = settings.collectMatchingCandidates(key, shortcutChar, hasArgument);
if (!candidates.isEmpty()) break;
}
if (candidates.isEmpty()) return false;
CommandProcessor.getInstance().executeCommand(
myProject, new Runnable() {
public void run() {
PsiDocumentManager.getInstance(myProject).commitDocument(document);
}
},
"", null
);
candidates = filterApplicableCandidates(file, caretOffset - key.length(), candidates);
if (candidates.isEmpty()) {
return false;
}
if (!FileDocumentManager.getInstance().requestWriting(editor.getDocument(), myProject)) {
return false;
}
if (candidates.size() == 1) {
TemplateImpl template = candidates.get(0);
startTemplateWithPrefix(editor, template, processor);
}
else {
ListTemplatesHandler.showTemplatesLookup(myProject, editor, key, candidates);
}
return true;
return candidates;
}
public void startTemplateWithPrefix(final Editor editor, final TemplateImpl template, @Nullable final PairProcessor<String, String> processor) {
public void startTemplateWithPrefix(final Editor editor,
final TemplateImpl template,
@Nullable final PairProcessor<String, String> processor,
@Nullable String argument) {
final int caretOffset = editor.getCaretModel().getOffset();
int startOffset = caretOffset - template.getKey().length();
if (argument != null) {
startOffset -= argument.length();
}
startTemplateWithPrefix(editor, template, startOffset, processor, argument);
}
public void startTemplateWithPrefix(final Editor editor,
final TemplateImpl template,
final int templateStart,
@Nullable final PairProcessor<String, String> processor,
@Nullable final String argument) {
final int caretOffset = editor.getCaretModel().getOffset();
final int wordStart = caretOffset - template.getKey().length();
final TemplateState templateState = initTemplateState(editor);
CommandProcessor commandProcessor = CommandProcessor.getInstance();
commandProcessor.executeCommand(
myProject, new Runnable() {
public void run() {
editor.getDocument().deleteString(wordStart, caretOffset);
editor.getCaretModel().moveToOffset(wordStart);
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
editor.getSelectionModel().removeSelection();
templateState.start(template, processor);
}
},
CodeInsightBundle.message("insert.code.template.command"), null
);
commandProcessor.executeCommand(myProject, new Runnable() {
public void run() {
editor.getDocument().deleteString(templateStart, caretOffset);
editor.getCaretModel().moveToOffset(templateStart);
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
editor.getSelectionModel().removeSelection();
templateState.start(template, processor, argument);
}
}, CodeInsightBundle.message("insert.code.template.command"), null);
}
private static List<TemplateImpl> filterApplicableCandidates(PsiFile file, int offset, List<TemplateImpl> candidates) {
private static List<TemplateImpl> filterApplicableCandidates(PsiFile file, int caretOffset, List<TemplateImpl> candidates) {
List<TemplateImpl> result = new ArrayList<TemplateImpl>();
for (TemplateImpl candidate : candidates) {
if (isApplicable(file, offset, candidate)) {
if (isApplicable(file, caretOffset - candidate.getKey().length(), candidate)) {
result.add(candidate);
}
}
@@ -266,16 +331,20 @@ public class TemplateManagerImpl extends TemplateManager implements ProjectCompo
public TemplateContextType getContextType(@NotNull PsiFile file, int offset) {
final TemplateContextType[] typeCollection = getAllContextTypes();
LinkedList<TemplateContextType> userDefinedExtensionsFirst = new LinkedList<TemplateContextType>();
for(TemplateContextType contextType: typeCollection) {
if (contextType.getClass().getName().startsWith("com.intellij.codeInsight.template")) userDefinedExtensionsFirst.addLast(contextType);
else userDefinedExtensionsFirst.addFirst(contextType);
for (TemplateContextType contextType : typeCollection) {
if (contextType.getClass().getName().startsWith("com.intellij.codeInsight.template")) {
userDefinedExtensionsFirst.addLast(contextType);
}
else {
userDefinedExtensionsFirst.addFirst(contextType);
}
}
for(TemplateContextType contextType: userDefinedExtensionsFirst) {
for (TemplateContextType contextType : userDefinedExtensionsFirst) {
if (contextType.isInContext(file, offset)) {
return contextType;
}
}
assert false: "OtherContextType should match any context";
assert false : "OtherContextType should match any context";
return null;
}
@@ -673,7 +673,7 @@ public class TemplateSettings implements PersistentStateComponent<Element>, Expo
return mySchemesManager.getAllSchemes();
}
public List<TemplateImpl> collectMatchingCandidates(String key, char shortcutChar) {
public List<TemplateImpl> collectMatchingCandidates(String key, char shortcutChar, boolean hasArgument) {
final Collection<TemplateImpl> templates = getTemplates(key);
List<TemplateImpl> candidates = new ArrayList<TemplateImpl>();
for (TemplateImpl template : templates) {
@@ -686,6 +686,9 @@ public class TemplateSettings implements PersistentStateComponent<Element>, Expo
if (template.isSelectionTemplate()) {
continue;
}
if (hasArgument && !template.hasArgument()) {
continue;
}
candidates.add(template);
}
return candidates;
@@ -71,6 +71,7 @@ public class TemplateState implements Disposable {
private TemplateImpl myTemplate;
private TemplateSegments mySegments = null;
private String myArgument;
private RangeMarker myTemplateRange = null;
private final ArrayList<RangeHighlighter> myTabStopHighlighters = new ArrayList<RangeHighlighter>();
@@ -106,6 +107,7 @@ public class TemplateState implements Disposable {
myCommandListener = new CommandAdapter() {
boolean started = false;
public void commandStarted(CommandEvent event) {
if (myEditor != null) {
final int offset = myEditor.getCaretModel().getOffset();
@@ -170,6 +172,9 @@ public class TemplateState implements Disposable {
if (variableName.equals(TemplateImpl.END)) {
return new TextResult("");
}
if (variableName.equals(TemplateImpl.ARG) && myArgument != null) {
return new TextResult(myArgument);
}
CharSequence text = myDocument.getCharsSequence();
int segmentNumber = myTemplate.getVariableSegmentNumber(variableName);
@@ -230,45 +235,43 @@ public class TemplateState implements Disposable {
}
}
public void start(TemplateImpl template, @Nullable final PairProcessor<String, String> processor) {
public void start(TemplateImpl template, @Nullable final PairProcessor<String, String> processor, @Nullable String argument) {
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
myProcessor = processor;
final DocumentReference[] refs = myDocument == null
? null
: new DocumentReference[] {DocumentReferenceManager.getInstance().create(myDocument) };
final DocumentReference[] refs =
myDocument == null ? null : new DocumentReference[]{DocumentReferenceManager.getInstance().create(myDocument)};
UndoManager.getInstance(myProject).undoableActionPerformed(
new UndoableAction() {
public void undo() {
if (myDocument != null) {
fireTemplateCancelled();
LookupManager.getInstance(myProject).hideActiveLookup();
int oldVar = myCurrentVariableNumber;
setCurrentVariableNumber(-1);
currentVariableChanged(oldVar);
}
}
public void redo() {
//TODO:
// throw new UnexpectedUndoException("Not implemented");
}
public DocumentReference[] getAffectedDocuments() {
return refs;
}
public boolean isGlobal() {
return false;
UndoManager.getInstance(myProject).undoableActionPerformed(new UndoableAction() {
public void undo() {
if (myDocument != null) {
fireTemplateCancelled();
LookupManager.getInstance(myProject).hideActiveLookup();
int oldVar = myCurrentVariableNumber;
setCurrentVariableNumber(-1);
currentVariableChanged(oldVar);
}
}
);
public void redo() {
//TODO:
// throw new UnexpectedUndoException("Not implemented");
}
public DocumentReference[] getAffectedDocuments() {
return refs;
}
public boolean isGlobal() {
return false;
}
});
myTemplateIndented = false;
myCurrentVariableNumber = -1;
mySegments = new TemplateSegments(myEditor);
myTemplate = template;
myArgument = argument;
if (template.isInline()) {
@@ -297,39 +300,37 @@ public class TemplateState implements Disposable {
}
private void preprocessTemplate(final PsiFile file, int caretOffset, final String textToInsert) {
for(TemplatePreprocessor preprocessor: Extensions.getExtensions(TemplatePreprocessor.EP_NAME)) {
for (TemplatePreprocessor preprocessor : Extensions.getExtensions(TemplatePreprocessor.EP_NAME)) {
preprocessor.preprocessTemplate(myEditor, file, caretOffset, textToInsert, myTemplate.getTemplateText());
}
}
private void processAllExpressions(final TemplateImpl template) {
ApplicationManager.getApplication().runWriteAction(
new Runnable() {
public void run() {
if (!template.isInline()) myDocument.insertString(myTemplateRange.getStartOffset(), template.getTemplateText());
for (int i = 0; i < template.getSegmentsCount(); i++) {
int segmentOffset = myTemplateRange.getStartOffset() + template.getSegmentOffset(i);
mySegments.addSegment(segmentOffset, segmentOffset);
}
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
if (!template.isInline()) myDocument.insertString(myTemplateRange.getStartOffset(), template.getTemplateText());
for (int i = 0; i < template.getSegmentsCount(); i++) {
int segmentOffset = myTemplateRange.getStartOffset() + template.getSegmentOffset(i);
mySegments.addSegment(segmentOffset, segmentOffset);
}
calcResults(false);
calcResults(false); //Fixed SCR #[vk500] : all variables should be recalced twice on start.
doReformat();
calcResults(false);
calcResults(false); //Fixed SCR #[vk500] : all variables should be recalced twice on start.
doReformat();
int nextVariableNumber = getNextVariableNumber(-1);
if (nextVariableNumber == -1) {
finishTemplateEditing();
}
else {
setCurrentVariableNumber(nextVariableNumber);
initTabStopHighlighters();
initListeners();
focusCurrentExpression();
currentVariableChanged(-1);
}
int nextVariableNumber = getNextVariableNumber(-1);
if (nextVariableNumber == -1) {
finishTemplateEditing();
}
else {
setCurrentVariableNumber(nextVariableNumber);
initTabStopHighlighters();
initListeners();
focusCurrentExpression();
currentVariableChanged(-1);
}
}
);
});
}
private void doReformat() {
@@ -352,7 +353,7 @@ public class TemplateState implements Disposable {
if (file != null) {
IntArrayList indices = initEmptyVariables();
mySegments.setSegmentsGreedy(false);
for(TemplateOptionalProcessor processor: Extensions.getExtensions(TemplateOptionalProcessor.EP_NAME)) {
for (TemplateOptionalProcessor processor : Extensions.getExtensions(TemplateOptionalProcessor.EP_NAME)) {
processor.processText(myProject, myTemplate, myDocument, myTemplateRange, myEditor);
}
mySegments.setSegmentsGreedy(true);
@@ -371,7 +372,8 @@ public class TemplateState implements Disposable {
setCurrentVariableNumber(-1);
currentVariableChanged(oldIndex);
fireTemplateCancelled();
} else {
}
else {
calcResults(true);
}
myDocumentChanged = false;
@@ -427,15 +429,16 @@ public class TemplateState implements Disposable {
final String s = lookupItems[0].getLookupString();
EditorModificationUtil.insertStringAtCaret(myEditor, s);
itemSelected(lookupItems[0], psiFile, currentSegmentNumber, ' ', lookupItems);
} else {
}
else {
runLookup(currentSegmentNumber, lookupItems, psiFile);
}
}
else {
Result result = expressionNode.calculateResult(context);
if (result != null) {
result.handleFocused(psiFile, myDocument,
mySegments.getSegmentStart(currentSegmentNumber), mySegments.getSegmentEnd(currentSegmentNumber));
result.handleFocused(psiFile, myDocument, mySegments.getSegmentStart(currentSegmentNumber),
mySegments.getSegmentEnd(currentSegmentNumber));
}
}
focusCurrentHighlighter(true);
@@ -465,7 +468,11 @@ public class TemplateState implements Disposable {
});
}
private void itemSelected(final LookupElement item, final PsiFile psiFile, final int currentSegmentNumber, final char completionChar, LookupElement[] elements) {
private void itemSelected(final LookupElement item,
final PsiFile psiFile,
final int currentSegmentNumber,
final char completionChar,
LookupElement[] elements) {
if (item != null) {
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
@@ -490,11 +497,13 @@ public class TemplateState implements Disposable {
PsiDocumentManager.getInstance(myProject).commitDocument(myDocument);
}
final TemplateLookupSelectionHandler handler = item instanceof LookupItem ? ((LookupItem<?>)item).getAttribute(TemplateLookupSelectionHandler.KEY_IN_LOOKUP_ITEM) : null;
final TemplateLookupSelectionHandler handler =
item instanceof LookupItem ? ((LookupItem<?>)item).getAttribute(TemplateLookupSelectionHandler.KEY_IN_LOOKUP_ITEM) : null;
if (handler != null) {
handler.itemSelected(item, psiFile, myDocument,
mySegments.getSegmentStart(currentSegmentNumber), mySegments.getSegmentEnd(currentSegmentNumber));
} else {
handler.itemSelected(item, psiFile, myDocument, mySegments.getSegmentStart(currentSegmentNumber),
mySegments.getSegmentEnd(currentSegmentNumber));
}
else {
new WriteCommandAction(myProject) {
protected void run(com.intellij.openapi.application.Result result) throws Throwable {
item.handleInsert(context);
@@ -533,45 +542,43 @@ public class TemplateState implements Disposable {
}
}
ApplicationManager.getApplication().runWriteAction(
new Runnable() {
public void run() {
BitSet calcedSegments = new BitSet();
int maxAttempts = (myTemplate.getVariableCount()+1)*3;
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
BitSet calcedSegments = new BitSet();
int maxAttempts = (myTemplate.getVariableCount() + 1) * 3;
do {
maxAttempts--;
calcedSegments.clear();
for (int i = myCurrentVariableNumber + 1; i < myTemplate.getVariableCount(); i++) {
String variableName = myTemplate.getVariableNameAt(i);
int segmentNumber = myTemplate.getVariableSegmentNumber(variableName);
if (segmentNumber < 0) continue;
Expression expression = myTemplate.getExpressionAt(i);
Expression defaultValue = myTemplate.getDefaultValueAt(i);
String oldValue = getVariableValue(variableName).getText();
recalcSegment(segmentNumber, isQuick, expression, defaultValue);
final TextResult value = getVariableValue(variableName);
assert value != null : "name=" + variableName + "\ntext=" + myTemplate.getTemplateText();
String newValue = value.getText();
if (!newValue.equals(oldValue)) {
calcedSegments.set(segmentNumber);
}
do {
maxAttempts--;
calcedSegments.clear();
for (int i = myCurrentVariableNumber + 1; i < myTemplate.getVariableCount(); i++) {
String variableName = myTemplate.getVariableNameAt(i);
int segmentNumber = myTemplate.getVariableSegmentNumber(variableName);
if (segmentNumber < 0) continue;
Expression expression = myTemplate.getExpressionAt(i);
Expression defaultValue = myTemplate.getDefaultValueAt(i);
String oldValue = getVariableValue(variableName).getText();
recalcSegment(segmentNumber, isQuick, expression, defaultValue);
final TextResult value = getVariableValue(variableName);
assert value != null : "name=" + variableName + "\ntext=" + myTemplate.getTemplateText();
String newValue = value.getText();
if (!newValue.equals(oldValue)) {
calcedSegments.set(segmentNumber);
}
}
for (int i = 0; i < myTemplate.getSegmentsCount(); i++) {
if (!calcedSegments.get(i)) {
String variableName = myTemplate.getSegmentName(i);
String newValue = getVariableValue(variableName).getText();
int start = mySegments.getSegmentStart(i);
int end = mySegments.getSegmentEnd(i);
replaceString(newValue, start, end, i);
}
for (int i = 0; i < myTemplate.getSegmentsCount(); i++) {
if (!calcedSegments.get(i)) {
String variableName = myTemplate.getSegmentName(i);
String newValue = getVariableValue(variableName).getText();
int start = mySegments.getSegmentStart(i);
int end = mySegments.getSegmentEnd(i);
replaceString(newValue, start, end, i);
}
}
while (!calcedSegments.isEmpty() && maxAttempts >= 0);
}
while (!calcedSegments.isEmpty() && maxAttempts >= 0);
}
);
});
}
private void recalcSegment(int segmentNumber, boolean isQuick, Expression expressionNode, Expression defaultValue) {
@@ -615,8 +622,8 @@ public class TemplateState implements Disposable {
if (result instanceof RecalculatableResult) {
shortenReferences();
PsiDocumentManager.getInstance(myProject).commitDocument(myDocument);
((RecalculatableResult) result).handleRecalc(psiFile, myDocument,
mySegments.getSegmentStart(segmentNumber), mySegments.getSegmentEnd(segmentNumber));
((RecalculatableResult)result)
.handleRecalc(psiFile, myDocument, mySegments.getSegmentStart(segmentNumber), mySegments.getSegmentEnd(segmentNumber));
}
}
@@ -632,11 +639,9 @@ public class TemplateState implements Disposable {
mySegments.setNeighboursGreedy(segmentNumber, true);
if (segmentNumberWithTheSameStart != -1) {
mySegments.replaceSegmentAt(
segmentNumberWithTheSameStart,
newEnd,
newEnd + mySegments.getSegmentEnd(segmentNumberWithTheSameStart) - mySegments.getSegmentStart(segmentNumberWithTheSameStart)
);
mySegments.replaceSegmentAt(segmentNumberWithTheSameStart, newEnd,
newEnd + mySegments.getSegmentEnd(segmentNumberWithTheSameStart) -
mySegments.getSegmentStart(segmentNumberWithTheSameStart));
}
}
}
@@ -723,7 +728,7 @@ public class TemplateState implements Disposable {
}
public <T> T getProperty(Key<T> key) {
return (T) myProperties.get(key);
return (T)myProperties.get(key);
}
};
}
@@ -743,7 +748,8 @@ public class TemplateState implements Disposable {
int offset = -1;
if (endSegmentNumber >= 0) {
offset = mySegments.getSegmentStart(endSegmentNumber);
} else {
}
else {
if (!myTemplate.isSelectionTemplate() && !myTemplate.isInline()) { //do not move caret to the end of range for selection templates
offset = myTemplateRange.getEndOffset();
}
@@ -758,10 +764,7 @@ public class TemplateState implements Disposable {
int selStart = myTemplate.getSelectionStartSegmentNumber();
int selEnd = myTemplate.getSelectionEndSegmentNumber();
if (selStart >= 0 && selEnd >= 0) {
myEditor.getSelectionModel().setSelection(
mySegments.getSegmentStart(selStart),
mySegments.getSegmentStart(selEnd)
);
myEditor.getSelectionModel().setSelection(mySegments.getSegmentStart(selStart), mySegments.getSegmentStart(selEnd));
}
fireBeforeTemplateFinished();
final Editor editor = myEditor;
@@ -797,10 +800,12 @@ public class TemplateState implements Disposable {
if (expression == null) {
return false;
}
if (myTemplate.isAlwaysStopAt(currentVariableNumber)) {
return true;
}
String variableName = myTemplate.getVariableNameAt(currentVariableNumber);
if (!(TemplateImpl.ARG.equals(variableName) && myArgument != null)) {
if (myTemplate.isAlwaysStopAt(currentVariableNumber)) {
return true;
}
}
int segmentNumber = myTemplate.getVariableSegmentNumber(variableName);
if (segmentNumber < 0) return false;
int start = mySegments.getSegmentStart(segmentNumber);
@@ -867,9 +872,7 @@ public class TemplateState implements Disposable {
}
private RangeHighlighter getSegmentHighlighter(int segmentNumber, boolean isSelected, boolean isEnd) {
TextAttributes attributes = isSelected
? new TextAttributes(null, null, Color.red, EffectType.BOXED, Font.PLAIN)
: new TextAttributes();
TextAttributes attributes = isSelected ? new TextAttributes(null, null, Color.red, EffectType.BOXED, Font.PLAIN) : new TextAttributes();
TextAttributes endAttributes = new TextAttributes();
RangeHighlighter segmentHighlighter;
@@ -880,8 +883,8 @@ public class TemplateState implements Disposable {
.addRangeHighlighter(start, end, HighlighterLayer.LAST + 1, endAttributes, HighlighterTargetArea.EXACT_RANGE);
}
else {
segmentHighlighter = myEditor.getMarkupModel()
.addRangeHighlighter(start, end, HighlighterLayer.LAST + 1, attributes, HighlighterTargetArea.EXACT_RANGE);
segmentHighlighter =
myEditor.getMarkupModel().addRangeHighlighter(start, end, HighlighterLayer.LAST + 1, attributes, HighlighterTargetArea.EXACT_RANGE);
}
segmentHighlighter.setGreedyToLeft(true);
segmentHighlighter.setGreedyToRight(true);
@@ -910,7 +913,7 @@ public class TemplateState implements Disposable {
final PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(myDocument);
if (file != null) {
CodeStyleManager style = CodeStyleManager.getInstance(myProject);
for(TemplateOptionalProcessor optionalProcessor : Extensions.getExtensions(TemplateOptionalProcessor.EP_NAME)) {
for (TemplateOptionalProcessor optionalProcessor : Extensions.getExtensions(TemplateOptionalProcessor.EP_NAME)) {
optionalProcessor.processText(myProject, myTemplate, myDocument, myTemplateRange, myEditor);
}
if (myTemplate.isToReformat()) {
@@ -921,7 +924,7 @@ public class TemplateState implements Disposable {
if (endSegmentNumber >= 0) {
int endVarOffset = mySegments.getSegmentStart(endSegmentNumber);
PsiElement marker = style.insertNewLineIndentMarker(file, endVarOffset);
if(marker != null) rangeMarker = myDocument.createRangeMarker(marker.getTextRange());
if (marker != null) rangeMarker = myDocument.createRangeMarker(marker.getTextRange());
}
style.reformatText(file, myTemplateRange.getStartOffset(), myTemplateRange.getEndOffset());
PsiDocumentManager.getInstance(myProject).commitDocument(myDocument);
@@ -254,6 +254,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
boolean completed = JobUtil.invokeConcurrentlyUnderMyProgress(new ArrayList<PsiFile>(fileSet), new Processor<PsiFile>() {
public boolean process(final PsiFile file) {
if (file instanceof PsiBinaryFile) return true;
file.getViewProvider().getContents(); // load contents outside readaction
ApplicationManager.getApplication().runReadAction(new Runnable() {
public void run() {
try {
@@ -73,7 +73,7 @@ public abstract class Task implements TaskInfo {
return myTitle;
}
public final Task setTitle(final String title) {
public final Task setTitle(@NotNull String title) {
myTitle = title;
return this;
}
@@ -347,6 +347,9 @@ public class VfsUtil {
if (file == null && uri.contains(JarFileSystem.JAR_SEPARATOR)) {
file = JarFileSystem.getInstance().findFileByPath(uri);
if (file == null && base == null) {
file = VirtualFileManager.getInstance().findFileByUrl(uri);
}
}
if (file == null) {
@@ -0,0 +1,117 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
*
* 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 com.intellij.ide.actions;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.wm.IdeFrame;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.openapi.wm.ex.WindowManagerEx;
import javax.swing.*;
import java.awt.*;
public abstract class WindowAction extends AnAction {
public static final String NO_WINDOW_ACTIONS = "no.window.actions";
protected Window myWindow;
private static JLabel mySizeHelper = new JLabel("W");
{
setEnabledInModalContext(true);
}
@Override
public final void update(AnActionEvent e) {
Window wnd = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow();
e.getPresentation().setEnabled(wnd != null && !(wnd instanceof IdeFrame));
Object noActions = null;
if (wnd instanceof JDialog) {
noActions = ((JDialog)wnd).getRootPane().getClientProperty(NO_WINDOW_ACTIONS);
} else if (wnd instanceof JFrame) {
noActions = ((JFrame)wnd).getRootPane().getClientProperty(NO_WINDOW_ACTIONS);
}
if (noActions != null && "true".equalsIgnoreCase(noActions.toString())) {
e.getPresentation().setEnabled(false);
}
if (e.getPresentation().isEnabled()) {
myWindow = wnd;
} else {
myWindow = null;
}
}
public abstract static class BaseSizeAction extends WindowAction {
private boolean myHorizontal;
private boolean myPositive;
protected BaseSizeAction(boolean horizontal, boolean positive) {
myHorizontal = horizontal;
myPositive = positive;
}
@Override
public void actionPerformed(AnActionEvent e) {
int baseValue = myHorizontal ? mySizeHelper.getPreferredSize().width : mySizeHelper.getPreferredSize().height;
int inc = baseValue * (myHorizontal ? Registry.intValue("ide.windowSystem.hScrollChars") : Registry.intValue("ide.windowSystem.vScrollChars"));
if (!myPositive) {
inc = -inc;
}
Rectangle bounds = myWindow.getBounds();
if (myHorizontal) {
bounds.width += inc;
} else {
bounds.height += inc;
}
myWindow.setBounds(bounds);
}
}
public static class IncrementWidth extends BaseSizeAction {
public IncrementWidth() {
super(true, true);
}
}
public static class DecrementWidth extends BaseSizeAction {
public DecrementWidth() {
super(true, false);
}
}
public static class IncrementHeight extends BaseSizeAction {
public IncrementHeight() {
super(false, true);
}
}
public static class DecrementHeight extends BaseSizeAction {
public DecrementHeight() {
super(false, false);
}
}
}
@@ -301,6 +301,8 @@ public class KeymapImpl implements Keymap, ExternalizableScheme {
}
private THashMap<KeyStroke,ArrayList<String>> getKeystroke2ListOfIds() {
myKeystroke2ListOfIds = null;
if (myKeystroke2ListOfIds == null) {
myKeystroke2ListOfIds = new THashMap<KeyStroke, ArrayList<String>>();
fillKeystroke2ListOfIds(myKeystroke2ListOfIds, KeyboardShortcut.class);
@@ -708,6 +708,10 @@ action.ResizeToolWindowUp.text=Stretch to Top
action.ResizeToolWindowUp.description=Resize active tool window to the top
action.ResizeToolWindowDown.text=Stretch to Bottom
action.ResizeToolWindowDown.description=Resize active tool window to the bottom
action.IncrementWindowWidth.text=Increment Width
action.DecrementWindowWidth.text=Decrement Width
action.IncrementWindowHeight.text=Increment Height
action.DecrementWindowHeight.text=Decrement Height
action.NextTab.text=Select Ne_xt Tab
action.NextTab.description=Activate next tab
action.PreviousTab.text=Se_lect Previous Tab
@@ -402,5 +402,10 @@
</group>
<action id="Rerun" class="com.intellij.execution.runners.FakeRerunAction" text="Rerun"/>
<action id="IncrementWindowWidth" class="com.intellij.ide.actions.WindowAction$IncrementWidth" use-shortcut-of="ResizeToolWindowRight"/>
<action id="DecrementWindowWidth" class="com.intellij.ide.actions.WindowAction$DecrementWidth" use-shortcut-of="ResizeToolWindowLeft"/>
<action id="IncrementWindowHeight" class="com.intellij.ide.actions.WindowAction$IncrementHeight" use-shortcut-of="ResizeToolWindowDown"/>
<action id="DecrementWindowHeight" class="com.intellij.ide.actions.WindowAction$DecrementHeight" use-shortcut-of="ResizeToolWindowUp"/>
</actions>
</component>
@@ -18,6 +18,7 @@ package com.intellij;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.PropertyKey;
@@ -51,7 +52,7 @@ public class CommonBundle {
return bundle;
}
public static String messageOrDefault(@Nullable final ResourceBundle bundle, final String key, final @Nullable String defaultValue, final Object... params) {
public static String messageOrDefault(@Nullable final ResourceBundle bundle, final String key, @Nullable final String defaultValue, final Object... params) {
if (bundle == null) return defaultValue;
String value;
@@ -64,7 +65,7 @@ public class CommonBundle {
} else {
value = "!" + key + "!";
if (assertKeyIsFound) {
assert false: key + " is not found";
assert false: key + " is not found in "+BUNDLE;
}
}
}
@@ -82,6 +83,7 @@ public class CommonBundle {
return messageOrDefault(bundle, key, null, params);
}
@NotNull
public static String getCancelButtonText() {
return message("button.cancel");
}
@@ -39,15 +39,10 @@ import org.jetbrains.plugins.groovy.codeInspection.GroovyImportsTracker;
import org.jetbrains.plugins.groovy.config.GroovyConfigUtils;
import org.jetbrains.plugins.groovy.highlighter.DefaultHighlighter;
import org.jetbrains.plugins.groovy.intentions.utils.DuplicatesUtil;
import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocComment;
import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocMemberReference;
import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocReferenceElement;
import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.*;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.lexer.TokenSets;
import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.*;
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList;
@@ -86,9 +81,11 @@ import java.util.*;
/**
* @author ven
*/
public class GroovyAnnotator implements Annotator {
public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
private static final Logger LOG = Logger.getInstance("org.jetbrains.plugins.groovy.annotator.GroovyAnnotator");
private AnnotationHolder myHolder;
private static boolean isDocCommentElement(PsiElement element) {
if (element == null) return false;
ASTNode node = element.getNode();
@@ -96,87 +93,21 @@ public class GroovyAnnotator implements Annotator {
}
public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) {
if (element instanceof GrCodeReferenceElement) {
checkReferenceElement(holder, (GrCodeReferenceElement)element);
if (element instanceof GroovyPsiElement) {
myHolder = holder;
((GroovyPsiElement)element).accept(this);
myHolder = null;
}
else if (element instanceof GrReferenceExpression) {
checkReferenceExpression(holder, (GrReferenceExpression)element);
}
else if (element instanceof GrTypeDefinition) {
final GrTypeDefinition typeDefinition = (GrTypeDefinition)element;
checkTypeDefinition(holder, typeDefinition);
checkTypeDefinitionModifiers(holder, typeDefinition);
final GrTypeDefinitionBody body = typeDefinition.getBody();
if (body != null) checkDuplicateMethod(body.getGroovyMethods(), holder);
checkImplementedMethodsOfClass(holder, typeDefinition);
}
else if (element instanceof GrMethod) {
final GrMethod method = (GrMethod)element;
checkMethodDefinitionModifiers(holder, method);
checkInnerMethod(holder, method);
}
else if (element instanceof GrVariableDeclaration) {
checkVariableDeclaration(holder, (GrVariableDeclaration)element);
}
else if (element instanceof GrVariable) {
if (element instanceof GrMember) {
highlightMember(holder, ((GrMember)element));
checkStaticDeclarationsInInnerClass((GrMember)element, holder);
}
checkVariable(holder, (GrVariable)element);
}
else if (element instanceof GrAssignmentExpression) {
checkAssignmentExpression((GrAssignmentExpression)element, holder);
}
else if (element instanceof GrReturnStatement) {
checkReturnStatement((GrReturnStatement)element, holder);
}
else if (element instanceof GrListOrMap) {
checkMap(((GrListOrMap)element).getNamedArguments(), holder);
}
else if (element instanceof GrNewExpression) {
checkNewExpression(holder, (GrNewExpression)element);
}
else if (element instanceof GrDocMemberReference) {
checkGrDocMemberReference((GrDocMemberReference)element, holder);
}
else if (element instanceof GrConstructorInvocation) {
checkConstructorInvocation(holder, (GrConstructorInvocation)element);
}
else if (element instanceof GrFlowInterruptingStatement) {
checkFlowInterruptStatement(((GrFlowInterruptingStatement)element), holder);
} else if (element instanceof GrLabeledStatement) {
checkLabeledStatement(((GrLabeledStatement) element), holder);
}
else if (element.getParent() instanceof GrDocReferenceElement) {
checkGrDocReferenceElement(holder, element);
}
else if (element instanceof GrPackageDefinition) {
//todo: if reference isn't resolved it construct package definition
checkPackageReference(holder, (GrPackageDefinition)element);
}
else if (element instanceof GrThisReferenceExpression || element instanceof GrSuperReferenceExpression) {
checkThisOrSuperReferenceExpression(((GrExpression)element), holder);
}
else if (element instanceof GrLiteral) {
checkLiteral(((GrLiteral)element), holder);
}
else if (element instanceof GrForInClause) {
checkForInClause(((GrForInClause)element), holder);
}
else if (element instanceof GroovyFile) {
final GroovyFile file = (GroovyFile)element;
if (file.isScript()) {
checkScriptDuplicateMethod(file.getTopLevelDefinitions(), holder);
}
}
else if (element instanceof GrImportStatement) {
checkAnnotationList(holder, ((GrImportStatement)element).getAnnotationList(), GroovyBundle.message("import.statement.cannot.have.modifiers"));
}
@Override
public void visitElement(GroovyPsiElement element) {
if (element.getParent() instanceof GrDocReferenceElement) {
checkGrDocReferenceElement(myHolder, element);
}
else {
final ASTNode node = element.getNode();
if (node != null &&
!(element instanceof PsiWhiteSpace) &&
if (!(element instanceof PsiWhiteSpace) &&
!GroovyTokenTypes.COMMENT_SET.contains(node.getElementType()) &&
element.getContainingFile() instanceof GroovyFile &&
!isDocCommentElement(element)) {
@@ -185,7 +116,377 @@ public class GroovyAnnotator implements Annotator {
}
}
private static void checkForInClause(GrForInClause forInClause, AnnotationHolder holder) {
@Override
public void visitCodeReferenceElement(GrCodeReferenceElement refElement) {
final PsiElement parent = refElement.getParent();
GroovyResolveResult resolveResult = refElement.advancedResolve();
highlightAnnotation(myHolder, refElement, resolveResult);
registerUsedImport(refElement, resolveResult);
highlightAnnotation(myHolder, refElement, resolveResult);
if (refElement.getReferenceName() != null) {
if (parent instanceof GrImportStatement && ((GrImportStatement)parent).isStatic() && refElement.multiResolve(false).length > 0) {
return;
}
checkSingleResolvedElement(myHolder, refElement, resolveResult);
}
}
@Override
public void visitReferenceExpression(GrReferenceExpression referenceExpression) {
GroovyResolveResult resolveResult = referenceExpression.advancedResolve();
GroovyResolveResult[] results = referenceExpression.multiResolve(false); //cached
for (GroovyResolveResult result : results) {
registerUsedImport(referenceExpression, result);
}
PsiElement resolved = resolveResult.getElement();
final PsiElement parent = referenceExpression.getParent();
if (resolved != null) {
if (resolved instanceof PsiMember) {
highlightMemberResolved(myHolder, referenceExpression, ((PsiMember)resolved));
}
if (!resolveResult.isAccessible()) {
String message = GroovyBundle.message("cannot.access", referenceExpression.getReferenceName());
myHolder.createWarningAnnotation(referenceExpression.getReferenceNameElement(), message);
}
if (!resolveResult.isStaticsOK() && resolved instanceof PsiModifierListOwner) {
if (!((PsiModifierListOwner)resolved).hasModifierProperty(PsiModifier.STATIC)) {
myHolder.createWarningAnnotation(referenceExpression, GroovyBundle.message("cannot.reference.nonstatic", referenceExpression.getReferenceName()));
}
}
}
else {
GrExpression qualifier = referenceExpression.getQualifierExpression();
if (qualifier == null && isDeclarationAssignment(referenceExpression)) return;
if (parent instanceof GrReferenceExpression && "class".equals(((GrReferenceExpression)parent).getReferenceName())) {
checkSingleResolvedElement(myHolder, referenceExpression, resolveResult);
}
}
if (parent instanceof GrCall) {
if (resolved == null && results.length > 0) {
resolved = results[0].getElement();
resolveResult = results[0];
}
if (resolved instanceof PsiMethod && resolved.getUserData(GrMethod.BUILDER_METHOD) == null) {
checkMethodApplicability(resolveResult, referenceExpression, myHolder);
}
else {
checkClosureApplicability(resolveResult, referenceExpression.getType(), referenceExpression, myHolder);
}
}
if (isDeclarationAssignment(referenceExpression) || resolved instanceof PsiPackage) return;
if (resolved == null) {
PsiElement refNameElement = referenceExpression.getReferenceNameElement();
PsiElement elt = refNameElement == null ? referenceExpression : refNameElement;
Annotation annotation = myHolder.createInfoAnnotation(elt, null);
final GrExpression qualifier = referenceExpression.getQualifierExpression();
if (qualifier == null) {
if (!(parent instanceof GrCall)) {
registerCreateClassByTypeFix(referenceExpression, annotation);
registerAddImportFixes(referenceExpression, annotation);
}
} else {
if (qualifier.getType() == null) {
return;
}
}
registerReferenceFixes(referenceExpression, annotation);
annotation.setTextAttributes(DefaultHighlighter.UNRESOLVED_ACCESS);
}
}
@Override
public void visitTypeDefinition(GrTypeDefinition typeDefinition) {
checkTypeDefinition(myHolder, typeDefinition);
checkTypeDefinitionModifiers(myHolder, typeDefinition);
final GrTypeDefinitionBody body = typeDefinition.getBody();
if (body != null) checkDuplicateMethod(body.getGroovyMethods(), myHolder);
checkImplementedMethodsOfClass(myHolder, typeDefinition);
}
@Override
public void visitMethod(GrMethod method) {
checkMethodDefinitionModifiers(myHolder, method);
checkInnerMethod(myHolder, method);
}
@Override
public void visitVariableDeclaration(GrVariableDeclaration variableDeclaration) {
PsiElement parent = variableDeclaration.getParent();
assert parent != null;
PsiElement typeDef = parent.getParent();
if (typeDef != null && typeDef instanceof GrTypeDefinition) {
PsiModifierList modifiersList = variableDeclaration.getModifierList();
checkAccessModifiers(myHolder, modifiersList);
if (modifiersList.hasExplicitModifier(PsiModifier.VOLATILE) && modifiersList.hasExplicitModifier(PsiModifier.FINAL)) {
myHolder.createErrorAnnotation(modifiersList, GroovyBundle.message("illegal.combination.of.modifiers.volatile.and.final"));
}
if (modifiersList.hasExplicitModifier(PsiModifier.NATIVE)) {
myHolder.createErrorAnnotation(modifiersList, GroovyBundle.message("variable.cannot.be.native"));
}
if (modifiersList.hasExplicitModifier(PsiModifier.ABSTRACT)) {
myHolder.createErrorAnnotation(modifiersList, GroovyBundle.message("variable.cannot.be.abstract"));
}
}
}
@Override
public void visitVariable(GrVariable variable) {
if (variable instanceof GrMember) {
highlightMember(myHolder, ((GrMember)variable));
checkStaticDeclarationsInInnerClass((GrMember)variable, myHolder);
}
PropertyResolverProcessor processor = new DuplicateVariablesProcessor(variable);
final GroovyPsiElement duplicate =
ResolveUtil.resolveExistingElement(variable, processor, GrVariable.class, GrReferenceExpression.class);
if (duplicate instanceof GrVariable) {
if (duplicate instanceof GrField && !(variable instanceof GrField)) {
myHolder
.createWarningAnnotation(variable.getNameIdentifierGroovy(), GroovyBundle.message("field.already.defined", variable.getName()));
}
else {
final String key = duplicate instanceof GrField ? "field.already.defined" : "variable.already.defined";
myHolder.createErrorAnnotation(variable.getNameIdentifierGroovy(), GroovyBundle.message(key, variable.getName()));
}
}
}
@Override
public void visitAssignmentExpression(GrAssignmentExpression expression) {
GrExpression lValue = expression.getLValue();
if (!PsiUtil.mightBeLVlaue(lValue)) {
myHolder.createErrorAnnotation(lValue, GroovyBundle.message("invalid.lvalue"));
}
}
@Override
public void visitReturnStatement(GrReturnStatement returnStatement) {
final GrExpression value = returnStatement.getReturnValue();
if (value != null) {
final PsiType type = value.getType();
if (type != null) {
final GrParametersOwner owner = PsiTreeUtil.getParentOfType(returnStatement, GrMethod.class, GrClosableBlock.class);
if (owner instanceof PsiMethod) {
final PsiMethod method = (PsiMethod)owner;
if (method.isConstructor()) {
myHolder.createErrorAnnotation(value, GroovyBundle.message("cannot.return.from.constructor"));
}
else {
final PsiType methodType = method.getReturnType();
if (methodType != null) {
if (PsiType.VOID.equals(methodType)) {
myHolder.createErrorAnnotation(value, GroovyBundle.message("cannot.return.from.void.method"));
}
}
}
}
}
}
}
@Override
public void visitListOrMap(GrListOrMap listOrMap) {
final Map<GrNamedArgument, List<GrNamedArgument>> map = DuplicatesUtil.factorDuplicates(listOrMap.getNamedArguments(), new TObjectHashingStrategy<GrNamedArgument>() {
public int computeHashCode(GrNamedArgument arg) {
final GrArgumentLabel label = arg.getLabel();
if (label == null) return 0;
final String name = label.getName();
if (name == null) return 0;
return name.hashCode();
}
public boolean equals(GrNamedArgument arg1, GrNamedArgument arg2) {
final GrArgumentLabel label1 = arg1.getLabel();
final GrArgumentLabel label2 = arg2.getLabel();
if (label1 == null || label2 == null) {
return label1 == null && label2 == null;
}
final String name1 = label1.getName();
final String name2 = label2.getName();
if (name1 == null || name2 == null) {
return name1 == null && name2 == null;
}
return name1.equals(name2);
}
});
processDuplicates(map, myHolder);
}
@Override
public void visitNewExpression(GrNewExpression newExpression) {
if (newExpression.getArrayCount() > 0) return;
GrCodeReferenceElement refElement = newExpression.getReferenceElement();
if (refElement == null) return;
final PsiElement element = refElement.resolve();
if (element instanceof PsiClass) {
PsiClass clazz = (PsiClass)element;
if (clazz.hasModifierProperty(PsiModifier.ABSTRACT)) {
if (newExpression.getAnonymousClassDefinition() == null) {
String message = clazz.isInterface()
? GroovyBundle.message("cannot.instantiate.interface", clazz.getName())
: GroovyBundle.message("cannot.instantiate.abstract.class", clazz.getName());
myHolder.createErrorAnnotation(refElement, message);
}
return;
}
if (newExpression.getQualifier() != null) {
if (clazz.hasModifierProperty(PsiModifier.STATIC)) {
myHolder.createErrorAnnotation(newExpression, GroovyBundle.message("qualified.new.of.static.class"));
}
} else {
final PsiClass outerClass = clazz.getContainingClass();
if (com.intellij.psi.util.PsiUtil.isInnerClass(clazz) && !PsiUtil.hasEnclosingInstanceInScope(outerClass, newExpression, true)) {
myHolder.createErrorAnnotation(newExpression, GroovyBundle.message("cannot.reference.nonstatic", clazz.getQualifiedName()));
}
}
}
final GroovyResolveResult constructorResolveResult = newExpression.resolveConstructorGenerics();
if (constructorResolveResult.getElement() != null) {
checkMethodApplicability(constructorResolveResult, refElement, myHolder);
final GrArgumentList argList = newExpression.getArgumentList();
if (argList != null && argList.getExpressionArguments().length == 0) checkDefaultMapConstructor(myHolder, argList);
}
else {
final GroovyResolveResult[] results = newExpression.multiResolveConstructor();
final GrArgumentList argList = newExpression.getArgumentList();
PsiElement toHighlight = argList != null ? argList : refElement.getReferenceNameElement();
if (results.length > 0) {
String message = GroovyBundle.message("ambiguous.constructor.call");
myHolder.createWarningAnnotation(toHighlight, message);
}
else {
if (element instanceof PsiClass) {
//default constructor invocation
PsiType[] argumentTypes = PsiUtil.getArgumentTypes(refElement, true, true);
if (argumentTypes != null && argumentTypes.length > 0) {
String message = GroovyBundle.message("cannot.find.default.constructor", ((PsiClass)element).getName());
myHolder.createWarningAnnotation(toHighlight, message);
}
else checkDefaultMapConstructor(myHolder, argList);
}
}
}
}
@Override
public void visitDocMethodReference(GrDocMethodReference reference) {
checkGrDocMemberReference(reference, myHolder);
}
@Override
public void visitDocFieldReference(GrDocFieldReference reference) {
checkGrDocMemberReference(reference, myHolder);
}
@Override
public void visitConstructorInvocation(GrConstructorInvocation invocation) {
final GroovyResolveResult resolveResult = invocation.resolveConstructorGenerics();
if (resolveResult != null) {
checkMethodApplicability(resolveResult, invocation.getThisOrSuperKeyword(), myHolder);
}
else {
final GroovyResolveResult[] results = invocation.multiResolveConstructor();
final GrArgumentList argList = invocation.getArgumentList();
if (results.length > 0) {
String message = GroovyBundle.message("ambiguous.constructor.call");
myHolder.createWarningAnnotation(argList, message);
}
else {
final PsiClass clazz = invocation.getDelegatedClass();
if (clazz != null) {
//default constructor invocation
PsiType[] argumentTypes = PsiUtil.getArgumentTypes(invocation.getThisOrSuperKeyword(), true, true);
if (argumentTypes != null && argumentTypes.length > 0) {
String message = GroovyBundle.message("cannot.find.default.constructor", clazz.getName());
myHolder.createWarningAnnotation(argList, message);
}
}
}
}
}
@Override
public void visitBreakStatement(GrBreakStatement breakStatement) {
checkFlowInterruptStatement(breakStatement, myHolder);
}
@Override
public void visitContinueStatement(GrContinueStatement continueStatement) {
checkFlowInterruptStatement(continueStatement, myHolder);
}
@Override
public void visitLabeledStatement(GrLabeledStatement labeledStatement) {
final String name = labeledStatement.getLabelName();
if (ResolveUtil.resolveLabeledStatement(name, labeledStatement, true) != null) {
myHolder.createWarningAnnotation(labeledStatement.getLabel(), GroovyBundle.message("label.already.used", name));
}
}
@Override
public void visitPackageDefinition(GrPackageDefinition packageDefinition) {
//todo: if reference isn't resolved it construct package definition
final PsiFile file = packageDefinition.getContainingFile();
assert file != null;
PsiDirectory psiDirectory = file.getContainingDirectory();
if (psiDirectory != null) {
PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(psiDirectory);
if (aPackage != null) {
String packageName = aPackage.getQualifiedName();
if (!packageDefinition.getPackageName().equals(packageName)) {
final Annotation annotation = myHolder.createWarningAnnotation(packageDefinition, "wrong package name");
annotation.registerFix(new ChangePackageQuickFix((GroovyFile)packageDefinition.getContainingFile(), packageName));
}
}
}
final GrModifierList modifierList = packageDefinition.getAnnotationList();
checkAnnotationList(myHolder, modifierList, GroovyBundle.message("package.definition.cannot.have.modifiers"));
}
@Override
public void visitSuperExpression(GrSuperReferenceExpression superExpression) {
checkThisOrSuperReferenceExpression(superExpression, myHolder);
}
@Override
public void visitThisExpression(GrThisReferenceExpression thisExpression) {
checkThisOrSuperReferenceExpression(thisExpression, myHolder);
}
@Override
public void visitLiteralExpression(GrLiteral literal) {
String text = literal.getText();
if (text.startsWith("'''")) {
if (text.length() < 6 || !text.endsWith("'''")) {
myHolder.createErrorAnnotation(literal, GroovyBundle.message("string.end.expected"));
}
}
else if (text.startsWith("'")) {
if (text.length() < 2 || !text.endsWith("'")) {
myHolder.createErrorAnnotation(literal, GroovyBundle.message("string.end.expected"));
}
}
}
@Override
public void visitForInClause(GrForInClause forInClause) {
final GrVariable[] declaredVariables = forInClause.getDeclaredVariables();
if (declaredVariables.length < 1) return;
final GrVariable variable = declaredVariables[0];
@@ -197,29 +498,28 @@ public class GroovyAnnotator implements Annotator {
final String modifierText = modifier.getText();
if (PsiModifier.FINAL.equals(modifierText)) continue;
if ("def".equals(modifierText)) continue;
holder.createErrorAnnotation(modifier, GroovyBundle.message("not.allowed.modifier.in.forin", modifierText));
myHolder.createErrorAnnotation(modifier, GroovyBundle.message("not.allowed.modifier.in.forin", modifierText));
}
}
private static void checkLiteral(GrLiteral literal, AnnotationHolder holder) {
String text = literal.getText();
if (text.startsWith("'''")) {
if (text.length() < 6 || !text.endsWith("'''")) {
holder.createErrorAnnotation(literal, GroovyBundle.message("string.end.expected"));
}
}
else if (text.startsWith("'")) {
if (text.length() < 2 || !text.endsWith("'")) {
holder.createErrorAnnotation(literal, GroovyBundle.message("string.end.expected"));
@Override
public void visitFile(GroovyFileBase file) {
if (!file.isScript()) return;
List<GrMethod> methods = new ArrayList<GrMethod>();
for (GrTopLevelDefintion topLevelDefinition : file.getTopLevelDefinitions()) {
if (topLevelDefinition instanceof GrMethod) {
methods.add(((GrMethod)topLevelDefinition));
}
}
checkDuplicateMethod(methods.toArray(new GrMethod[methods.size()]), myHolder);
}
private static void checkLabeledStatement(GrLabeledStatement statement, AnnotationHolder holder) {
final String name = statement.getLabelName();
if (ResolveUtil.resolveLabeledStatement(name, statement, true) != null) {
holder.createWarningAnnotation(statement.getLabel(), GroovyBundle.message("label.already.used", name));
}
@Override
public void visitImportStatement(GrImportStatement importStatement) {
checkAnnotationList(myHolder, importStatement.getAnnotationList(), GroovyBundle.message("import.statement.cannot.have.modifiers"));
}
private static void checkFlowInterruptStatement(GrFlowInterruptingStatement statement, AnnotationHolder holder) {
@@ -314,25 +614,6 @@ public class GroovyAnnotator implements Annotator {
}
}
private static void checkPackageReference(AnnotationHolder holder, GrPackageDefinition packageDefinition) {
final PsiFile file = packageDefinition.getContainingFile();
assert file != null;
PsiDirectory psiDirectory = file.getContainingDirectory();
if (psiDirectory != null) {
PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(psiDirectory);
if (aPackage != null) {
String packageName = aPackage.getQualifiedName();
if (!packageDefinition.getPackageName().equals(packageName)) {
final Annotation annotation = holder.createWarningAnnotation(packageDefinition, "wrong package name");
annotation.registerFix(new ChangePackageQuickFix((GroovyFile)packageDefinition.getContainingFile(), packageName));
}
}
}
final GrModifierList modifierList = packageDefinition.getAnnotationList();
checkAnnotationList(holder, modifierList, GroovyBundle.message("package.definition.cannot.have.modifiers"));
}
private static void checkAnnotationList(AnnotationHolder holder, @Nullable GrModifierList modifierList, String message) {
if (modifierList == null) return;
final PsiElement[] modifiers = modifierList.getModifiers();
@@ -366,32 +647,6 @@ public class GroovyAnnotator implements Annotator {
annotation.registerFix(new ImplementMethodsQuickFix(typeDefinition));
}
private static void checkConstructorInvocation(AnnotationHolder holder, GrConstructorInvocation invocation) {
final GroovyResolveResult resolveResult = invocation.resolveConstructorGenerics();
if (resolveResult != null) {
checkMethodApplicability(resolveResult, invocation.getThisOrSuperKeyword(), holder);
}
else {
final GroovyResolveResult[] results = invocation.multiResolveConstructor();
final GrArgumentList argList = invocation.getArgumentList();
if (results.length > 0) {
String message = GroovyBundle.message("ambiguous.constructor.call");
holder.createWarningAnnotation(argList, message);
}
else {
final PsiClass clazz = invocation.getDelegatedClass();
if (clazz != null) {
//default constructor invocation
PsiType[] argumentTypes = PsiUtil.getArgumentTypes(invocation.getThisOrSuperKeyword(), true, true);
if (argumentTypes != null && argumentTypes.length > 0) {
String message = GroovyBundle.message("cannot.find.default.constructor", clazz.getName());
holder.createWarningAnnotation(argList, message);
}
}
}
}
}
private static void checkInnerMethod(AnnotationHolder holder, GrMethod grMethod) {
final PsiElement parent = grMethod.getParent();
if (parent instanceof GrOpenBlock || parent instanceof GrClosableBlock) {
@@ -399,34 +654,6 @@ public class GroovyAnnotator implements Annotator {
}
}
private static void checkMap(GrNamedArgument[] namedArguments, AnnotationHolder holder) {
final Map<GrNamedArgument, List<GrNamedArgument>> map = DuplicatesUtil.factorDuplicates(namedArguments, new TObjectHashingStrategy<GrNamedArgument>() {
public int computeHashCode(GrNamedArgument arg) {
final GrArgumentLabel label = arg.getLabel();
if (label == null) return 0;
final String name = label.getName();
if (name == null) return 0;
return name.hashCode();
}
public boolean equals(GrNamedArgument arg1, GrNamedArgument arg2) {
final GrArgumentLabel label1 = arg1.getLabel();
final GrArgumentLabel label2 = arg2.getLabel();
if (label1 == null || label2 == null) {
return label1 == null && label2 == null;
}
final String name1 = label1.getName();
final String name2 = label2.getName();
if (name1 == null || name2 == null) {
return name1 == null && name2 == null;
}
return name1.equals(name2);
}
});
processDuplicates(map, holder);
}
protected static void processDuplicates(Map<GrNamedArgument, List<GrNamedArgument>> map, AnnotationHolder holder) {
for (List<GrNamedArgument> args : map.values()) {
for (int i = 1; i < args.size(); i++) {
@@ -436,30 +663,6 @@ public class GroovyAnnotator implements Annotator {
}
}
private static void checkVariableDeclaration(AnnotationHolder holder, GrVariableDeclaration variableDeclaration) {
PsiElement parent = variableDeclaration.getParent();
assert parent != null;
PsiElement typeDef = parent.getParent();
if (typeDef != null && typeDef instanceof GrTypeDefinition) {
PsiModifierList modifiersList = variableDeclaration.getModifierList();
checkAccessModifiers(holder, modifiersList);
if (modifiersList.hasExplicitModifier(PsiModifier.VOLATILE) && modifiersList.hasExplicitModifier(PsiModifier.FINAL)) {
holder.createErrorAnnotation(modifiersList, GroovyBundle.message("illegal.combination.of.modifiers.volatile.and.final"));
}
if (modifiersList.hasExplicitModifier(PsiModifier.NATIVE)) {
holder.createErrorAnnotation(modifiersList, GroovyBundle.message("variable.cannot.be.native"));
}
if (modifiersList.hasExplicitModifier(PsiModifier.ABSTRACT)) {
holder.createErrorAnnotation(modifiersList, GroovyBundle.message("variable.cannot.be.abstract"));
}
}
}
private static void checkMethodDefinitionModifiers(AnnotationHolder holder, GrMethod method) {
final PsiModifierList modifiersList = method.getModifierList();
checkAccessModifiers(holder, modifiersList);
@@ -597,18 +800,6 @@ public class GroovyAnnotator implements Annotator {
}
}
private static void checkScriptDuplicateMethod(GrTopLevelDefintion[] topLevelDefinitions, AnnotationHolder holder) {
List<GrMethod> methods = new ArrayList<GrMethod>();
for (GrTopLevelDefintion topLevelDefinition : topLevelDefinitions) {
if (topLevelDefinition instanceof GrMethod) {
methods.add(((GrMethod)topLevelDefinition));
}
}
checkDuplicateMethod(methods.toArray(new GrMethod[methods.size()]), holder);
}
private static void checkDuplicateMethod(GrMethod[] methods, AnnotationHolder holder) {
final Map<GrMethod, List<GrMethod>> map = DuplicatesUtil.factorDuplicates(methods, new TObjectHashingStrategy<GrMethod>() {
public int computeHashCode(GrMethod method) {
@@ -639,51 +830,6 @@ public class GroovyAnnotator implements Annotator {
}
private static void checkReturnStatement(GrReturnStatement returnStatement, AnnotationHolder holder) {
final GrExpression value = returnStatement.getReturnValue();
if (value != null) {
final PsiType type = value.getType();
if (type != null) {
final GrParametersOwner owner = PsiTreeUtil.getParentOfType(returnStatement, GrMethod.class, GrClosableBlock.class);
if (owner instanceof PsiMethod) {
final PsiMethod method = (PsiMethod)owner;
if (method.isConstructor()) {
holder.createErrorAnnotation(value, GroovyBundle.message("cannot.return.from.constructor"));
}
else {
final PsiType methodType = method.getReturnType();
if (methodType != null) {
if (PsiType.VOID.equals(methodType)) {
holder.createErrorAnnotation(value, GroovyBundle.message("cannot.return.from.void.method"));
}
}
}
}
}
}
}
private static void checkAssignmentExpression(GrAssignmentExpression assignment, AnnotationHolder holder) {
GrExpression lValue = assignment.getLValue();
if (!PsiUtil.mightBeLVlaue(lValue)) {
holder.createErrorAnnotation(lValue, GroovyBundle.message("invalid.lvalue"));
}
}
private static void checkVariable(AnnotationHolder holder, GrVariable variable) {
PropertyResolverProcessor processor = new DuplicateVariablesProcessor(variable);
final GroovyPsiElement duplicate = ResolveUtil.resolveExistingElement(variable, processor, GrVariable.class, GrReferenceExpression.class);
if (duplicate instanceof GrVariable) {
if (duplicate instanceof GrField && !(variable instanceof GrField)) {
holder.createWarningAnnotation(variable.getNameIdentifierGroovy(), GroovyBundle.message("field.already.defined", variable.getName()));
} else {
final String key = duplicate instanceof GrField ? "field.already.defined" : "variable.already.defined";
holder.createErrorAnnotation(variable.getNameIdentifierGroovy(), GroovyBundle.message(key, variable.getName()));
}
}
}
private static void checkTypeDefinition(AnnotationHolder holder, GrTypeDefinition typeDefinition) {
final GroovyConfigUtils configUtils = GroovyConfigUtils.getInstance();
if (typeDefinition.isAnnotationType()) {
@@ -804,72 +950,6 @@ public class GroovyAnnotator implements Annotator {
}
}
private static void checkReferenceExpression(AnnotationHolder holder, final GrReferenceExpression refExpr) {
GroovyResolveResult resolveResult = refExpr.advancedResolve();
GroovyResolveResult[] results = refExpr.multiResolve(false); //cached
for (GroovyResolveResult result : results) {
registerUsedImport(refExpr, result);
}
PsiElement resolved = resolveResult.getElement();
final PsiElement parent = refExpr.getParent();
if (resolved != null) {
if (resolved instanceof PsiMember) {
highlightMemberResolved(holder, refExpr, ((PsiMember)resolved));
}
if (!resolveResult.isAccessible()) {
String message = GroovyBundle.message("cannot.access", refExpr.getReferenceName());
holder.createWarningAnnotation(refExpr.getReferenceNameElement(), message);
}
if (!resolveResult.isStaticsOK() && resolved instanceof PsiModifierListOwner) {
if (!((PsiModifierListOwner)resolved).hasModifierProperty(PsiModifier.STATIC)) {
holder.createWarningAnnotation(refExpr, GroovyBundle.message("cannot.reference.nonstatic", refExpr.getReferenceName()));
}
}
}
else {
GrExpression qualifier = refExpr.getQualifierExpression();
if (qualifier == null && isDeclarationAssignment(refExpr)) return;
if (parent instanceof GrReferenceExpression && "class".equals(((GrReferenceExpression)parent).getReferenceName())) {
checkSingleResolvedElement(holder, refExpr, resolveResult);
}
}
if (parent instanceof GrCall) {
if (resolved == null && results.length > 0) {
resolved = results[0].getElement();
resolveResult = results[0];
}
if (resolved instanceof PsiMethod && resolved.getUserData(GrMethod.BUILDER_METHOD) == null) {
checkMethodApplicability(resolveResult, refExpr, holder);
}
else {
checkClosureApplicability(resolveResult, refExpr.getType(), refExpr, holder);
}
}
if (isDeclarationAssignment(refExpr) || resolved instanceof PsiPackage) return;
if (resolved == null) {
PsiElement refNameElement = refExpr.getReferenceNameElement();
PsiElement elt = refNameElement == null ? refExpr : refNameElement;
Annotation annotation = holder.createInfoAnnotation(elt, null);
final GrExpression qualifier = refExpr.getQualifierExpression();
if (qualifier == null) {
if (!(parent instanceof GrCall)) {
registerCreateClassByTypeFix(refExpr, annotation);
registerAddImportFixes(refExpr, annotation);
}
} else {
if (qualifier.getType() == null) {
return;
}
}
registerReferenceFixes(refExpr, annotation);
annotation.setTextAttributes(DefaultHighlighter.UNRESOLVED_ACCESS);
}
}
private static void registerReferenceFixes(GrReferenceExpression refExpr, Annotation annotation) {
PsiClass targetClass = QuickfixUtil.findTargetClass(refExpr);
if (targetClass == null) return;
@@ -994,23 +1074,6 @@ public class GroovyAnnotator implements Annotator {
return false;
}
private static void checkReferenceElement(AnnotationHolder holder, final GrCodeReferenceElement refElement) {
final PsiElement parent = refElement.getParent();
GroovyResolveResult resolveResult = refElement.advancedResolve();
highlightAnnotation(holder, refElement, resolveResult);
registerUsedImport(refElement, resolveResult);
highlightAnnotation(holder, refElement, resolveResult);
if (refElement.getReferenceName() != null) {
if (parent instanceof GrImportStatement && ((GrImportStatement)parent).isStatic() && refElement.multiResolve(false).length > 0) {
return;
}
checkSingleResolvedElement(holder, refElement, resolveResult);
}
}
private static void checkSingleResolvedElement(AnnotationHolder holder, GrReferenceElement refElement, GroovyResolveResult resolveResult) {
final PsiElement resolved = resolveResult.getElement();
if (resolved == null) {
@@ -1033,63 +1096,6 @@ public class GroovyAnnotator implements Annotator {
}
}
private static void checkNewExpression(AnnotationHolder holder, GrNewExpression newExpression) {
if (newExpression.getArrayCount() > 0) return;
GrCodeReferenceElement refElement = newExpression.getReferenceElement();
if (refElement == null) return;
final PsiElement element = refElement.resolve();
if (element instanceof PsiClass) {
PsiClass clazz = (PsiClass)element;
if (clazz.hasModifierProperty(PsiModifier.ABSTRACT)) {
if (newExpression.getAnonymousClassDefinition() == null) {
String message = clazz.isInterface()
? GroovyBundle.message("cannot.instantiate.interface", clazz.getName())
: GroovyBundle.message("cannot.instantiate.abstract.class", clazz.getName());
holder.createErrorAnnotation(refElement, message);
}
return;
}
if (newExpression.getQualifier() != null) {
if (clazz.hasModifierProperty(PsiModifier.STATIC)) {
holder.createErrorAnnotation(newExpression, GroovyBundle.message("qualified.new.of.static.class"));
}
} else {
final PsiClass outerClass = clazz.getContainingClass();
if (com.intellij.psi.util.PsiUtil.isInnerClass(clazz) && !PsiUtil.hasEnclosingInstanceInScope(outerClass, newExpression, true)) {
holder.createErrorAnnotation(newExpression, GroovyBundle.message("cannot.reference.nonstatic", clazz.getQualifiedName()));
}
}
}
final GroovyResolveResult constructorResolveResult = newExpression.resolveConstructorGenerics();
if (constructorResolveResult.getElement() != null) {
checkMethodApplicability(constructorResolveResult, refElement, holder);
final GrArgumentList argList = newExpression.getArgumentList();
if (argList != null && argList.getExpressionArguments().length == 0) checkDefaultMapConstructor(holder, argList);
}
else {
final GroovyResolveResult[] results = newExpression.multiResolveConstructor();
final GrArgumentList argList = newExpression.getArgumentList();
PsiElement toHighlight = argList != null ? argList : refElement.getReferenceNameElement();
if (results.length > 0) {
String message = GroovyBundle.message("ambiguous.constructor.call");
holder.createWarningAnnotation(toHighlight, message);
}
else {
if (element instanceof PsiClass) {
//default constructor invocation
PsiType[] argumentTypes = PsiUtil.getArgumentTypes(refElement, true, true);
if (argumentTypes != null && argumentTypes.length > 0) {
String message = GroovyBundle.message("cannot.find.default.constructor", ((PsiClass)element).getName());
holder.createWarningAnnotation(toHighlight, message);
}
else checkDefaultMapConstructor(holder, argList);
}
}
}
}
private static void checkDefaultMapConstructor(AnnotationHolder holder, GrArgumentList argList) {
if (argList != null) {
final GrNamedArgument[] args = argList.getNamedArguments();
@@ -17,7 +17,10 @@ package org.jetbrains.plugins.groovy.compiler.generator;
import com.intellij.compiler.CompilerConfiguration;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.compiler.*;
import com.intellij.openapi.compiler.CompileContext;
import com.intellij.openapi.compiler.CompilerManager;
import com.intellij.openapi.compiler.TimestampValidityState;
import com.intellij.openapi.compiler.ValidityState;
import com.intellij.openapi.compiler.options.ExcludedEntriesConfiguration;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.JavaModuleType;
@@ -36,6 +39,7 @@ import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.HashSet;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.GroovyFileType;
import org.jetbrains.plugins.groovy.compiler.GroovyCompilerConfiguration;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
@@ -68,8 +72,7 @@ import java.util.*;
* @author: Dmitry.Krasilschikov
* @date: 03.05.2007
*/
//todo it's not actually a compiler anymore, remove all the implements'
public class GroovyToJavaGenerator implements SourceGeneratingCompiler, CompilationStatusListener {
public class GroovyToJavaGenerator {
private static final Map<String, String> typesToInitialValues = new HashMap<String, String>();
private static final Logger LOG = Logger.getInstance("org.jetbrains.plugins.groovy.compiler.generator.GroovyToJavaGenerator");
@@ -100,12 +103,6 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat
PsiModifier.VOLATILE
};
private static final String[] JAVA_TYPE_DEFINITION_MODIFIERS = new String[]{
PsiModifier.PUBLIC,
PsiModifier.ABSTRACT,
PsiModifier.FINAL
};
private static final CharSequence PREFIX_SEPARATOR = "/";
private final CompileContext myContext;
private final Project myProject;
@@ -149,7 +146,7 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat
//top level class
if (needCreateTopLevelClass) {
generationItems.add(new GenerationItemImpl(prefix + file.getNameWithoutExtension() + "." + "java", module, new TimestampValidityState(file.getTimeStamp()), isInTestSources, file));
generationItems.add(new GenerationItem(prefix + file.getNameWithoutExtension() + "." + "java", module, new TimestampValidityState(file.getTimeStamp()), isInTestSources, file));
}
GrTypeDefinition[] typeDefinitions = ApplicationManager.getApplication().runReadAction(new Computable<GrTypeDefinition[]>() {
@@ -159,7 +156,7 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat
});
for (GrTypeDefinition typeDefinition : typeDefinitions) {
item = new GenerationItemImpl(prefix + typeDefinition.getName() + "." + "java", module, new TimestampValidityState(file.getTimeStamp()), isInTestSources, file);
item = new GenerationItem(prefix + typeDefinition.getName() + "." + "java", module, new TimestampValidityState(file.getTimeStamp()), isInTestSources, file);
generationItems.add(item);
}
}
@@ -181,7 +178,7 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat
return VfsUtil.toVirtualFileArray(set);
}
public GenerationItem[] generate(CompileContext context, GenerationItem[] itemsToGenerate, VirtualFile outputRootDirectory) {
public GenerationItem[] generate(GenerationItem[] itemsToGenerate, VirtualFile outputRootDirectory) {
List<GenerationItem> generatedItems = new ArrayList<GenerationItem>();
Map<String, GenerationItem> pathsToItemsMap = new HashMap<String, GenerationItem>();
@@ -192,7 +189,7 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat
Set<VirtualFile> vFiles = new HashSet<VirtualFile>();
for (GenerationItem item : itemsToGenerate) {
vFiles.add(((GenerationItemImpl) item).getVFile());
vFiles.add(item.getVFile());
}
for (VirtualFile vFile : vFiles) {
@@ -270,19 +267,19 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat
!classNames.contains(StringUtil.decapitalize(fileDefinitionName))) {
final PsiClass scriptClass = file.getScriptClass();
if (scriptClass != null) {
generatedItemsRelativePaths.add(createJavaSourceFile(outputRootDirectory, file, scriptClass, packageDefinition));
generatedItemsRelativePaths.add(createJavaSourceFile(outputRootDirectory, scriptClass, packageDefinition));
}
}
}
for (final GrTypeDefinition typeDefinition : file.getTypeDefinitions()) {
generatedItemsRelativePaths.add(createJavaSourceFile(outputRootDirectory, file, typeDefinition, packageDefinition));
generatedItemsRelativePaths.add(createJavaSourceFile(outputRootDirectory, typeDefinition, packageDefinition));
}
return generatedItemsRelativePaths;
}
private static String getJavaClassPackage(GrPackageDefinition packageDefinition) {
private static String getJavaClassPackage(@Nullable GrPackageDefinition packageDefinition) {
if (packageDefinition == null) return "";
String prefix = packageDefinition.getPackageName();
@@ -292,24 +289,43 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat
return prefix;
}
private String createJavaSourceFile(VirtualFile outputRootDirectory, GroovyFileBase file, @NotNull PsiClass typeDefinition, GrPackageDefinition packageDefinition) {
//prefix defines structure of directories tree
String prefix = "";
if (packageDefinition != null) {
prefix = getJavaClassPackage(packageDefinition);
private String createJavaSourceFile(VirtualFile outputRootDirectory, @NotNull PsiClass typeDefinition, GrPackageDefinition packageDefinition) {
StringBuffer text = new StringBuffer();
writeTypeDefinition(text, typeDefinition, packageDefinition, true);
String prefix = getJavaClassPackage(packageDefinition);
String outputDir = outputRootDirectory.getPath();
String fileName = typeDefinition.getName() + "." + "java";
String prefixWithoutSeparator = prefix;
if (!"".equals(prefix)) {
prefixWithoutSeparator = prefix.substring(0, prefix.length() - PREFIX_SEPARATOR.length());
new File(outputDir, prefixWithoutSeparator).mkdirs();
}
StringBuffer text = new StringBuffer();
File myFile;
if (!"".equals(prefix))
myFile = new File(outputDir + File.separator + prefixWithoutSeparator, fileName);
else
myFile = new File(outputDir, fileName);
final String typeDefinitionName = typeDefinition.getName();
writeTypeDefinition(text, typeDefinitionName, typeDefinition, packageDefinition);
VirtualFile virtualFile = file.getVirtualFile();
assert virtualFile != null;
// String generatedFileRelativePath = prefix + typeDefinitionName + "." + "java";
String fileShortName = typeDefinitionName + "." + "java";
createGeneratedFile(text, outputRootDirectory.getPath(), prefix, fileShortName);
return prefix + typeDefinitionName + "." + "java";
BufferedWriter writer = null;
try {
Writer fileWriter = new FileWriter(myFile);
writer = new BufferedWriter(fileWriter);
writer.write(text.toString());
} catch (IOException e) {
LOG.error(e);
} finally {
try {
assert writer != null;
writer.close();
} catch (IOException e) {
LOG.error(e);
}
}
return prefix + fileName;
}
private static GrTopStatement[] getTopStatementsInReadAction(final GroovyFileBase myPsiFile) {
@@ -333,7 +349,8 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat
return isOnlyInnerTypeDef;
}
private void writeTypeDefinition(StringBuffer text, String typeDefinitionName, @NotNull PsiClass typeDefinition, GrPackageDefinition packageDefinition) {
private void writeTypeDefinition(StringBuffer text, @NotNull PsiClass typeDefinition,
@Nullable GrPackageDefinition packageDefinition, boolean toplevel) {
final boolean isScript = typeDefinition instanceof GroovyScriptClass;
writePackageStatement(text, packageDefinition);
@@ -345,39 +362,26 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat
boolean isEnum = typeDefinition instanceof GrEnumTypeDefinition;
boolean isAtInterface = typeDefinition instanceof GrAnnotationTypeDefinition;
PsiModifierList modifierList = typeDefinition.getModifierList();
boolean wasAddedModifiers = modifierList != null && writeTypeDefinitionMethodModifiers(text, modifierList, JAVA_TYPE_DEFINITION_MODIFIERS, typeDefinition.isInterface());
if (!wasAddedModifiers) {
text.append("public ");
}
writeClassModifiers(text, typeDefinition.getModifierList(), typeDefinition.isInterface(), toplevel);
if (isInterface) text.append("interface");
else if (isEnum) text.append("enum");
else if (isAtInterface) text.append("@interface");
else text.append("class");
text.append(" ");
text.append(" ").append(typeDefinition.getName());
text.append(typeDefinitionName);
if (typeDefinition != null) {
appendTypeParameters(text, typeDefinition);
}
appendTypeParameters(text, typeDefinition);
text.append(" ");
if (isScript) {
text.append("extends ");
text.append("groovy.lang.Script ");
text.append("extends groovy.lang.Script ");
} else if (!isEnum && !isAtInterface) {
final PsiClassType[] extendsClassesTypes = typeDefinition.getExtendsListTypes();
if (extendsClassesTypes.length > 0) {
text.append("extends ");
text.append(computeTypeText(extendsClassesTypes[0], false));
text.append(" ");
text.append("extends ").append(computeTypeText(extendsClassesTypes[0], false)).append(" ");
}
PsiClassType[] implementsTypes = typeDefinition.getImplementsListTypes();
@@ -386,8 +390,7 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat
int i = 0;
while (i < implementsTypes.length) {
if (i > 0) text.append(", ");
text.append(computeTypeText(implementsTypes[i], false));
text.append(" ");
text.append(computeTypeText(implementsTypes[i], false)).append(" ");
i++;
}
}
@@ -457,6 +460,10 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat
writeVariableDeclarations(text, (GrVariableDeclaration) declaration);
}
}
for (PsiClass inner : typeDefinition.getInnerClasses()) {
writeTypeDefinition(text, inner, null, false);
text.append("\n");
}
text.append("}");
}
@@ -527,7 +534,7 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat
}
}
private void writeConstructor(final StringBuffer text, final GrConstructor constructor, boolean isEnum) {
private static void writeConstructor(final StringBuffer text, final GrConstructor constructor, boolean isEnum) {
text.append("\n");
text.append(" ");
if (!isEnum) {
@@ -543,23 +550,16 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat
GrParameter[] parameterList = constructor.getParameters();
text.append("(");
String paramType;
GrTypeElement paramTypeElement;
for (int i = 0; i < parameterList.length; i++) {
if (i > 0) text.append(", ");
GrParameter parameter = parameterList[i];
paramTypeElement = parameter.getTypeElementGroovy();
paramType = getTypeText(paramTypeElement);
text.append(paramType);
text.append(" ");
text.append(parameter.getName());
text.append(getTypeText(parameter.getTypeElementGroovy())).append(" ").append(parameter.getName());
}
text.append(")");
text.append(" ");
text.append(") ");
/************* body **********/
@@ -744,27 +744,32 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat
}
}
private static boolean writeTypeDefinitionMethodModifiers(StringBuffer text, PsiModifierList modifierList, String[] modifiers, boolean isInterface) {
boolean wasAddedModifiers = false;
for (String modifierType : modifiers) {
if (modifierList.hasModifierProperty(modifierType)) {
if (PsiModifier.ABSTRACT.equals(modifierType) && isInterface) {
continue;
private static void writeClassModifiers(StringBuffer text,
@Nullable PsiModifierList modifierList, boolean isInterface, boolean toplevel) {
if (modifierList == null || modifierList.hasModifierProperty(PsiModifier.PUBLIC)) {
text.append("public ");
}
if (modifierList != null) {
List<String> allowedModifiers = new ArrayList<String>();
allowedModifiers.add(PsiModifier.FINAL);
if (!toplevel) {
allowedModifiers.addAll(Arrays.asList(PsiModifier.PROTECTED, PsiModifier.PRIVATE, PsiModifier.STATIC));
}
if (!isInterface) {
allowedModifiers.add(PsiModifier.ABSTRACT);
}
for (String modifierType : allowedModifiers) {
if (modifierList.hasModifierProperty(modifierType)) {
text.append(modifierType).append(" ");
}
text.append(modifierType);
text.append(" ");
wasAddedModifiers = true;
}
}
return wasAddedModifiers;
}
private static String getTypeText(GrTypeElement typeElement) {
if (typeElement == null) {
return "java.lang.Object";
} else {
return computeTypeText(typeElement.getType(), false);
}
return getTypeText(typeElement == null ? null : typeElement.getType(), false);
}
private static String getTypeText(PsiType type, boolean allowVarargs) {
@@ -786,66 +791,16 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat
return canonicalText != null ? canonicalText : type.getPresentableText();
}
private static void createGeneratedFile(StringBuffer text, String outputDir, String prefix, String generatedItemPath) {
assert prefix != null;
String prefixWithoutSeparator = prefix;
if (!"".equals(prefix)) {
prefixWithoutSeparator = prefix.substring(0, prefix.length() - PREFIX_SEPARATOR.length());
new File(outputDir, prefixWithoutSeparator).mkdirs();
}
File myFile;
if (!"".equals(prefix))
myFile = new File(outputDir + File.separator + prefixWithoutSeparator, generatedItemPath);
else
myFile = new File(outputDir, generatedItemPath);
BufferedWriter writer = null;
try {
Writer fileWriter = new FileWriter(myFile);
writer = new BufferedWriter(fileWriter);
writer.write(text.toString());
} catch (IOException e) {
LOG.error(e);
} finally {
try {
assert writer != null;
writer.close();
} catch (IOException e) {
LOG.error(e);
}
}
}
@NotNull
public String getDescription() {
return "Groovy to java source code generator";
}
public boolean validateConfiguration(CompileScope scope) {
return true;
}
CharTrie myTrie = new CharTrie();
public void compilationFinished(boolean aborted, int errors, int warnings, final CompileContext compileContext) {
myTrie.clear();
}
public ValidityState createValidityState(DataInput in) throws IOException {
return TimestampValidityState.load(in);
}
class GenerationItemImpl implements GenerationItem {
public class GenerationItem {
ValidityState myState;
private final boolean myInTestSources;
final Module myModule;
public int myHashCode;
private final VirtualFile myVFile;
public GenerationItemImpl(String path, Module module, ValidityState state, boolean isInTestSources, VirtualFile vFile) {
public GenerationItem(String path, Module module, ValidityState state, boolean isInTestSources, VirtualFile vFile) {
myVFile = vFile;
myModule = module;
myState = state;
@@ -857,18 +812,10 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat
return myTrie.getString(myHashCode);
}
public ValidityState getValidityState() {
return myState;
}
public Module getModule() {
return myModule;
}
public boolean isTestSource() {
return myInTestSources;
}
public VirtualFile getVFile() {
return myVFile;
}
@@ -263,7 +263,7 @@ public class GroovyCompilerTest extends GroovyCompilerTestCase {
Module dep = addDependentModule();
addGroovyLibrary(dep);
addGroovyLibrary(dep, false);
assertEmpty(make());
assertOutput("Bar", "239", dep);
@@ -278,5 +278,14 @@ public class GroovyCompilerTest extends GroovyCompilerTestCase {
assertEmpty make()
}
public void test1_7InnerClass() throws Exception {
myFixture.addFileToProject "Foo.groovy", """
class Foo {
static class Bar {}
}"""
myFixture.addFileToProject "AJava.java", "public class AJava extends Foo.Bar {}"
assertEmpty make()
}
}
@@ -43,6 +43,7 @@ import com.intellij.util.concurrency.Semaphore;
import org.jetbrains.plugins.groovy.compiler.GroovyCompilerLoader;
import org.jetbrains.plugins.groovy.config.GroovyConfigUtils;
import org.jetbrains.plugins.groovy.util.GroovyUtils;
import org.jetbrains.plugins.groovy.util.TestUtils;
import java.io.File;
import java.io.IOException;
@@ -65,7 +66,7 @@ public abstract class GroovyCompilerTestCase extends JavaCodeInsightFixtureTestC
CompilerProjectExtension.getInstance(getProject()).setCompilerOutputUrl(myMainOutput.findOrCreateDir("out").getUrl());
addGroovyLibrary(myModule);
addGroovyLibrary(myModule, getName().contains("1_7"));
}
@Override
@@ -74,8 +75,8 @@ public abstract class GroovyCompilerTestCase extends JavaCodeInsightFixtureTestC
super.tuneFixture(moduleBuilder);
}
protected static void addGroovyLibrary(final Module to) {
final String root = PathManager.getHomePath() + "/community/lib/";
protected static void addGroovyLibrary(final Module to, boolean version17) {
final String root = version17 ? TestUtils.getRealGroovy1_7LibraryHome() : PathManager.getHomePath() + "/community/lib/";
final File[] groovyJars = GroovyUtils.getFilesInDirectoryByPattern(root, GroovyConfigUtils.GROOVY_ALL_JAR_PATTERN);
assert groovyJars.length == 1;
PsiTestUtil.addLibrary(to, "groovy", root, groovyJars[0].getName());
@@ -1,15 +1,14 @@
package org.jetbrains.plugins.groovy.lang.generator;
import com.intellij.openapi.compiler.CompileContext;
import com.intellij.openapi.compiler.GeneratingCompiler;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase;
import com.intellij.testFramework.fixtures.TempDirTestFixture;
import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.plugins.groovy.compiler.generator.GroovyToJavaGenerator;
import org.jetbrains.plugins.groovy.util.TestUtils;
@@ -77,15 +76,15 @@ public void testArrayType1() throws Throwable { doTest(); }
final StringBuffer buffer = new StringBuffer();
final GroovyToJavaGeneratorTester groovyToJavaGeneratorTester = new GroovyToJavaGeneratorTester(relTestPath, data.get(0), getProject());
final GeneratingCompiler.GenerationItem[][] generatedItems = new GeneratingCompiler.GenerationItem[1][1];
final GroovyToJavaGenerator.GenerationItem[][] generatedItems = new GroovyToJavaGenerator.GenerationItem[1][1];
GeneratingCompiler.GenerationItem[] generationItems = groovyToJavaGeneratorTester.getGenerationItems(null);
GroovyToJavaGenerator.GenerationItem[] generationItems = groovyToJavaGeneratorTester.getGenerationItems(null);
VirtualFile outputDirVirtualFile = tempDirFixture.getFile("");
generatedItems[0] = groovyToJavaGeneratorTester.generate(null, generationItems, outputDirVirtualFile);
generatedItems[0] = groovyToJavaGeneratorTester.generate(generationItems, outputDirVirtualFile);
for (GeneratingCompiler.GenerationItem generatedItem : generatedItems[0]) {
for (GroovyToJavaGenerator.GenerationItem generatedItem : generatedItems[0]) {
final String path = tempDirFixture.getTempDirPath() + File.separator + generatedItem.getPath();
BufferedReader reader = new BufferedReader(new FileReader(path));
@@ -58,6 +58,10 @@ public abstract class TestUtils {
return getAbsoluteTestDataPath() + "/mockGroovyLib1.7";
}
public static String getRealGroovy1_7LibraryHome() {
return getAbsoluteTestDataPath() + "/realGroovy17/";
}
public static String getMockGroovy1_7LibraryName() {
return getMockGroovy1_7LibraryHome()+"/groovy-all-1.7.jar";
}
Binary file not shown.
@@ -16,6 +16,7 @@
package com.intellij.html.impl;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ArrayUtil;
import com.intellij.xml.XmlAttributeDescriptor;
@@ -82,6 +83,11 @@ public class RelaxedHtmlFromSchemaElementDescriptor extends XmlElementDescriptor
return descriptors;
}
@Override
public XmlAttributeDescriptor getAttributeDescriptor(XmlAttribute attribute) {
return getAttributeDescriptor(attribute.getName(), attribute.getParent());
}
public XmlAttributeDescriptor getAttributeDescriptor(String attributeName, final XmlTag context) {
final XmlAttributeDescriptor descriptor = super.getAttributeDescriptor(attributeName.toLowerCase(), context);
if (descriptor != null) return descriptor;
@@ -156,15 +156,17 @@ public class XmlElementDescriptorImpl implements XmlElementDescriptor, PsiWritab
return nsDescriptor;
}
@Nullable
public TypeDescriptor getType() {
return getType(null);
}
@Nullable
public TypeDescriptor getType(XmlElement context) {
final XmlNSDescriptor nsDescriptor = getNSDescriptor(context);
if (!(nsDescriptor instanceof XmlNSDescriptorImpl)) return null;
if (!(nsDescriptor instanceof XmlNSTypeDescriptorProvider)) return null;
TypeDescriptor type = ((XmlNSDescriptorImpl) nsDescriptor).getTypeDescriptor(myDescriptorTag);
TypeDescriptor type = ((XmlNSTypeDescriptorProvider) nsDescriptor).getTypeDescriptor(myDescriptorTag);
if (type == null) {
String substAttr = myDescriptorTag.getAttributeValue("substitutionGroup");
if (substAttr != null) {
@@ -48,7 +48,7 @@ import java.util.*;
* @author Mike
*/
@SuppressWarnings({"HardCodedStringLiteral"})
public class XmlNSDescriptorImpl implements XmlNSDescriptor,Validator<XmlDocument>, DumbAware {
public class XmlNSDescriptorImpl implements XmlNSDescriptor,Validator<XmlDocument>, DumbAware, XmlNSTypeDescriptorProvider {
@NonNls private static final Set<String> STD_TYPES = new HashSet<String>();
private static final Set<String> UNDECLARED_STD_TYPES = new HashSet<String>();
private XmlFile myFile;
@@ -335,7 +335,7 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptor,Validator<XmlDocumen
return new XmlAttributeDescriptorImpl(tag);
}
protected TypeDescriptor getTypeDescriptor(XmlTag descriptorTag) {
public TypeDescriptor getTypeDescriptor(XmlTag descriptorTag) {
String type = descriptorTag.getAttributeValue("type");
if (type != null) {
@@ -405,20 +405,23 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptor,Validator<XmlDocumen
return defaultNSDescriptor;
}
@Nullable
protected TypeDescriptor findTypeDescriptor(final String qname) {
return findTypeDescriptor(qname, myTag);
}
@Nullable
protected TypeDescriptor findTypeDescriptor(final String qname, XmlTag context) {
String namespace = context.getNamespaceByPrefix(XmlUtil.findPrefixByQualifiedName(qname));
return findTypeDescriptor(XmlUtil.findLocalNameByQualifiedName(qname), namespace);
}
@Nullable
private TypeDescriptor findTypeDescriptor(String localName, String namespace) {
TypeDescriptor typeDescriptor = findTypeDescriptorImpl(myTag, localName, namespace, null);
return typeDescriptor;
return findTypeDescriptorImpl(myTag, localName, namespace, null);
}
@Nullable
protected TypeDescriptor findTypeDescriptorImpl(XmlTag rootTag, final String name, String namespace, Set<XmlTag> visited) {
XmlNSDescriptorImpl responsibleDescriptor = this;
if (namespace != null && namespace.length() != 0 && !namespace.equals(getDefaultNamespace())) {
@@ -0,0 +1,30 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
*
* 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 com.intellij.xml.impl.schema;
import com.intellij.psi.xml.XmlTag;
import org.jetbrains.annotations.Nullable;
/**
* @author nik
*/
public interface XmlNSTypeDescriptorProvider {
@Nullable
TypeDescriptor getTypeDescriptor(String name, XmlTag context);
@Nullable
TypeDescriptor getTypeDescriptor(XmlTag descriptorTag);
}
@@ -38,7 +38,7 @@ import java.util.Map;
public class XmlNamespaceIndex extends XmlIndex<String> {
@Nullable
public static String getNamespace(VirtualFile file, final Project project) {
public static String getNamespace(@NotNull VirtualFile file, final Project project) {
final List<String> list = FileBasedIndex.getInstance().getValues(NAME, file.getUrl(), createFilter(project));
return list.size() == 0 ? null : list.get(0);
}