| 22 | | private import parser.Element; |
|---|
| 23 | | private import parser.Module; |
|---|
| 24 | | private import parser.Class; |
|---|
| 25 | | private import parser.Enum; |
|---|
| 26 | | private import parser.Tokenizer; |
|---|
| 27 | | private import parser.Block; |
|---|
| 28 | | private import parser.Function; |
|---|
| | 19 | private import property.Props; |
|---|
| | 20 | private import property.Properties; |
|---|
| | 21 | private import resources.Pixmaps; |
|---|
| | 22 | |
|---|
| | 23 | private import language.d.Element; |
|---|
| | 24 | private import language.d.Definition; |
|---|
| | 25 | private import language.d.Directory; |
|---|
| | 26 | private import language.d.CodeBlock; |
|---|
| | 27 | private import language.d.Module; |
|---|
| | 28 | private import language.d.Method; |
|---|
| | 29 | private import language.d.Class; |
|---|
| | 30 | private import language.d.Enum; |
|---|
| | 31 | private import language.d.Import; |
|---|
| | 32 | private import language.d.Token; |
|---|
| | 33 | |
|---|
| | 34 | private import language.d.Tokenizer; |
|---|
| | 35 | |
|---|
| | 36 | |
|---|
| | 37 | // dantfw |
|---|
| 225 | | String key = new String(element.getModifiers())~"."~cast(int)element.getType(); |
|---|
| 226 | | if ( Element.Type.FUNCTION == element.getType() ) |
|---|
| 227 | | { |
|---|
| 228 | | switch ( element.id.toString() ) |
|---|
| 229 | | { |
|---|
| 230 | | case "this" : ctor = true; key ~= "ctor"; break; |
|---|
| 231 | | case "~this" : dtor = true; key ~= "dtor"; break; |
|---|
| 232 | | default : break; |
|---|
| 233 | | } |
|---|
| 234 | | } |
|---|
| 235 | | if ( Element.Type.BLOCK == element.getType() ) |
|---|
| 236 | | { |
|---|
| 237 | | key ~= element.returnType; |
|---|
| 238 | | } |
|---|
| | 233 | //String key = new String(element.getModifiers())~"."~cast(int)element.getType(); |
|---|
| | 234 | String key = new String(element.getType()); |
|---|
| | 235 | // we dont support modifiers. yet... |
|---|
| | 236 | |
|---|
| | 237 | // support for extern/version/override/unittest etc. |
|---|
| | 238 | //if ( Element.Type.BLOCK == element.getType() ) |
|---|
| | 239 | //{ |
|---|
| | 240 | // key ~= element.returnType; |
|---|
| | 241 | //} |
|---|
| 250 | | case Element.Type.MODULE : pixDef = Pixmaps.greenPackage_xpm; break; |
|---|
| 251 | | case Element.Type.IMPORT : pixDef = Pixmaps.import_xpm; break; |
|---|
| 252 | | case Element.Type.ENUM : pixDef = Pixmaps.greenEnum_xpm; break; |
|---|
| 253 | | case Element.Type.STRUCT : pixDef = Pixmaps.greenStruct_xpm; break; |
|---|
| 254 | | case Element.Type.DECLARATION : pixDef = Pixmaps.greenVar_xpm; break; |
|---|
| 255 | | case Element.Type.FUNCTION : |
|---|
| 256 | | if ( ctor ) pixDef = Pixmaps.greenCtor_xpm; |
|---|
| 257 | | else if ( dtor ) pixDef = Pixmaps.greenDtor_xpm; |
|---|
| 258 | | else if ( element.isOverride() ) pixDef = Pixmaps.greenOverride_xpm; |
|---|
| 259 | | else pixDef = Pixmaps.greenFunction_xpm; |
|---|
| 260 | | break; |
|---|
| 261 | | case Element.Type.CONSTRUCTOR : pixDef = Pixmaps.greenCtor_xpm; break; |
|---|
| 262 | | case Element.Type.DESTRUCTOR : pixDef = Pixmaps.greenDtor_xpm; break; |
|---|
| 263 | | case Element.Type.CLASS : pixDef = Pixmaps.greenClass_xpm; break; |
|---|
| 264 | | case Element.Type.INTERFACE : pixDef = Pixmaps.greenInterface_xpm; break; |
|---|
| 265 | | case Element.Type.TEMPLATE : pixDef = Pixmaps.greenTemplate_xpm; break; |
|---|
| 266 | | case Element.Type.BLOCK: |
|---|
| | 255 | case Element.MODULE : pixDef = Pixmaps.greenPackage_xpm; break; |
|---|
| | 256 | case Element.IMPORT : pixDef = Pixmaps.import_xpm; break; |
|---|
| | 257 | case Element.ENUM : pixDef = Pixmaps.greenEnum_xpm; break; |
|---|
| | 258 | case Element.STRUCT : pixDef = Pixmaps.greenStruct_xpm; break; |
|---|
| | 259 | case Element.DECLARATION : pixDef = Pixmaps.greenVar_xpm; break; |
|---|
| | 260 | case Element.FUNCTION : pixDef = Pixmaps.greenFunction_xpm; break; |
|---|
| | 261 | |
|---|
| | 262 | //else if ( element.isOverride() ) pixDef = Pixmaps.greenOverride_xpm; |
|---|
| | 263 | //else pixDef = Pixmaps.greenFunction_xpm; |
|---|
| | 264 | //break; |
|---|
| | 265 | |
|---|
| | 266 | |
|---|
| | 267 | case Element.CONSTRUCTOR : pixDef = Pixmaps.greenCtor_xpm; break; |
|---|
| | 268 | case Element.DESTRUCTOR : pixDef = Pixmaps.greenDtor_xpm; break; |
|---|
| | 269 | case Element.CLASS : pixDef = Pixmaps.greenClass_xpm; break; |
|---|
| | 270 | case Element.INTERFACE : pixDef = Pixmaps.greenInterface_xpm; break; |
|---|
| | 271 | case Element.TEMPLATE : pixDef = Pixmaps.greenTemplate_xpm; break; |
|---|
| | 272 | case Element.BLOCK: pixDef = Pixmaps.red_xpm; break; |
|---|
| | 273 | /* not supported yet. |
|---|
| | 274 | |
|---|
| 417 | | |
|---|
| 418 | | debug(lookup) printf("CodeLookup.getLookupList start = %.*s\n", start.toString()); |
|---|
| 419 | | |
|---|
| 420 | | Project project = codeview.getProject(); |
|---|
| 421 | | // let's start by doing a static lookup. |
|---|
| 422 | | if (!project) { |
|---|
| 423 | | writefln("no project"); |
|---|
| 424 | | canAutoCompleteLastRet = (list.length > 0); |
|---|
| | 417 | String[] strs = start.split("("); |
|---|
| | 418 | start = strs.length ? strs[0] : new String(""); |
|---|
| | 419 | |
|---|
| | 420 | |
|---|
| | 421 | foreach(str,tokval;Token.stdKeyword) { |
|---|
| | 422 | //writefln("test %s", str); |
|---|
| | 423 | if (start.length < str.length) { |
|---|
| | 424 | if (str[0..start.length] == start) { |
|---|
| | 425 | list ~= new String(str); |
|---|
| | 426 | } |
|---|
| | 427 | } |
|---|
| | 428 | } |
|---|
| | 429 | |
|---|
| | 430 | |
|---|
| | 431 | Module sourceModule = this.getCachedModule(); |
|---|
| | 432 | CodeBlock container = sourceModule.getContainerForLine(codeview.getLineNumber()); |
|---|
| | 433 | if (!container) { |
|---|
| | 434 | writefln("no container found?"); |
|---|
| 427 | | |
|---|
| 428 | | |
|---|
| 429 | | // start with local variables.. |
|---|
| 430 | | debug(lookup) writefln("calling getlocalvars on " ~ container.classinfo.name); |
|---|
| 431 | | String[] localVars; |
|---|
| 432 | | container.getLocalVars(localVars); |
|---|
| 433 | | addMatching(list, start, localVars); |
|---|
| 434 | | |
|---|
| 435 | | debug(lookup) writefln("loadingImports"); |
|---|
| 436 | | // load Imports |
|---|
| 437 | | String[] imports = project.getPropValue("importDirs","").split("\n"); |
|---|
| 438 | | imports ~= project.getPropValue("phobos",""); |
|---|
| 439 | | imports ~= new String(project.getBaseDir() ~ Path.sep ~ "src"); |
|---|
| 440 | | Module.paths = imports; |
|---|
| 441 | | |
|---|
| 442 | | debug(lookup) writefln("getClassMemberNames"); |
|---|
| 443 | | // find potential methods / properties. |
|---|
| 444 | | String[] classMembers; |
|---|
| 445 | | container.getClassMemberNames(classMembers,true); |
|---|
| 446 | | // add this.* |
|---|
| 447 | | int classMemberslen = classMembers.length; |
|---|
| 448 | | for(int i=0;i < classMemberslen; i++) { |
|---|
| 449 | | classMembers ~= new String("this." ~ classMembers[i]); |
|---|
| 450 | | } |
|---|
| 451 | | addMatching(list, start, classMembers); |
|---|
| 452 | | |
|---|
| 453 | | |
|---|
| 454 | | |
|---|
| 455 | | writefln("availableFQN"); |
|---|
| 456 | | // try looking up the static posibilities. |
|---|
| 457 | | String[] testwith; |
|---|
| 458 | | sourceModule.availableFQN( testwith ,Element.Type.NONE, Element.Attribute.STATIC,false); |
|---|
| 459 | | sourceModule.availableFQN( testwith ,Element.Type.NONE, Element.Attribute.STATIC,true); |
|---|
| 460 | | writefln(String.join(testwith,"\n")); |
|---|
| 461 | | addMatching(list, start, testwith); |
|---|
| 462 | | |
|---|
| 463 | | |
|---|
| 464 | | |
|---|
| 465 | | |
|---|
| 466 | | |
|---|
| 467 | | // ok not found .. -> let's try resolving the thing. |
|---|
| 468 | | |
|---|
| 469 | | // start by splitting it into parts.. |
|---|
| 470 | | |
|---|
| 471 | | |
|---|
| 472 | | |
|---|
| 473 | | // temporary stop if we have found stuff. |
|---|
| 474 | | if (list.length) { |
|---|
| 475 | | // we may want more !!!! |
|---|
| 476 | | canAutoCompleteLastRet = (list.length > 0); |
|---|
| | 437 | String[] bits = start.split("."); |
|---|
| | 438 | writefln("bits leng = %d", bits.length); |
|---|
| | 439 | if (bits.length < 2) { |
|---|
| | 440 | // simple single entity. |
|---|
| | 441 | container.getAutoCompleteList(start, list); |
|---|
| | 442 | return list.sort; |
|---|
| | 443 | } |
|---|
| | 444 | // do lookup on '*.*' |
|---|
| | 445 | |
|---|
| | 446 | Element lookupwith = null; |
|---|
| | 447 | for(int i=0;i< bits.length-1; i++) { |
|---|
| | 448 | Element type = null; |
|---|
| | 449 | if (!lookupwith) { |
|---|
| | 450 | type = container.getDefinitionElement(bits[i]); |
|---|
| | 451 | } else { |
|---|
| | 452 | type = lookupwith.getDefinitionElement(bits[i], false); // dont go up tree. |
|---|
| | 453 | } |
|---|
| | 454 | if (!type) { |
|---|
| | 455 | writefln("cant find defintion of item named %s" , bits[i]); |
|---|
| | 456 | return list; |
|---|
| | 457 | } |
|---|
| | 458 | // got a parent |
|---|
| | 459 | container = type.moduleObj; // use the scope of the definition. |
|---|
| | 460 | lookupwith = container.getTypeElement(type); |
|---|
| | 461 | if (!lookupwith) { |
|---|
| | 462 | writefln("cant find defintion of type %s" , type.returnType); |
|---|
| | 463 | return list; |
|---|
| | 464 | } |
|---|
| | 465 | } |
|---|
| | 466 | |
|---|
| | 467 | start = bits[bits.length-1]; |
|---|
| | 468 | writefln("building autocomplete list for '%s' on %s", start, lookupwith.classinfo.name); |
|---|
| | 469 | //lookupwith.dumpAll(1); |
|---|
| | 470 | lookupwith.getAutoCompleteList(start, list, false); |
|---|
| | 471 | //writefln("got %d elements", list.length); |
|---|
| | 472 | if (start.length) { |
|---|
| 481 | | String[] parts = start.split("."); |
|---|
| 482 | | int startp = 0; |
|---|
| 483 | | if (!parts[0].length) { |
|---|
| 484 | | canAutoCompleteLastRet = (list.length > 0); |
|---|
| 485 | | return list; |
|---|
| 486 | | } |
|---|
| 487 | | |
|---|
| 488 | | String leftPart = parts[0].dup; |
|---|
| 489 | | if (parts[0] == "this" && (parts.length > 1)) { |
|---|
| 490 | | startp= 1; |
|---|
| 491 | | leftPart ~= "." ~ parts[1].dup; |
|---|
| 492 | | } |
|---|
| 493 | | writefln("about to call resolvetype"); |
|---|
| 494 | | Element basePart = container.resolveTypeOfVarNamed(parts[startp]); |
|---|
| 495 | | writefln("got 1st basepart"); |
|---|
| 496 | | if (!basePart) { // we can not resolve the type. |
|---|
| 497 | | writefln("BASEPART: cant resolve type of %s", parts[startp]); |
|---|
| 498 | | canAutoCompleteLastRet = (list.length > 0); |
|---|
| 499 | | return list; |
|---|
| 500 | | } |
|---|
| 501 | | // skip the last one. |
|---|
| 502 | | for (int i = startp+1;i< (parts.length -1); i++) { |
|---|
| 503 | | writefln("geting basepart %d", i); |
|---|
| 504 | | basePart = basePart.resolvePropertyNamed(parts[i]); |
|---|
| 505 | | if (!basePart) { // we can not resolve the type. |
|---|
| 506 | | writefln("cant resolve type of %s", parts[i]); |
|---|
| 507 | | canAutoCompleteLastRet = (list.length > 0); |
|---|
| 508 | | return list; |
|---|
| 509 | | } |
|---|
| 510 | | leftPart ~= "." ~ parts[i]; |
|---|
| 511 | | } |
|---|
| 512 | | if (!basePart) { // we can not resolve the type. |
|---|
| 513 | | canAutoCompleteLastRet = (list.length > 0); |
|---|
| 514 | | return list; |
|---|
| 515 | | } |
|---|
| 516 | | writefln("got the base part"); |
|---|
| 517 | | // now we have the basePart.. |
|---|
| 518 | | // get the potentail |
|---|
| 519 | | String[] possibleClassMembers; |
|---|
| 520 | | basePart.getClassMemberNames(possibleClassMembers,true); |
|---|
| 521 | | if (possibleClassMembers.length) { |
|---|
| 522 | | |
|---|
| 523 | | String[] possibleClassMembersList; |
|---|
| 524 | | foreach(pcm; possibleClassMembers) { |
|---|
| 525 | | possibleClassMembersList ~= new String(leftPart ~ "." ~ pcm); |
|---|
| 526 | | } |
|---|
| 527 | | addMatching(list, start, possibleClassMembersList); |
|---|
| 528 | | } |
|---|
| 529 | | |
|---|
| 530 | | // temporary stop if we have found stuff. |
|---|
| 531 | | //if (list.length) { |
|---|
| 532 | | // we may want more !!!! |
|---|
| 533 | | canAutoCompleteLastRet = (list.length > 0); |
|---|
| 534 | | return list; |
|---|
| 535 | | |
|---|
| 536 | | |
|---|
| 537 | | } |
|---|
| | 484 | |
|---|
| | 485 | } |
|---|
| | 486 | /** |
|---|
| | 487 | * Utility method for building autocomplete list. |
|---|
| | 488 | */ |
|---|
| 840 | | s = strs[0]; |
|---|
| 841 | | |
|---|
| 842 | | char elementType = ' '; |
|---|
| 843 | | Element e = getElementByName(s, codeview.getLineNumber(), elementType); |
|---|
| 844 | | |
|---|
| | 794 | s = strs.length ? strs[0] : new String(""); |
|---|
| | 795 | if (!s.length) { |
|---|
| | 796 | return; |
|---|
| | 797 | } |
|---|
| | 798 | if (s.toString() in Token.stdKeyword) { |
|---|
| | 799 | codeview.getWorkspace().getSystemConsole.print("D Keyword: " ~ s.toString()); |
|---|
| | 800 | } |
|---|
| | 801 | |
|---|
| | 802 | |
|---|
| | 803 | Module sourceModule = this.getCachedModule(); |
|---|
| | 804 | CodeBlock container = sourceModule.getContainerForLine(codeview.getLineNumber()); |
|---|
| | 805 | if (!container) { |
|---|
| | 806 | writefln("no container found?"); |
|---|
| | 807 | return; |
|---|
| | 808 | } |
|---|
| | 809 | String[] bits = s.split("."); |
|---|
| | 810 | writefln("bits leng = %d", bits.length); |
|---|
| | 811 | if (bits.length < 2) { |
|---|
| | 812 | // simple single entity. |
|---|
| | 813 | Element[] types; |
|---|
| | 814 | container.getDefinitionElementAll(s,types); |
|---|
| | 815 | if (types) { |
|---|
| | 816 | char[] str = ""; |
|---|
| | 817 | foreach(type;types) { |
|---|
| | 818 | str ~= (str.length ? "\n" : "") ~ type.getHelp().toString(); |
|---|
| | 819 | } |
|---|
| | 820 | codeview.getWorkspace().getSystemConsole.print(str); |
|---|
| | 821 | } |
|---|
| | 822 | return; |
|---|
| | 823 | } |
|---|
| | 824 | // do lookup on '*.*' |
|---|
| | 825 | |
|---|
| | 826 | Element lookupwith = null; |
|---|
| | 827 | for(int i=0;i< bits.length-1; i++) { |
|---|
| | 828 | Element type = null; |
|---|
| | 829 | if (!lookupwith) { |
|---|
| | 830 | type = container.getDefinitionElement(bits[i]); |
|---|
| | 831 | } else { |
|---|
| | 832 | type = lookupwith.getDefinitionElement(bits[i], false); // dont go up tree. |
|---|
| | 833 | } |
|---|
| | 834 | if (!type) { |
|---|
| | 835 | writefln("cant find defintion of item named %s" , bits[i]); |
|---|
| | 836 | return; |
|---|
| | 837 | } |
|---|
| | 838 | // got a parent |
|---|
| | 839 | container = type.moduleObj; |
|---|
| | 840 | lookupwith = container.getTypeElement(type); |
|---|
| | 841 | if (!lookupwith) { |
|---|
| | 842 | writefln("cant find defintion of type %s" , type.returnType); |
|---|
| | 843 | return; |
|---|
| | 844 | } |
|---|
| | 845 | } |
|---|
| | 846 | |
|---|
| | 847 | s = bits[bits.length-1]; |
|---|
| | 848 | writefln("building help for '%s' from %s ", s, lookupwith.classinfo.name); |
|---|
| | 849 | //lookupwith.dumpAll(1); |
|---|
| | 850 | |
|---|
| | 851 | //writefln("got %d elements", list.length); |
|---|
| | 852 | if (!s.length || !cast(CodeBlock)lookupwith) { |
|---|
| | 853 | if (cast(Directory)lookupwith && s.length) { |
|---|
| | 854 | Element de = lookupwith.getDefinitionElement(s); |
|---|
| | 855 | codeview.getWorkspace().getSystemConsole.print(de.getHelp()); |
|---|
| | 856 | return; |
|---|
| | 857 | } |
|---|
| | 858 | return; |
|---|
| | 859 | } |
|---|
| | 860 | Element[] types; |
|---|
| | 861 | (cast(CodeBlock)lookupwith).getDefinitionElementAll(s,types,false); |
|---|
| | 862 | // last item was a '.' |
|---|
| | 863 | if (types) { |
|---|
| | 864 | char[] str = ""; |
|---|
| | 865 | foreach(type;types) { |
|---|
| | 866 | str ~= (str.length ? "\n" : "") ~ type.getHelp().toString(); |
|---|
| | 867 | } |
|---|
| | 868 | codeview.getWorkspace().getSystemConsole.print(str); |
|---|
| | 869 | } |
|---|
| | 870 | |
|---|
| 846 | | |
|---|
| 847 | | switch (elementType) { |
|---|
| 848 | | case 'L': // local variable. |
|---|
| 849 | | |
|---|
| 850 | | if (!e) { |
|---|
| 851 | | codeview.getWorkspace().getSystemConsole.print( |
|---|
| 852 | | "Local Variable: " ~ s.toString() ~ " of UNKNOWN Type"); |
|---|
| 853 | | return; |
|---|
| 854 | | } |
|---|
| 855 | | codeview.getWorkspace().getSystemConsole.print( |
|---|
| 856 | | "Local Variable: "~ s.toString() ~ |
|---|
| 857 | | " of Type " ~ e.getFQN(true).toString() ~ "\n" ~ |
|---|
| 858 | | e.getHelpString().toString() |
|---|
| 859 | | ); |
|---|
| 860 | | return; |
|---|
| 861 | | |
|---|
| 862 | | case 'M': |
|---|
| 863 | | if (!e) { |
|---|
| 864 | | codeview.getWorkspace().getSystemConsole.print( |
|---|
| 865 | | "Class Member: " ~ s.toString() ~ " Unknown type / Unknown Prop?" |
|---|
| 866 | | ); |
|---|
| 867 | | return; |
|---|
| 868 | | } |
|---|
| 869 | | Element proptype = e.resolveTypeNamed(e.getReturnType()); |
|---|
| 870 | | |
|---|
| 871 | | |
|---|
| 872 | | char[] helptext = "Class Variable: " ~ e.getFQN(false).toString() ~ "\n" ~ |
|---|
| 873 | | e.getHelpString().toString() ~ "\n"; |
|---|
| 874 | | |
|---|
| 875 | | |
|---|
| 876 | | if (proptype) { |
|---|
| 877 | | helptext ~= "Type: " ~ proptype.getFQN(true).toString() ~ "\n" ~ |
|---|
| 878 | | proptype.getHelpString().toString(); |
|---|
| 879 | | } else { |
|---|
| 880 | | // since the prop should show our type - dont bother here. |
|---|
| 881 | | //helptext ~= "Type: " ~ (prop ? prop.getReturnType().toString() : " Unknown"); |
|---|
| 882 | | } |
|---|
| 883 | | |
|---|
| 884 | | codeview.getWorkspace().getSystemConsole.print(helptext); |
|---|
| 885 | | return; |
|---|
| 886 | | case 'S': |
|---|
| 887 | | if (!e) { |
|---|
| 888 | | return; |
|---|
| 889 | | } |
|---|
| 890 | | codeview.getWorkspace().getSystemConsole.print((cast(Module)e).getHelp(s).toString()); |
|---|
| 891 | | return; |
|---|
| 892 | | |
|---|
| 893 | | default: |
|---|
| 894 | | return; |
|---|
| 895 | | } |
|---|
| 942 | | |
|---|
| 943 | | |
|---|
| 944 | | Element getElementByName(String s, int lineNumber, inout char elementType) |
|---|
| 945 | | { |
|---|
| 946 | | |
|---|
| 947 | | //writefln("LanguageD: show Help %s", s.toString()); |
|---|
| 948 | | // remove the function args component |
|---|
| 949 | | String[] strs = s.split("("); |
|---|
| 950 | | s = strs[0]; |
|---|
| 951 | | |
|---|
| 952 | | auto project = codeview.getProject(); |
|---|
| 953 | | if (!project) { |
|---|
| 954 | | writefln("no project"); |
|---|
| 955 | | return null; |
|---|
| 956 | | } |
|---|
| 957 | | Module sourceModule = this.getCachedModule(); |
|---|
| 958 | | |
|---|
| 959 | | // gets the inner most container for this line |
|---|
| 960 | | Element container = sourceModule.getContainerForLine(codeview.getLineNumber()); |
|---|
| 961 | | if ( container is null ) { |
|---|
| 962 | | container = sourceModule; |
|---|
| 963 | | } |
|---|
| 964 | | |
|---|
| 965 | | |
|---|
| 966 | | // load Imports |
|---|
| 967 | | String[] imports = project.getPropValue("importDirs","").split("\n"); |
|---|
| 968 | | imports ~= project.getPropValue("phobos",""); |
|---|
| 969 | | imports ~= new String(project.getBaseDir() ~ Path.sep ~ "src"); |
|---|
| 970 | | Module.paths =imports; |
|---|
| 971 | | |
|---|
| 972 | | |
|---|
| 973 | | // start with local variables.. |
|---|
| 974 | | //writefln("calling getlocalvars on " ~ container.classinfo.name); |
|---|
| 975 | | String[] localVars; |
|---|
| 976 | | //writefln("getting localvars"); |
|---|
| 977 | | container.getLocalVars(localVars); |
|---|
| 978 | | // writefln("searching localvars %s", String.join(localVars, "\n") ); |
|---|
| 979 | | if (findInArray(localVars, s)) { |
|---|
| 980 | | // get the type of the local var. |
|---|
| 981 | | //writefln("found match localvar"); |
|---|
| 982 | | elementType = 'L'; |
|---|
| 983 | | |
|---|
| 984 | | Element matchElement = container.resolveTypeOfVarNamed(s); |
|---|
| 985 | | return matchElement; |
|---|
| 986 | | |
|---|
| 987 | | } |
|---|
| 988 | | //writefln("done searching array"); |
|---|
| 989 | | |
|---|
| 990 | | |
|---|
| 991 | | // find potential methods / properties. |
|---|
| 992 | | String[] classMembers; |
|---|
| 993 | | container.getClassMemberNames(classMembers); |
|---|
| 994 | | // add this.* |
|---|
| 995 | | //writefln("removing this."); |
|---|
| 996 | | if ((s.length > 5) && (s[0..5] == "this.")) { |
|---|
| 997 | | s = new String(s[5..s.length]); |
|---|
| 998 | | } |
|---|
| 999 | | |
|---|
| 1000 | | //writefln("checking classmembers"); |
|---|
| 1001 | | foreach(classMember;classMembers) { |
|---|
| 1002 | | if (classMember != s) { |
|---|
| 1003 | | continue; |
|---|
| 1004 | | } |
|---|
| 1005 | | |
|---|
| 1006 | | // we have a match. - need to display 2 help info - docs on the class member |
|---|
| 1007 | | // and docs on the type. |
|---|
| 1008 | | //writefln("finding prop"); |
|---|
| 1009 | | Element prop = container.findPropertyNamed(s); |
|---|
| 1010 | | |
|---|
| 1011 | | elementType = 'M'; // property member; |
|---|
| 1012 | | return prop; |
|---|
| 1013 | | |
|---|
| 1014 | | } |
|---|
| 1015 | | |
|---|
| 1016 | | |
|---|
| 1017 | | // try looking up the static posibilities. |
|---|
| 1018 | | String[] testwith; |
|---|
| 1019 | | sourceModule.availableFQN( testwith ,Element.Type.NONE, Element.Attribute.STATIC,false); |
|---|
| 1020 | | sourceModule.availableFQN( testwith ,Element.Type.NONE, Element.Attribute.STATIC,true); |
|---|
| 1021 | | |
|---|
| 1022 | | //writefln("GOT statics: " ~ String.join(testwith,"\n")); |
|---|
| 1023 | | //writefln("LOOKING FOR '%s'",s); |
|---|
| 1024 | | if (findInArray(testwith, s)) { |
|---|
| 1025 | | elementType = 'S'; // static return. |
|---|
| 1026 | | return sourceModule; |
|---|
| 1027 | | |
|---|
| 1028 | | } |
|---|
| 1029 | | |
|---|
| 1030 | | // ok not found .. -> let's try resolving the thing. |
|---|
| 1031 | | |
|---|
| 1032 | | // start by splitting it into parts.. |
|---|
| 1033 | | |
|---|
| 1034 | | |
|---|
| 1035 | | |
|---|
| 1036 | | String[] parts = s.split("."); |
|---|
| 1037 | | int startp = 0; |
|---|
| 1038 | | if (parts[startp] == "this") { |
|---|
| 1039 | | startp++; |
|---|
| 1040 | | } |
|---|
| 1041 | | if (startp >= parts.length) { |
|---|
| 1042 | | return null; |
|---|
| 1043 | | } |
|---|
| 1044 | | Element basePart = container.resolveTypeOfVarNamed(parts[startp]); |
|---|
| 1045 | | if (!basePart) { // we can not resolve the type. |
|---|
| 1046 | | writefln("cant resolve type of %s", parts[startp]); |
|---|
| 1047 | | return null; |
|---|
| 1048 | | } |
|---|
| 1049 | | // skip the last one. |
|---|
| 1050 | | for (int i = startp+1;i< (parts.length -1); i++) { |
|---|
| 1051 | | basePart = basePart.resolvePropertyNamed(parts[i]); |
|---|
| 1052 | | if (!basePart) { // we can not resolve the type. |
|---|
| 1053 | | return null; |
|---|
| 1054 | | } |
|---|
| 1055 | | |
|---|
| 1056 | | } |
|---|
| 1057 | | if (!basePart) { // we can not resolve the type. |
|---|
| 1058 | | return null; |
|---|
| 1059 | | } |
|---|
| 1060 | | |
|---|
| 1061 | | writefln("finding prop"); |
|---|
| 1062 | | Element prop = basePart.findPropertyNamed(parts[length-1]); |
|---|
| 1063 | | elementType = 'M'; //member.. |
|---|
| 1064 | | |
|---|
| 1065 | | return prop; |
|---|
| 1066 | | |
|---|
| 1067 | | |
|---|
| 1068 | | |
|---|
| 1069 | | } |
|---|
| 1070 | | |
|---|
| | 922 | |
|---|
| 1164 | | return getMissingReturn(thisModule); |
|---|
| 1165 | | |
|---|
| 1166 | | |
|---|
| 1167 | | |
|---|
| 1168 | | } |
|---|
| 1169 | | |
|---|
| 1170 | | String getMissingReturn(Element element) |
|---|
| 1171 | | { |
|---|
| 1172 | | String miss = new String(); |
|---|
| 1173 | | |
|---|
| 1174 | | if ( cast(Function)element && element.getReturnType()!="void" ) |
|---|
| 1175 | | { |
|---|
| 1176 | | Function f = cast(Function)element; |
|---|
| 1177 | | String code = f.getBody(); |
|---|
| 1178 | | if ( code !is null && code.find("return") < 0 ) |
|---|
| 1179 | | { |
|---|
| 1180 | | codeview.markError(element.getLineInCode(), new String("Missing return"), 0x00FFFF); |
|---|
| 1181 | | miss ~= f.getName(); |
|---|
| 1182 | | miss ~= " "; |
|---|
| 1183 | | } |
|---|
| 1184 | | } |
|---|
| 1185 | | if ( element.getElements() !is null ) |
|---|
| 1186 | | { |
|---|
| 1187 | | foreach ( Element child ; element.getElements() ) |
|---|
| 1188 | | { |
|---|
| 1189 | | miss ~= getMissingReturn(child); |
|---|
| 1190 | | } |
|---|
| 1191 | | } |
|---|
| 1192 | | |
|---|
| 1193 | | return miss; |
|---|
| 1194 | | } |
|---|
| | 1018 | Method container = thisModule.getMethodForLine(codeview.getLineNumber()); |
|---|
| | 1019 | if (!container) { |
|---|
| | 1020 | return new String(); |
|---|
| | 1021 | } |
|---|
| | 1022 | if (!container.missingReturn()) { |
|---|
| | 1023 | return new String(); |
|---|
| | 1024 | } |
|---|
| | 1025 | codeview.markError(container.startLine, new String("Missing return"), 0x00FFFF); |
|---|
| | 1026 | return new String(container.name); |
|---|
| | 1027 | |
|---|
| | 1028 | |
|---|
| | 1029 | } |
|---|
| | 1030 | |
|---|
| 1205 | | bit findContainer( |
|---|
| 1206 | | out Block container, |
|---|
| 1207 | | out Function funct, |
|---|
| 1208 | | in int lineNumber ) |
|---|
| 1209 | | { |
|---|
| 1210 | | |
|---|
| 1211 | | |
|---|
| 1212 | | |
|---|
| 1213 | | |
|---|
| 1214 | | |
|---|
| 1215 | | |
|---|
| 1216 | | //debug(autoComments) System.writefln("CodeView.findContainer 1"); |
|---|
| 1217 | | bit found = false; |
|---|
| 1218 | | Module mod = this.getCachedModule(); |
|---|
| 1219 | | container = cast(Block)mod.getContainerForLine(lineNumber); |
|---|
| 1220 | | //debug(autoComments) System.writefln("CodeView.findContainer 3"); |
|---|
| 1221 | | if ( container !is null ) |
|---|
| 1222 | | { |
|---|
| 1223 | | //debug(autoComments) System.writefln("CodeView.findContainer 4"); |
|---|
| 1224 | | funct = container.getFunction(lineNumber); |
|---|
| 1225 | | if ( funct !is null ) |
|---|
| 1226 | | { |
|---|
| 1227 | | debug(autoComments) System.writefln("CodeView.findContainer 5"); |
|---|
| 1228 | | found = true; |
|---|
| 1229 | | } |
|---|
| 1230 | | //else |
|---|
| 1231 | | //{ |
|---|
| 1232 | | // debug(autoComments) System.writefln("CodeView.findContainer 6"); |
|---|
| 1233 | | //codeEdit.insertText(insertPos, "What function?"); |
|---|
| 1234 | | //} |
|---|
| 1235 | | } |
|---|
| 1236 | | //else |
|---|
| 1237 | | //{ |
|---|
| 1238 | | // debug(autoComments) System.writefln("CodeView.findContainer 7"); |
|---|
| 1239 | | // //codeEdit.insertText(insertPos, "What container?"); |
|---|
| 1240 | | //} |
|---|
| 1241 | | //debug(autoComments) System.writefln("CodeView.findContainer exit found = ", found); |
|---|
| 1242 | | return found; |
|---|
| 1243 | | } |
|---|
| | 1041 | |
|---|