예제 #1
0
  private static boolean tradForClauseParse(PsiBuilder builder, GroovyParser parser) {

    PsiBuilder.Marker marker = builder.mark();

    if (ParserUtils.getToken(builder, mSEMI)
        || (Declaration.parse(builder, false, parser) && ParserUtils.getToken(builder, mSEMI))) {
      StrictContextExpression.parse(builder, parser);
      ParserUtils.getToken(builder, mSEMI, GroovyBundle.message("semi.expected"));
      ParserUtils.getToken(builder, mNLS);
      if (!mRPAREN.equals(builder.getTokenType())) {
        controlExpressionListParse(builder, parser);
      }
    } else {
      marker.rollbackTo();
      marker = builder.mark();
      controlExpressionListParse(builder, parser);
      ParserUtils.getToken(builder, mSEMI, GroovyBundle.message("semi.expected"));
      StrictContextExpression.parse(builder, parser);
      ParserUtils.getToken(builder, mSEMI, GroovyBundle.message("semi.expected"));
      ParserUtils.getToken(builder, mNLS);
      if (!mRPAREN.equals(builder.getTokenType())) {
        controlExpressionListParse(builder, parser);
      }
    }

    marker.done(FOR_TRADITIONAL_CLAUSE);
    return true;
  }
예제 #2
0
  /*
   * Parses list of control expression in for condition
   */
  private static void controlExpressionListParse(PsiBuilder builder, GroovyParser parser) {

    if (!StrictContextExpression.parse(builder, parser)) return;

    while (mCOMMA.equals(builder.getTokenType())) {

      if (ParserUtils.lookAhead(builder, mCOMMA, mNLS, mRPAREN)
          || ParserUtils.lookAhead(builder, mCOMMA, mRPAREN)) {
        ParserUtils.getToken(builder, mCOMMA);
        builder.error(GroovyBundle.message("expression.expected"));
      } else {
        ParserUtils.getToken(builder, mCOMMA);
      }
      ParserUtils.getToken(builder, mNLS);
      if (!StrictContextExpression.parse(builder, parser)) {
        ParserUtils.getToken(builder, mNLS);
        if (!mRPAREN.equals(builder.getTokenType()) && !mSEMI.equals(builder.getTokenType())) {
          builder.error(GroovyBundle.message("expression.expected"));
        }
        if (!mRPAREN.equals(builder.getTokenType())
            && !mSEMI.equals(builder.getTokenType())
            && !mCOMMA.equals(builder.getTokenType())
            && !mNLS.equals(builder.getTokenType())) {
          builder.advanceLexer();
        }
      }
    }
  }
  public boolean tryToSetUpGroovyFacetOnTheFly(final Module module) {
    final Project project = module.getProject();
    final Library[] libraries = getAllSDKLibraries(project);
    if (libraries.length > 0) {
      final Library library = libraries[0];
      int result =
          Messages.showOkCancelDialog(
              GroovyBundle.message(
                  "groovy.like.library.found.text",
                  module.getName(),
                  library.getName(),
                  getSDKLibVersion(library)),
              GroovyBundle.message("groovy.like.library.found"),
              JetgroovyIcons.Groovy.Groovy_32x32);
      if (result == Messages.OK) {
        AccessToken accessToken = WriteAction.start();

        try {
          ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel();
          LibraryOrderEntry entry = model.addLibraryEntry(libraries[0]);
          LibrariesUtil.placeEntryToCorrectPlace(model, entry);
          model.commit();
          return true;
        } finally {
          accessToken.finish();
        }
      }
    }
    return false;
  }
예제 #4
0
  public static boolean parse(
      PsiBuilder builder, boolean isInClass, boolean isInAnnotation, GroovyParser parser) {
    PsiBuilder.Marker declMarker = builder.mark();
    // allows error messages
    boolean modifiersParsed = Modifiers.parse(builder, parser);

    final boolean methodStart = mLT == builder.getTokenType();
    final IElementType type =
        parseAfterModifiers(
            builder, isInClass, isInAnnotation, parser, declMarker, modifiersParsed);
    if (type == WRONGWAY) {
      if (modifiersParsed && methodStart) {
        declMarker.error(GroovyBundle.message("method.definitions.expected"));
        return false;
      }

      declMarker.rollbackTo();
      if (modifiersParsed) {
        builder.error(GroovyBundle.message("variable.definitions.expected"));
      }

      return false;
    }

    if (type != null) {
      declMarker.done(type);
    } else {
      declMarker.drop();
    }
    return true;
  }
  private static IElementType parseMethod(
      PsiBuilder builder,
      boolean isAnnotationMember,
      boolean hasModifiers,
      GroovyParser parser,
      boolean constructor) {
    // if we have no modifiers and current method is not constructor there is something wrong
    if (!hasModifiers && !constructor) {
      builder.error(GroovyBundle.message("method.definition.without.modifier"));
      return GroovyElementTypes.WRONGWAY;
    }

    builder.advanceLexer();

    ParameterList.parse(builder, GroovyTokenTypes.mRPAREN, parser);

    ParserUtils.getToken(builder, GroovyTokenTypes.mNLS);
    if (!ParserUtils.getToken(builder, GroovyTokenTypes.mRPAREN)) {
      builder.error(GroovyBundle.message("rparen.expected"));
      ThrowClause.parse(builder);
      return methodType(isAnnotationMember, constructor);
    }

    if (isAnnotationMember && builder.getTokenType() == GroovyTokenTypes.kDEFAULT) {
      ParserUtils.getToken(builder, GroovyTokenTypes.kDEFAULT);
      ParserUtils.getToken(builder, GroovyTokenTypes.mNLS);

      if (!AnnotationArguments.parseAnnotationMemberValueInitializer(builder, parser)) {
        builder.error(GroovyBundle.message("annotation.initializer.expected"));
      }
    }

    if (ParserUtils.lookAhead(builder, GroovyTokenTypes.mNLS, GroovyTokenTypes.kTHROWS)
        || ParserUtils.lookAhead(builder, GroovyTokenTypes.mNLS, GroovyTokenTypes.mLCURLY)) {
      ParserUtils.getToken(builder, GroovyTokenTypes.mNLS);
    }

    if (isAnnotationMember && builder.getTokenType() == GroovyTokenTypes.kTHROWS) {
      builder.error(GroovyBundle.message("throws.clause.is.not.allowed.in.at.interface"));
    }
    ThrowClause.parse(builder);

    if (builder.getTokenType() == GroovyTokenTypes.mLCURLY
        || ParserUtils.lookAhead(builder, GroovyTokenTypes.mNLS, GroovyTokenTypes.mLCURLY)) {
      ParserUtils.getToken(builder, GroovyTokenTypes.mNLS);
      if (isAnnotationMember) {
        builder.error(GroovyBundle.message("separator.or.rcurly.expected"));
      }
      if (constructor) {
        ConstructorBody.parseConstructorBody(builder, parser);
      } else {
        OpenOrClosableBlock.parseOpenBlock(builder, parser);
      }
    }

    return methodType(isAnnotationMember, constructor);
  }
  @Nullable
  private static HighlightInfo checkRefInner(GrReferenceExpression ref) {
    PsiElement refNameElement = ref.getReferenceNameElement();
    if (refNameElement == null) return null;

    boolean cannotBeDynamic = PsiUtil.isCompileStatic(ref) || isPropertyAccessInStaticMethod(ref);
    GroovyResolveResult resolveResult = getBestResolveResult(ref);

    if (resolveResult.getElement() != null) {
      if (!isInspectionEnabled(ref.getContainingFile(), ref.getProject())) return null;

      if (isStaticOk(resolveResult)) return null;
      String message = GroovyBundle.message("cannot.reference.non.static", ref.getReferenceName());
      return createAnnotationForRef(ref, cannotBeDynamic, message);
    }

    if (ResolveUtil.isKeyOfMap(ref) || isClassReference(ref)) {
      return null;
    }

    if (!cannotBeDynamic) {
      if (!isInspectionEnabled(ref.getContainingFile(), ref.getProject())) return null;
      GrUnresolvedAccessInspection inspection =
          getInstance(ref.getContainingFile(), ref.getProject());

      if (!inspection.myHighlightIfGroovyObjectOverridden && areGroovyObjectMethodsOverridden(ref))
        return null;
      if (!inspection.myHighlightIfMissingMethodsDeclared && areMissingMethodsDeclared(ref))
        return null;

      if (GroovySuppressableInspectionTool.isElementToolSuppressedIn(ref, SHORT_NAME)) return null;
    }

    if (cannotBeDynamic || shouldHighlightAsUnresolved(ref)) {
      HighlightInfo info =
          createAnnotationForRef(
              ref, cannotBeDynamic, GroovyBundle.message("cannot.resolve", ref.getReferenceName()));
      LOG.assertTrue(info != null);

      HighlightDisplayKey displayKey = HighlightDisplayKey.find(SHORT_NAME);
      if (ref.getParent() instanceof GrMethodCall) {
        registerStaticImportFix(ref, info, displayKey);
      } else {
        registerCreateClassByTypeFix(ref, info, displayKey);
        registerAddImportFixes(ref, info, displayKey);
      }

      registerReferenceFixes(ref, info, cannotBeDynamic, displayKey);
      UnresolvedReferenceQuickFixProvider.registerReferenceFixes(
          ref, new QuickFixActionRegistrarAdapter(info, displayKey));
      OrderEntryFix.registerFixes(new QuickFixActionRegistrarAdapter(info, displayKey), ref);
      return info;
    }

    return null;
  }
 @Override
 public void checkConfiguration() throws RuntimeConfigurationException {
   final PsiClass toRun = getScriptClass();
   if (toRun == null) {
     throw new RuntimeConfigurationWarning(GroovyBundle.message("class.does.not.exist"));
   }
   if (toRun instanceof GrTypeDefinition) {
     if (!GroovyRunnerUtil.canBeRunByGroovy(toRun)) {
       throw new RuntimeConfigurationWarning(GroovyBundle.message("class.can't be executed"));
     }
   } else if (!(toRun instanceof GroovyScriptClass)) {
     throw new RuntimeConfigurationWarning(GroovyBundle.message("script.file.is.not.groovy.file"));
   }
 }
 private static void checkScriptField(AnnotationHolder holder, GrAnnotation annotation) {
   final PsiAnnotationOwner owner = annotation.getOwner();
   final GrMember container = PsiTreeUtil.getParentOfType(((PsiElement) owner), GrMember.class);
   if (container != null) {
     if (container.getContainingClass() instanceof GroovyScriptClass) {
       holder.createErrorAnnotation(
           annotation,
           GroovyBundle.message("annotation.field.can.only.be.used.within.a.script.body"));
     } else {
       holder.createErrorAnnotation(
           annotation, GroovyBundle.message("annotation.field.can.only.be.used.within.a.script"));
     }
   }
 }
  public static IElementType parseDefinitions(
      @NotNull PsiBuilder builder,
      boolean isInClass,
      boolean isInAnnotation,
      @Nullable String typeDefinitionName,
      boolean hasModifiers,
      boolean canBeTuple,
      @NotNull GroovyParser parser) {
    boolean isLParenth = builder.getTokenType() == GroovyTokenTypes.mLPAREN;

    boolean isStringName =
        builder.getTokenType() == GroovyTokenTypes.mSTRING_LITERAL
            || builder.getTokenType() == GroovyTokenTypes.mGSTRING_LITERAL;

    if (builder.getTokenType() != GroovyTokenTypes.mIDENT && !isStringName && !isLParenth) {
      builder.error(GroovyBundle.message("indentifier.or.string.or.left.parenth.literal.expected"));
      return GroovyElementTypes.WRONGWAY;
    }

    if (isLParenth && !canBeTuple) {
      builder.error(GroovyBundle.message("indentifier.or.string.or.left.parenth.literal.expected"));
      return GroovyElementTypes.WRONGWAY;
    }

    if (isInAnnotation && isStringName) {
      builder.error(GroovyBundle.message("string.name.unexpected"));
    }

    if (!isLParenth) { // id or string => method name
      PsiBuilder.Marker varMarker = builder.mark();

      final boolean isConstructor =
          isInClass
              && !isInAnnotation
              && typeDefinitionName != null
              && builder.getTokenType() == GroovyTokenTypes.mIDENT
              && typeDefinitionName.equals(builder.getTokenText());
      builder.advanceLexer();

      if (GroovyTokenTypes.mLPAREN != builder.getTokenType()) {
        varMarker.rollbackTo();
      } else {
        varMarker.drop();
        return parseMethod(builder, isInAnnotation, hasModifiers, parser, isConstructor);
      }
    }

    return parseVar(builder, isInClass, hasModifiers, parser, isLParenth);
  }
  public static void parse(PsiBuilder builder, GroovyParser parser) {

    PsiBuilder.Marker annArgs = builder.mark();
    if (!ParserUtils.getToken(builder, mLPAREN)) {
      annArgs.done(ANNOTATION_ARGUMENTS);
      return;
    }

    if (ParserUtils.lookAhead(builder, mIDENT, mASSIGN)) {
      if (!parseAnnotationMemberValuePairs(builder, parser)) {
        annArgs.rollbackTo();
        return;
      }
    } else {
      PsiBuilder.Marker pairMarker = builder.mark();
      if (!parseAnnotationMemberValueInitializer(builder, parser)) {
        pairMarker.drop();
      } else {
        pairMarker.done(ANNOTATION_MEMBER_VALUE_PAIR);
      }
    }

    ParserUtils.getToken(builder, mNLS);

    if (!ParserUtils.getToken(builder, mRPAREN)) {
      builder.error(GroovyBundle.message("rparen.expected"));
    }
    annArgs.done(ANNOTATION_ARGUMENTS);
  }
예제 #11
0
  /*
   * Parses Groovy-style 'in' clause
   */
  private static boolean forInClauseParse(PsiBuilder builder, GroovyParser parser) {

    PsiBuilder.Marker marker = builder.mark();

    PsiBuilder.Marker declMarker = builder.mark();

    if (ParserUtils.lookAhead(builder, mIDENT, kIN)) {
      ParserUtils.eatElement(builder, PARAMETER);
      declMarker.drop();
      ParserUtils.getToken(builder, kIN);
      if (!ShiftExpression.parse(builder, parser)) {
        builder.error(GroovyBundle.message("expression.expected"));
      }
      marker.done(FOR_IN_CLAUSE);
      return true;
    }

    if (DeclarationStart.parse(builder, parser)) {
      if (Modifiers.parse(builder, parser)) {
        TypeSpec.parse(builder);
        return singleDeclNoInitParse(builder, marker, declMarker, parser);
      }
    }

    if (TypeSpec.parse(builder)) {
      return singleDeclNoInitParse(builder, marker, declMarker, parser);
    }

    declMarker.drop();
    marker.drop();
    return false;
  }
  @Nullable
  private static HighlightInfo checkCodeRefInner(GrCodeReferenceElement refElement) {
    if (PsiTreeUtil.getParentOfType(refElement, GroovyDocPsiElement.class) != null) return null;

    PsiElement nameElement = refElement.getReferenceNameElement();
    if (nameElement == null) return null;

    if (isResolvedStaticImport(refElement)) return null;

    GroovyResolveResult resolveResult = refElement.advancedResolve();
    final PsiElement resolved = resolveResult.getElement();

    if (!(refElement.getParent() instanceof GrPackageDefinition) && resolved == null) {
      String message = GroovyBundle.message("cannot.resolve", refElement.getReferenceName());
      HighlightInfo info =
          HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF)
              .range(nameElement)
              .descriptionAndTooltip(message)
              .create();

      // todo implement for nested classes
      HighlightDisplayKey displayKey = HighlightDisplayKey.find(SHORT_NAME);
      registerCreateClassByTypeFix(refElement, info, displayKey);
      registerAddImportFixes(refElement, info, displayKey);
      UnresolvedReferenceQuickFixProvider.registerReferenceFixes(
          refElement, new QuickFixActionRegistrarAdapter(info, displayKey));
      OrderEntryFix.registerFixes(new QuickFixActionRegistrarAdapter(info, displayKey), refElement);

      return info;
    }

    return null;
  }
  private static IElementType parseVar(
      PsiBuilder builder,
      boolean isInClass,
      boolean hasModifiers,
      GroovyParser parser,
      boolean LParenth) {
    // a = b, c = d
    PsiBuilder.Marker varAssMarker = builder.mark();

    final IElementType declarator = parseDeclarator(builder, LParenth);

    if (declarator != GroovyElementTypes.WRONGWAY) {
      final boolean wasAssignment = parseAssignment(builder, parser);

      if (declarator == GroovyElementTypes.TUPLE_DECLARATION) {
        varAssMarker.drop();
        if (!wasAssignment && !hasModifiers) {
          builder.error(GroovyBundle.message("assignment.expected"));
          return GroovyElementTypes.WRONGWAY;
        }
      } else if (isInClass) { // a = b, c = d
        varAssMarker.done(GroovyElementTypes.FIELD);
      } else {
        varAssMarker.done(GroovyElementTypes.VARIABLE);
      }

      while (ParserUtils.getToken(builder, GroovyTokenTypes.mCOMMA)) {
        ParserUtils.getToken(builder, GroovyTokenTypes.mNLS);

        if (GroovyElementTypes.WRONGWAY.equals(parseVariableOrField(builder, isInClass, parser))
            && declarator == GroovyTokenTypes.mIDENT) {
          return GroovyElementTypes.VARIABLE_DEFINITION_ERROR; // parse b = d
        }
      }

      if (isInClass && declarator == GroovyElementTypes.TUPLE_DECLARATION) {
        builder.error(GroovyBundle.message("tuple.cant.be.placed.in.class"));
      }
      return GroovyElementTypes.VARIABLE_DEFINITION;
    } else {
      varAssMarker.drop();
      builder.error(GroovyBundle.message("identifier.expected"));
      return GroovyElementTypes.WRONGWAY;
    }
  }
  public static boolean parseAnnotationMemberValueInitializer(
      PsiBuilder builder, GroovyParser parser) {
    if (builder.getTokenType() == mAT) {
      return Annotation.parse(builder, parser);
    } else if (builder.getTokenType() == mLBRACK) {
      PsiBuilder.Marker marker = builder.mark();
      ParserUtils.getToken(builder, mLBRACK);
      while (parseAnnotationMemberValueInitializer(builder, parser)) {
        if (builder.eof() || builder.getTokenType() == mRBRACK) break;
        ParserUtils.getToken(builder, mCOMMA, GroovyBundle.message("comma.expected"));
      }

      ParserUtils.getToken(builder, mRBRACK, GroovyBundle.message("rbrack.expected"));
      marker.done(ANNOTATION_ARRAY_INITIALIZER);
      return true;
    }

    // check
    return ConditionalExpression.parse(builder, parser) && !ParserUtils.getToken(builder, mASSIGN);
  }
  private static boolean parseAssignment(PsiBuilder builder, GroovyParser parser) {
    if (ParserUtils.getToken(builder, GroovyTokenTypes.mASSIGN)) {
      PsiBuilder.Marker marker = builder.mark();
      ParserUtils.getToken(builder, GroovyTokenTypes.mNLS);

      if (!AssignmentExpression.parse(builder, parser, true)) {
        marker.rollbackTo();
        builder.error(GroovyBundle.message("expression.expected"));
        return false;
      } else {
        marker.drop();
        return true;
      }
    }
    return false;
  }
  private static boolean parseAnnotationMemberValueSinglePair(
      PsiBuilder builder, GroovyParser parser) {
    PsiBuilder.Marker annmvp = builder.mark();

    if (!ParserUtils.getToken(builder, mIDENT)) {
      annmvp.rollbackTo();
      return false;
    }

    if (!ParserUtils.getToken(builder, mASSIGN)) {
      annmvp.rollbackTo();
      return false;
    }

    ParserUtils.getToken(builder, mNLS);

    if (!parseAnnotationMemberValueInitializer(builder, parser)) {
      builder.error(GroovyBundle.message("annotation.member.value.initializer.expected"));
    }

    annmvp.done(ANNOTATION_MEMBER_VALUE_PAIR);
    return true;
  }
예제 #17
0
 private static boolean singleDeclNoInitParse(
     PsiBuilder builder,
     PsiBuilder.Marker marker,
     PsiBuilder.Marker declMarker,
     GroovyParser parser) {
   if (ParserUtils.getToken(builder, mIDENT)) {
     if (kIN.equals(builder.getTokenType()) || mCOLON.equals(builder.getTokenType())) {
       declMarker.done(PARAMETER);
       builder.advanceLexer();
       if (!ShiftExpression.parse(builder, parser)) {
         builder.error(GroovyBundle.message("expression.expected"));
       }
       marker.done(FOR_IN_CLAUSE);
       return true;
     } else {
       marker.rollbackTo();
       return false;
     }
   } else {
     declMarker.drop();
     marker.rollbackTo();
     return false;
   }
 }
 @NotNull
 public String getText() {
   return GroovyBundle.message("change.implements.and.extends.classes");
 }
예제 #19
0
  public boolean validateConfiguration(CompileScope compileScope) {
    VirtualFile[] files = compileScope.getFiles(GroovyFileType.GROOVY_FILE_TYPE, true);
    if (files.length == 0) return true;

    final Set<String> scriptExtensions = GroovyFileTypeLoader.getCustomGroovyScriptExtensions();

    final CompilerManager compilerManager = CompilerManager.getInstance(myProject);
    Set<Module> modules = new HashSet<Module>();
    for (VirtualFile file : files) {
      if (scriptExtensions.contains(file.getExtension())
          || compilerManager.isExcludedFromCompilation(file)
          || CompilerConfiguration.getInstance(myProject).isResourceFile(file)) {
        continue;
      }

      ProjectRootManager rootManager = ProjectRootManager.getInstance(myProject);
      Module module = rootManager.getFileIndex().getModuleForFile(file);
      if (module != null) {
        modules.add(module);
      }
    }

    Set<Module> nojdkModules = new HashSet<Module>();
    for (Module module : modules) {
      if (!GroovyUtils.isAcceptableModuleType(ModuleType.get(module))) continue;
      final Sdk sdk = ModuleRootManager.getInstance(module).getSdk();
      if (sdk == null || !(sdk.getSdkType() instanceof JavaSdkType)) {
        nojdkModules.add(module);
        continue;
      }

      if (!LibrariesUtil.hasGroovySdk(module)) {
        if (!GroovyConfigUtils.getInstance().tryToSetUpGroovyFacetOntheFly(module)) {
          Messages.showErrorDialog(
              myProject,
              GroovyBundle.message("cannot.compile.groovy.files.no.facet", module.getName()),
              GroovyBundle.message("cannot.compile"));
          ModulesConfigurator.showDialog(
              module.getProject(), module.getName(), ClasspathEditor.NAME);
          return false;
        }
      }
    }

    if (!nojdkModules.isEmpty()) {
      final Module[] noJdkArray = nojdkModules.toArray(new Module[nojdkModules.size()]);
      if (noJdkArray.length == 1) {
        Messages.showErrorDialog(
            myProject,
            GroovyBundle.message("cannot.compile.groovy.files.no.sdk", noJdkArray[0].getName()),
            GroovyBundle.message("cannot.compile"));
      } else {
        StringBuilder modulesList = new StringBuilder();
        for (int i = 0; i < noJdkArray.length; i++) {
          if (i > 0) modulesList.append(", ");
          modulesList.append(noJdkArray[i].getName());
        }
        Messages.showErrorDialog(
            myProject,
            GroovyBundle.message("cannot.compile.groovy.files.no.sdk.mult", modulesList.toString()),
            GroovyBundle.message("cannot.compile"));
      }
      return false;
    }

    final GroovyCompilerConfiguration configuration =
        GroovyCompilerConfiguration.getInstance(myProject);
    if (!configuration.transformsOk && needTransformCopying(compileScope)) {
      final int result =
          Messages.showYesNoDialog(
              myProject,
              "You seem to have global Groovy AST transformations defined in your project,\n"
                  + "but they won't be applied to your code because they are not marked as compiler resources.\n"
                  + "Do you want to add them to compiler resource list?\n"
                  + "(you can do it yourself later in Settings | Compiler | Resource patterns)",
              "AST Transformations found",
              GroovyIcons.GROOVY_ICON_32x32);
      if (result == 0) {
        CompilerConfiguration.getInstance(myProject)
            .addResourceFilePattern(AST_TRANSFORM_FILE_NAME);
      } else {
        configuration.transformsOk = true;
      }
    }

    return true;
  }
예제 #20
0
  @Nullable
  public static IElementType parseAfterModifiers(
      PsiBuilder builder,
      boolean isInClass,
      boolean isInAnnotation,
      GroovyParser parser,
      PsiBuilder.Marker declMarker,
      boolean modifiersParsed) {
    if (modifiersParsed && mLT == builder.getTokenType()) {
      TypeParameters.parse(builder);
      PsiBuilder.Marker checkMarker = builder.mark(); // point to begin of type or variable

      if (TypeSpec.parse(builder, true)
          == fail) { // if type wasn't recognized trying parse VariableDeclaration
        checkMarker.rollbackTo();
      } else {
        checkMarker.drop();
      }
      IElementType decl =
          VariableDefinitions.parseDefinitions(
              builder, isInClass, false, false, true, modifiersParsed, false, parser);

      if (WRONGWAY.equals(decl)) {
        return WRONGWAY;
      }

      return METHOD_DEFINITION;
    }

    if (modifiersParsed) {

      PsiBuilder.Marker checkMarker = builder.mark(); // point to begin of type or variable

      if (TypeSpec.parse(builder, false)
          == fail) { // if type wasn't recognized trying parse VariableDeclaration
        checkMarker.rollbackTo();

        if (isInAnnotation) {
          builder.error(GroovyBundle.message("type.expected"));
        }

        // current token isn't identifier
        IElementType varDecl =
            VariableDefinitions.parse(builder, isInClass, modifiersParsed, parser);

        if (WRONGWAY.equals(varDecl)) {
          return WRONGWAY;
        }
        return varDecl;
      } else { // type was recognized, identifier here
        // starts after type
        IElementType varDeclarationTop =
            VariableDefinitions.parse(builder, isInClass, modifiersParsed, false, parser);

        if (WRONGWAY.equals(varDeclarationTop)) {
          checkMarker.rollbackTo();

          if (isInAnnotation) {
            builder.error(GroovyBundle.message("type.expected"));
          }

          // starts before "type" identifier, here can't be tuple, because next token is identifier
          // (we are in "type recognized" branch)
          IElementType varDecl =
              VariableDefinitions.parse(builder, isInClass, modifiersParsed, false, parser);

          if (WRONGWAY.equals(varDecl)) {
            return WRONGWAY;
          } else {
            return varDecl;
          }
        } else {
          checkMarker.drop();
          return varDeclarationTop;
        }
      }
    } else {

      // if definition starts with lower case letter than it can be just call expression

      String text = builder.getTokenText();
      if (!builder.eof()
          && !TokenSets.BUILT_IN_TYPE.contains(builder.getTokenType())
          && text != null
          && (Character.isLowerCase((text.charAt(0))) || !Character.isLetter(text.charAt(0)))
          && (ParserUtils.lookAhead(builder, mIDENT, mIDENT)
              || ParserUtils.lookAhead(builder, mIDENT, mLPAREN))) {
        // call expression
        return WRONGWAY;
      }

      boolean typeParsed = false;
      if (!ParserUtils.lookAhead(builder, mIDENT, mLPAREN)) {
        typeParsed = TypeSpec.parse(builder, true) != fail;
        // type specification starts with upper case letter
        if (!typeParsed) {
          builder.error(GroovyBundle.message("type.specification.expected"));
          return WRONGWAY;
        }
      }

      IElementType varDef =
          VariableDefinitions.parseDefinitions(
              builder, isInClass, false, false, false, typeParsed, false, parser);
      if (varDef != WRONGWAY) {
        return varDef;
      } else if (isInClass && typeParsed) {
        return typeParsed ? null : WRONGWAY;
      }

      return WRONGWAY;
    }
  }
 @Override
 protected String buildErrorString(Object... args) {
   return GroovyBundle.message("label.already.used", args);
 }